Compare commits

..

90 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
21258845f0 Bump v12.0.18 2021-08-27 10:19:01 -07:00
trop[bot]
96bcadd290 fix: {exit|enter}-html-fullscreen emitted after esc in webview (#30669)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-08-24 10:47:02 +02:00
trop[bot]
ee1030e044 chore: cherry-pick fix for 1227933 from chromium (#30615)
* chore: cherry-pick 1227933 from chromium

* chore: update patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-08-23 17:06:27 +09:00
trop[bot]
11d1bfa071 chore: cherry-pick 4ce2abc17078 from chromium (#30581)
* chore: cherry-pick 4ce2abc17078 from chromium (#30449)

* chore: cherry-pick 4ce2abc17078 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>

* Update .patches

* chore: update patches

Co-authored-by: Steven Barbaro <StevenEBarbaro@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-08-19 15:11:48 +09:00
trop[bot]
131be8cefd chore: cherry-pick e2123a8e0943 from chromium (#30580)
* chore: cherry-pick e2123a8e0943 from chromium

* chore: update patches

* chore: update patches

Co-authored-by: Steven Barbaro <StevenEBarbaro@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-08-19 08:25:58 +09:00
Sudowoodo Release Bot
61b6ede68c Bump v12.0.17 2021-08-17 15:41:48 -07:00
Keeley Hammond
c1c02e172e ci: update git on CI machines (#30526) (#30574) 2021-08-17 15:40:45 -07:00
Sudowoodo Release Bot
8c399548b5 Revert "Bump v12.0.17"
This reverts commit 118f8c4b88.
2021-08-17 09:30:33 -07:00
Sudowoodo Release Bot
118f8c4b88 Bump v12.0.17 2021-08-17 08:45:49 -07:00
trop[bot]
8210faeb09 fix: color select eyedropper not working within DevTools (#29729) (#30490)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-08-13 09:46:47 +09:00
Jeremy Rose
1c927dbbe8 fix: check DCHECK_IS_ON() instead of #ifdef DCHECK_IS_ON (#29674) (#30504)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2021-08-12 11:50:16 -07:00
Jeremy Rose
56cb0d52b9 build: decode error output as utf8 (#30093) (#30505) 2021-08-12 11:44:13 -07:00
Jeremy Rose
083913c738 test: disable failing node tests (#30098) (#30506)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2021-08-12 11:08:39 -04:00
trop[bot]
b164a0506d docs: add missing <webview> event documentation (#30464)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-08-10 10:20:48 +02:00
Jeremy Rose
494c3f8c04 fix: backport 774cfcb from sqlite (#30398) 2021-08-09 09:58:17 -07:00
trop[bot]
f5321177e7 build: rebase release branch before reverting bump (#30416)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-08-09 09:54:23 +02:00
Electron Bot
58f180201e Bump v12.0.16 2021-08-03 10:22:35 -07:00
trop[bot]
767f98b213 build: set the export goma auth fallback flag for the control process (#30316)
Co-authored-by: Samuel Attard <sam@electronjs.org>
2021-08-02 09:55:54 +09:00
trop[bot]
c8da588479 chore: update deps (#30343)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-07-30 14:56:49 -07:00
trop[bot]
d9538c7fd4 fix: use contentAspectRatio not aspectRatio (#30329)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-07-30 02:28:35 -07:00
Pedro Pontes
c51aec4911 chore: cherry-pick 1168f81092 from sqlite (#30295)
* chore: cherry-pick 1168f81092 from sqlite

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-07-30 09:00:28 +09:00
Pedro Pontes
73d9a14c6f chore: cherry-pick 24293de155 from chromium (#30261)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-07-30 08:57:53 +09:00
Pedro Pontes
02f9078c92 chore: cherry-pick e60cc80ff744 from chromium (#30227)
* chore: cherry-pick e60cc80ff744 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-07-29 19:46:14 +09:00
Pedro Pontes
9a77e2b07b chore: cherry-pick 0e7f91956cec from v8 (#30198) 2021-07-29 09:23:06 +09:00
Pedro Pontes
e2e85fb8fc chore: cherry-pick 3feda0244490 from chromium (#30195)
* chore: cherry-pick 3feda0244490 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-07-29 09:22:34 +09:00
trop[bot]
4e68a33c60 chore: update publish to npm to use GitHub token (#30289)
ensures that we don't get hit with a rate limit while trying to publish a release.

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-07-28 12:25:09 -07:00
Pedro Pontes
6e1e2399c7 chore: cherry-pick ac9dc1235e28 from chromium (#30266)
* chore: cherry-pick ac9dc1235e28 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-07-28 15:55:44 +02:00
Pedro Pontes
99413641d1 chore: cherry-pick 79fc7bcbc9 from chromium. (#30182) 2021-07-27 09:16:25 +09:00
Pedro Pontes
ab0f3fd8ff chore: cherry-pick cd98d7c0dae9 from chromium (#30252)
* chore: cherry-pick cd98d7c0dae9 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-07-26 17:50:45 +09:00
trop[bot]
9ce16a44db fix: increase stack size on windows x86 (#30244)
* fix: increace main thread stack size on windows x86

* chore: improve quit-on-crashed-event spec

* chore: add debug logs

* Revert "chore: add debug logs"

This reverts commit 0be81ae07c.

* chore: use a reliable crash endpoint

Co-authored-by: Stephen Wang <wangwenqiang.wwq@bytedance.com>
Co-authored-by: Deepak Mohan <hop2deep@gmail.com>
2021-07-26 17:49:23 +09:00
trop[bot]
f551883fb8 build: handle release failure by existing with code 1 (#30220)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-07-21 11:14:15 -04:00
Pedro Pontes
3ec9f58c8e chore: cherry-pick e76178b896f2 from v8 (#30185)
* chore: cherry-pick e76178b896f2 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-07-19 09:22:18 -07:00
Electron Bot
a52eaeb6e1 Bump v12.0.15 2021-07-15 10:18:21 -07:00
trop[bot]
08ce5bbd33 docs: fix fiddle path (#30143)
This is breaking the build in `electron/electronjs.org-new` and will
most likely not work when clicking the "Fiddle" button.

Rel: https://github.com/electron/electronjs.org-new/pull/65

Co-authored-by: Antón Molleda <amolleda@gmail.com>
2021-07-15 15:26:31 +09:00
Milan Burda
488fbfe469 fix: potential crash on macOS app exit (#29941) (#30138)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-07-15 11:42:24 +09:00
Milan Burda
705a9a39c4 fix: pressing ESC should exit fullscreen from webview (#30063) (#30137)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-07-15 11:42:02 +09:00
trop[bot]
d98b2a760c docs: add <webview> 'did-attach' event documentation (#30130)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-07-15 10:40:52 +09:00
trop[bot]
e48e899807 docs: update quick-start.md (#30132)
Change app-quit link definition, so both window-all-closed and app-quit redirects to appropriate sites.

Co-authored-by: Davenury <57959794+Davenury@users.noreply.github.com>
2021-07-14 22:26:01 +09:00
Jeremy Rose
d84ef8bfb3 fix: crash when invoking login callback synchronously (#30092) 2021-07-14 20:47:56 +09:00
trop[bot]
a8cdc21731 chore: cherry-pick 9bab573a37 from chromium (#30099)
* chore: cherry-pick 9bab573a37 from chromium

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

* Update .patches

* chore: update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-07-13 10:54:43 -07:00
trop[bot]
fc06c55bc0 fix: window ordering on mac (#30067)
* fix: window ordering on mac

* chore: fix flaky fullscreen inheritance test

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2021-07-12 00:22:49 -07:00
trop[bot]
f459315060 docs: modernize protocol-handler docs (#30056)
* docs: modernize protocol-handler docs

* docs: iadd contextIsolation

* docs: add guide for launch-app-from-URL-in-other-app

* docs: address comments

* chore: fix brackets

* chore: add escaped brackets

Co-authored-by: George Xu <gxu@slack-corp.com>
2021-07-09 14:37:43 -04:00
Electron Bot
a4197c367d Bump v12.0.14 2021-07-06 08:16:17 -07:00
Shelley Vohr
b11025a539 fix: fsPromises.readFile renderer crash (#29929) 2021-07-06 10:36:55 +09:00
trop[bot]
ede6cb7edf docs: remove requestHeaders in webRequest.onHeadersReceived (#29932)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2021-07-06 10:35:14 +09:00
trop[bot]
961ce1ded1 fix: honor user-defined Downloads directory (#29966)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-07-06 10:33:11 +09:00
trop[bot]
c6e2cca8bc fix: do not leak NSUUID (#30007)
* fix: do not leak NSUUID

* Fix build error

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-07-05 15:43:37 -04:00
trop[bot]
f1f9a76579 fix: webview should maximize on requestFullscreen (#29988)
* fix: webview should maximize on requestFullscreen

* fix merge error

* chore: update patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-07-05 13:42:35 -04:00
trop[bot]
1f21dfd838 fix: self.module.paths not working in web workers (#30012)
* fix: global.module.paths in workers

* spec: add a regression test

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-07-05 15:27:34 +09:00
trop[bot]
5ba3bba53e docs: remove mention of node-mac-notifier (#30001)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-07-05 08:44:36 +09:00
trop[bot]
f740afcc67 docs: fix broken markdown in dialog.md (#29847)
* docs: fix broken markdown in dialog.md

* &#32;

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2021-07-02 09:52:35 +09:00
Pedro Pontes
822fcfe030 chore: cherry-pick 0f8d58300b from usrsctp (#29876) 2021-07-02 09:52:17 +09:00
trop[bot]
85e4bffabd fix: correctly propagate title updates for window with no navigation entries (#29960)
* fix: correctly propagate title updates for window with no navigation entries

* test

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-07-02 09:49:11 +09:00
trop[bot]
545aba8e16 build: add support for spawning builds for a specific commit on appveyor (#29971) (#29982)
Co-authored-by: Samuel Attard <sam@electronjs.org>
2021-07-01 10:53:24 -07:00
Shelley Vohr
574bd21696 fix: child window alwaysOnTop level persistence (#29957) 2021-07-01 11:51:27 -04:00
trop[bot]
bb149b0e93 fix: crash when clicking links with target=_blank from webview (#29950)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2021-06-30 09:41:23 -07:00
Pedro Pontes
a42ddbc98d chore: cherry-pick ee6aee64e24c from chromium (#29878)
* chore: cherry-pick ee6aee64e24c from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-06-29 15:14:38 -04:00
Electron Bot
14ae30aa9b Bump v12.0.13 2021-06-28 15:18:48 -07:00
John Kleinschmidt
e3a78f62b5 ci: fixup cross arch mksnapshot testing (#29923) 2021-06-28 16:53:10 -04:00
trop[bot]
5bef67a468 fix: stop window.open from hanging when prevented (#29881)
* fix: stop window.open from hanging when prevented

* add test

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-06-28 15:24:38 +09:00
trop[bot]
a6f26b5788 fix: properly order out child windows (#29887)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-06-25 17:55:22 +09:00
Pedro Pontes
54a7f6d865 chore: cherry-pick b77b38a3380c from chromium (#29822)
* chore: cherry-pick b77b38a3380c from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-06-23 15:08:18 +09:00
Pedro Pontes
de7ec574e2 chore: cherry-pick 50de6a8ddad9 from v8 (#29838)
* chore: cherry-pick 50de6a8ddad9 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-06-23 10:41:23 +09:00
Pedro Pontes
bfa682dfa3 chore: cherry-pick 910e9e40d376 from chromium (#29818)
* chore: cherry-pick 910e9e40d376 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-06-23 10:10:09 +09:00
trop[bot]
4baa634d7b fix: properly handle optional requestHeaders with onBeforeSendHeaders (#29834)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2021-06-23 10:08:34 +09:00
Pedro Pontes
3822bc8432 chore: cherry-pick d9556a80a790 from chromium (#29816)
* chore: cherry-pick d9556a80a790 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-06-22 15:11:05 +09:00
Pedro Pontes
1acec5d48b chore: cherry-pick b9ad6a864c79 from v8 (#29814)
* chore: cherry-pick b9ad6a864c79 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-06-22 15:08:30 +09:00
Pedro Pontes
31e8f75795 chore: cherry-pick 3d4f87ab5b9b from angle (#29789)
* chore: cherry-pick 3d4f87ab5b9b from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-06-22 15:00:28 +09:00
Pedro Pontes
905bc4a946 chore: cherry-pick d0aadee1a60a from v8 (#29784)
* chore: cherry-pick d0aadee1a60a from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-06-22 14:59:46 +09:00
John Kleinschmidt
9a48f2322f ci: run linux arm tests on CircleCI (#29767)
* ci: run linux arm tests on CircleCI

(cherry picked from commit c0d93a1772)

* cleanup electron dirs after testing

* use start-stop-daemon to kill Xvfb

(cherry picked from commit 1d10a68c31)

* actually call cleanup step
2021-06-22 14:58:00 +09:00
Electron Bot
088bc334f0 Bump v12.0.12 2021-06-21 10:04:07 -07:00
trop[bot]
8836c814b9 fix: do not cancel CORS preflight request on proxy auth. (#29810)
* fix: do not cancel CORS preflight request on proxy auth. (#29266)

* fix: do not cancel CORS preflight request on proxy auth.

If connecting via proxy, preflight request can receive 407
header response from proxy. This does not mean request
was finished even though it received headers (from proxy,
not the destination server), so prevent "completing"
and most importantly deleting it, which causes request
to be canceled in network layer. Just continue to monitor it
and await proper response from server. Also add circut breaker
to cancel request if proxy auth failed 3 times (for example
user keeps cancelling auth). This behavior happens only
when app registered WebRequest api listeners.

* Port chromium webrequest changes to electron code.

Move relevant parts of chromium WebRequestProxyingURLLoaderFactory from
https://chromium-review.googlesource.com/c/chromium/src/+/2011781
into electron ProxyingURLLoaderFactory.

* Update code to upstreamed version and remove retyr count failsafe.

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

* chore: add required header

Co-authored-by: marekharanczyk <48673767+marekharanczyk@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-06-21 21:20:27 +09:00
Pedro Pontes
5b6e117041 chore: cherry-pick 34d5af37f9ac from chromium (#29776)
* chore: cherry-pick 34d5af37f9ac from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-06-21 19:08:10 +09:00
trop[bot]
845716019a fix: microtasks policy in CreateEnvironment (#29807)
* fix: microtasks policy in CreateEnvironment

Microtasks policy should not be updated for the renderer because
`NodeBindings::CreateEnvironment` might be entered with or without
`UvRunOnce()` on stack. One of the examples of such calls is
`window.open()` which is possible to invoke while `uv_run()` is still
running (e.g. with `setImmediate()`).

All in all, it doesn't matter that much which policy we use since
`v8::MicrotasksScope` has a check for the policy in its destructor and
no commits will be made if the policy is `kExplicit`. It is important,
however, to not change the policy in the middle of `UvRunOnce()` so we
should respect whatever we currently have and move on.

Fix: #29463

* Move test to a better place

* Update spec-main/fixtures/crash-cases/setimmediate-window-open-crash/index.html

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

* Update spec-main/fixtures/crash-cases/setimmediate-window-open-crash/index.html

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

* simplify crash-case

* comment

* fix comment

Co-authored-by: Fedor Indutny <fedor@indutny.com>
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: Fedor Indutny <indutny@signal.org>
2021-06-21 19:06:50 +09:00
Pedro Pontes
308470c98d fix: cherry-pick 9a9c936879 from v8 (#29779)
* cherry-pick 9a9c936879 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-06-21 15:53:37 +09:00
Pedro Pontes
9a8ebbb471 chore: cherry-pick b7a1f498f1 and fad297a48a from chromium (#29786)
* cherry-pick b7a1f498f1 and fad297a48a from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-06-21 15:51:40 +09:00
trop[bot]
c90f41d0c4 fix: fix hover state not clear bug when BrowserWindow is not resizable (#611) (#29799)
Co-authored-by: sssooonnnggg <sssooonnnggg111@gmail.com>
2021-06-21 13:59:14 +09:00
trop[bot]
f275211555 fix: ensure detached devtools are not always draggable (#29736)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-06-17 15:29:49 +09:00
trop[bot]
5b04b64397 fix: draggable regions with devtools open (#29733)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-06-17 15:20:52 +09:00
trop[bot]
066f5136d5 fix setWindowOpenHandler call syntax (#29725)
Co-authored-by: kdau <kevin@kdau.com>
2021-06-16 10:13:12 -07:00
trop[bot]
c0cc008368 fix: don't warn about enableRemoteModule when it's undefined (#29701)
* fix: don't warn about enableRemoteModule when it's undefined

* fix tests

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-06-15 14:26:54 -07:00
Milan Burda
b8e7bcb621 fix: don't warn about enableRemoteModule when it's disabled at build time (#29712) 2021-06-15 14:26:44 -07:00
trop[bot]
170fb689c0 docs: coordinate system of Display.bounds and Display.workArea (#29708)
They are in DIP points (rather than screen points). We can use
screen.dipToScreen* to convert to screen points.

Co-authored-by: Jim Fisher <jameshfisher@gmail.com>
2021-06-15 16:17:49 -04:00
trop[bot]
15b11599a2 docs: Update represented-file fiddle tutorial (#29692)
* Update represented-file fiddle.

* add index and code back to guide

Co-authored-by: Kevin Hartman <kevin@hart.mn>
Co-authored-by: Ethan Arrowood <ethan.arrowood@gmail.com>
2021-06-15 11:37:04 +09:00
trop[bot]
621cc90674 docs: fix file mode of versioning-sketch-2.png (#29680)
Unlike the other files, this file had its executable bit set in its file
mode. This change removes the executable bit to align its file mode with
the rest of the files.

Signed-off-by: Darshan Sen <raisinten@gmail.com>

Co-authored-by: Darshan Sen <raisinten@gmail.com>
2021-06-14 10:12:24 -07:00
trop[bot]
7d791b7f46 fix: use correct spelling of attachment with Content-Disposition header (#29671)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2021-06-14 20:59:20 +09:00
trop[bot]
4e61bc3cfd fix: copy received data in URLPipeLoader to prevent corruption (#29668)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2021-06-14 17:47:00 +09:00
trop[bot]
d82832d8bc fix: improper wrapping of fs.promises.readFile (#29575)
* fix: improper wrapping of fs.promises.readFile

* test: add a regression test

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-06-14 09:35:35 +09:00
trop[bot]
7cb6f61af0 docs: fix image links in performance.md (#29630)
* docs: fix image links in performance.md

Fixes https://github.com/electron/electron/issues/29580

Signed-off-by: Darshan Sen <raisinten@gmail.com>

* Apply suggestions from code review

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

Co-authored-by: Darshan Sen <raisinten@gmail.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2021-06-14 09:33:41 +09:00
trop[bot]
4ab2254879 fix: select-bluetooth-device on Windows (#29612)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-06-09 12:56:02 -04:00
125 changed files with 4617 additions and 364 deletions

View File

@@ -57,6 +57,16 @@ parameters:
type: boolean
default: false
# Executors
executors:
linux-arm:
resource_class: electronjs/linux-arm
machine: true
linux-arm64:
resource_class: electronjs/linux-arm64
machine: true
# The config expects the following environment variables to be set:
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
#
@@ -69,7 +79,7 @@ parameters:
# Build machines configs.
docker-image: &docker-image
docker:
- image: electron.azurecr.io/build:4cec2c5ab66765caa724e37bae2bffb9b29722a5
- image: electron.azurecr.io/build:d818f06a9b1540c7fd38f75ad5a2c493dd6843b6
machine-linux-medium: &machine-linux-medium
<<: *docker-image
@@ -225,6 +235,25 @@ step-maybe-notify-slack-success: &step-maybe-notify-slack-success
fi
when: on_success
step-maybe-cleanup-arm: &step-maybe-cleanup-arm
run:
name: Cleanup after testing
command: |
if [ "$TARGET_ARCH" == "arm64" ] &&[ "`uname`" == "Darwin" ]; then
killall Electron || echo "No Electron processes left running"
killall Safari || echo "No Safari processes left running"
rm -rf ~/Library/Application\ Support/Electron*
rm -rf ~/Library/Application\ Support/electron*
elif [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
XVFB=/usr/bin/Xvfb
/sbin/start-stop-daemon --stop --exec $XVFB || echo "Xvfb not running"
pkill electron || echo "electron not running"
rm -rf ~/.config/Electron*
rm -rf ~/.config/electron*
fi
when: always
step-checkout-electron: &step-checkout-electron
checkout:
path: src/electron
@@ -308,6 +337,7 @@ 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 })"
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
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
@@ -668,6 +698,7 @@ step-persist-data-for-tests: &step-persist-data-for-tests
- src/electron
- src/third_party/electron_node
- src/third_party/nan
- src/cross-arch-snapshots
step-electron-dist-unzip: &step-electron-dist-unzip
run:
@@ -730,7 +761,11 @@ step-verify-mksnapshot: &step-verify-mksnapshot
name: Verify mksnapshot
command: |
cd src
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
else
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
fi
step-verify-chromedriver: &step-verify-chromedriver
run:
@@ -857,23 +892,6 @@ step-maybe-cross-arch-snapshot-store: &step-maybe-cross-arch-snapshot-store
path: src/cross-arch-snapshots
destination: cross-arch-snapshots
step-maybe-trigger-arm-test: &step-maybe-trigger-arm-test
run:
name: Trigger an arm test on VSTS if applicable
command: |
cd src
# Only run for non-fork prs
if [ "$TRIGGER_ARM_TEST" == "true" ] && [ -z "$CIRCLE_PR_NUMBER" ]; then
#Trigger VSTS job, passing along CircleCI job number and branch to build
if [ "`uname`" == "Darwin" ]; then
echo "Triggering electron-arm2-testing build on Azure DevOps"
node electron/script/release/ci-release-build.js --job=electron-arm2-testing --ci=DevOps --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
else
echo "Triggering electron-$TARGET_ARCH-testing build on VSTS"
node electron/script/release/ci-release-build.js --job=electron-$TARGET_ARCH-testing --ci=VSTS --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
fi
fi
step-maybe-generate-typescript-defs: &step-maybe-generate-typescript-defs
run:
name: Generate type declarations
@@ -1288,8 +1306,14 @@ steps-tests: &steps-tests
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
command: |
cd src
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec-main/*-spec.ts | circleci tests split))
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.js | circleci tests split))
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging)
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging)
else
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec-main/*-spec.ts | circleci tests split))
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.js | circleci tests split))
fi
- run:
name: Check test results existence
command: |
@@ -1310,6 +1334,8 @@ steps-tests: &steps-tests
- *step-maybe-notify-slack-failure
- *step-maybe-cleanup-arm
steps-test-nan: &steps-test-nan
steps:
- attach_workspace:
@@ -1582,9 +1608,6 @@ commands:
steps:
- *step-save-out-cache
# Trigger tests on arm hardware if needed
- *step-maybe-trigger-arm-test
- *step-maybe-notify-slack-failure
electron-publish:
@@ -1912,7 +1935,7 @@ jobs:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: false
persist: true
checkout: true
use-out-cache: false
@@ -1970,7 +1993,7 @@ jobs:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: false
persist: true
checkout: true
use-out-cache: false
@@ -2358,6 +2381,24 @@ jobs:
<<: *env-send-slack-notifications
<<: *steps-verify-ffmpeg
linux-arm-testing-tests:
executor: linux-arm
environment:
<<: *env-arm
<<: *env-global
<<: *env-headless-testing
<<: *env-stack-dumping
<<: *steps-tests
linux-arm64-testing-tests:
executor: linux-arm64
environment:
<<: *env-arm64
<<: *env-global
<<: *env-headless-testing
<<: *env-stack-dumping
<<: *steps-tests
osx-testing-x64-tests:
<<: *machine-mac-large
environment:
@@ -2590,8 +2631,23 @@ workflows:
- linux-ia32-testing
- linux-arm-testing
- linux-arm-testing-tests:
filters:
branches:
# Do not run this on forked pull requests
ignore: /pull\/[0-9]+/
requires:
- linux-arm-testing
- linux-arm64-testing
- linux-arm64-testing-tests:
filters:
branches:
# Do not run this on forked pull requests
ignore: /pull\/[0-9]+/
requires:
- linux-arm64-testing
- linux-arm64-testing-gn-check:
requires:
- linux-checkout-fast

View File

@@ -1 +1 @@
12.0.11
12.0.18

View File

@@ -21,6 +21,6 @@ except subprocess.CalledProcessError as e:
+ "' failed with code '"
+ str(e.returncode)
+ "':\n"
+ e.output
+ e.output.decode('utf8')
)
sys.exit(e.returncode)

View File

@@ -139,6 +139,8 @@ static_library("chrome") {
if (enable_color_chooser) {
sources += [
"//chrome/browser/devtools/devtools_eye_dropper.cc",
"//chrome/browser/devtools/devtools_eye_dropper.h",
"//chrome/browser/platform_util.cc",
"//chrome/browser/platform_util.h",
"//chrome/browser/ui/browser_dialogs.h",

View File

@@ -24,7 +24,7 @@ The `dialog` module has the following methods:
* `buttonLabel` String (optional) - Custom label for the confirmation button, when
left empty the default label will be used.
* `filters` [FileFilter[]](structures/file-filter.md) (optional)
* `properties` String[] (optional) - Contains which features the dialog should
* `properties` String[]&#32;(optional) - Contains which features the dialog should
use. The following values are supported:
* `openFile` - Allow files to be selected.
* `openDirectory` - Allow directories to be selected.
@@ -87,7 +87,7 @@ dialog.showOpenDialogSync(mainWindow, {
* `buttonLabel` String (optional) - Custom label for the confirmation button, when
left empty the default label will be used.
* `filters` [FileFilter[]](structures/file-filter.md) (optional)
* `properties` String[] (optional) - Contains which features the dialog should
* `properties` String[]&#32;(optional) - Contains which features the dialog should
use. The following values are supported:
* `openFile` - Allow files to be selected.
* `openDirectory` - Allow directories to be selected.
@@ -112,7 +112,7 @@ Returns `Promise<Object>` - Resolve with an object containing the following:
* `canceled` Boolean - whether or not the dialog was canceled.
* `filePaths` String[] - An array of file paths chosen by the user. If the dialog is cancelled this will be an empty array.
* `bookmarks` String[] (optional) _macOS_ _mas_ - An array matching the `filePaths` array of base64 encoded strings which contains security scoped bookmark data. `securityScopedBookmarks` must be enabled for this to be populated. (For return values, see [table here](#bookmarks-array).)
* `bookmarks` String[]&#32;(optional) _macOS_ _mas_ - An array matching the `filePaths` array of base64 encoded strings which contains security scoped bookmark data. `securityScopedBookmarks` must be enabled for this to be populated. (For return values, see [table here](#bookmarks-array).)
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
@@ -165,7 +165,7 @@ dialog.showOpenDialog(mainWindow, {
displayed in front of the filename text field.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box,
defaults to `true`.
* `properties` String[] (optional)
* `properties` String[]&#32;(optional)
* `showHiddenFiles` - Show hidden files in dialog.
* `createDirectory` _macOS_ - Allow creating new directories from dialog.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
@@ -195,7 +195,7 @@ The `filters` specifies an array of file types that can be displayed, see
* `nameFieldLabel` String (optional) _macOS_ - Custom label for the text
displayed in front of the filename text field.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box, defaults to `true`.
* `properties` String[] (optional)
* `properties` String[]&#32;(optional)
* `showHiddenFiles` - Show hidden files in dialog.
* `createDirectory` _macOS_ - Allow creating new directories from dialog.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
@@ -227,7 +227,7 @@ expanding and collapsing the dialog.
`"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless
you set an icon using the `"icon"` option. On macOS, both `"warning"` and
`"error"` display the same warning icon.
* `buttons` String[] (optional) - Array of texts for buttons. On Windows, an empty array
* `buttons` String[]&#32;(optional) - Array of texts for buttons. On Windows, an empty array
will result in one button labeled "OK".
* `defaultId` Integer (optional) - Index of the button in the buttons array which will
be selected by default when the message box opens.
@@ -273,7 +273,7 @@ If `browserWindow` is not shown dialog will not be attached to it. In such case
`"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless
you set an icon using the `"icon"` option. On macOS, both `"warning"` and
`"error"` display the same warning icon.
* `buttons` String[] (optional) - Array of texts for buttons. On Windows, an empty array
* `buttons` String[]&#32;(optional) - Array of texts for buttons. On Windows, an empty array
will result in one button labeled "OK".
* `defaultId` Integer (optional) - Index of the button in the buttons array which will
be selected by default when the message box opens.

View File

@@ -11,9 +11,9 @@
* `colorDepth` Number - The number of bits per pixel.
* `depthPerComponent` Number - The number of bits per color component.
* `displayFrequency` Number - The display refresh rate.
* `bounds` [Rectangle](rectangle.md)
* `bounds` [Rectangle](rectangle.md) - the bounds of the display in DIP points.
* `size` [Size](size.md)
* `workArea` [Rectangle](rectangle.md)
* `workArea` [Rectangle](rectangle.md) - the work area of the display in DIP points.
* `workAreaSize` [Size](size.md)
* `internal` Boolean - `true` for an internal display and `false` for an external display

View File

@@ -154,7 +154,6 @@ response are visible by the time this listener is fired.
* `timestamp` Double
* `statusLine` String
* `statusCode` Integer
* `requestHeaders` Record<string, string>
* `responseHeaders` Record<string, string[]> (optional)
* `callback` Function
* `headersReceivedResponse` Object

View File

@@ -718,6 +718,10 @@ Corresponds to the points in time when the spinner of the tab starts spinning.
Corresponds to the points in time when the spinner of the tab stops spinning.
### Event: 'did-attach'
Fired when attached to the embedder web contents.
### Event: 'dom-ready'
Fired when document in the given frame is loaded.
@@ -838,6 +842,19 @@ this purpose.
Calling `event.preventDefault()` does __NOT__ have any effect.
### Event: 'did-start-navigation'
Returns:
* `url` String
* `isInPlace` Boolean
* `isMainFrame` Boolean
* `frameProcessId` Integer
* `frameRoutingId` Integer
Emitted when any frame (including main) starts navigating. `isInPlace` will be
`true` for in-page navigations.
### Event: 'did-navigate'
Returns:
@@ -850,6 +867,23 @@ This event is not emitted for in-page navigations, such as clicking anchor links
or updating the `window.location.hash`. Use `did-navigate-in-page` event for
this purpose.
### Event: 'did-frame-navigate'
Returns:
* `url` String
* `httpResponseCode` Integer - -1 for non HTTP navigations
* `httpStatusText` String - empty for non HTTP navigations,
* `isMainFrame` Boolean
* `frameProcessId` Integer
* `frameRoutingId` Integer
Emitted when any frame navigation is done.
This event is not emitted for in-page navigations, such as clicking anchor links
or updating the `window.location.hash`. Use `did-navigate-in-page` event for
this purpose.
### Event: 'did-navigate-in-page'
Returns:

View File

@@ -117,15 +117,18 @@ const mainWindow = new BrowserWindow({
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
if (url === 'about:blank') {
return {
frame: false,
fullscreenable: false,
backgroundColor: 'black',
webPreferences: {
preload: 'my-child-window-preload-script.js'
action: 'allow',
overrideBrowserWindowOptions: {
frame: false,
fullscreenable: false,
backgroundColor: 'black',
webPreferences: {
preload: 'my-child-window-preload-script.js'
}
}
}
}
return false
return { action: 'deny' }
})
```

View File

@@ -4,13 +4,14 @@
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link rel="stylesheet" type="text/css" href="./styles.css">
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
Click on the title with the <pre>Command</pre> or <pre>Control</pre> key pressed.
You should see a popup with the represented file at the top.
</p>
</body>
</body>
</html>

View File

@@ -4,10 +4,7 @@ const os = require('os');
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
height: 600
})
win.loadFile('index.html')

View File

@@ -1,92 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>app.setAsDefaultProtocol Demo</title>
</head>
<body>
<section>
<header>
<h1>
Protocol Handler
</h1>
<h3>The <code>app</code> module provides methods for handling protocols.</h3>
<p>These methods allow you to set and unset the protocols your app should be the default app for. Similar to when a browser asks to be your default for viewing web pages.</p>
<h1>App Default Protocol Demo</h1>
<p>Open the <a href="https://electronjs.org/docs/api/app">full app API documentation<span class="u-visible-to-screen-reader">(opens in new window)</span></a> in your browser.</p>
</header>
<p>The protocol API allows us to register a custom protocol and intercept existing protocol requests.</p>
<p>These methods allow you to set and unset the protocols your app should be the default app for. Similar to when a
browser asks to be your default for viewing web pages.</p>
<div >
<button id="open-in-browser" class="js-container-target demo-toggle-button">Launch current page in browser
<div class="demo-meta u-avoid-clicks">Supports: Win, macOS <span class="demo-meta-divider">|</span> Process: Main</div>
</button>
<section id='open-app-link'>
<a href="electron-api-demos://open">Now... launch the app from a web link</a>
</section>
<div >
<p>You can set your app as the default app to open for a specific protocol. For instance, in this demo we set this app as the default for <code>electron-api-demos://</code>. The demo button above will launch a page in your default browser with a link. Click that link and it will re-launch this app.</p>
<h5>Packaging</h5>
<p>This feature will only work on macOS when your app is packaged. It will not work when you're launching it in development from the command-line. When you package your app you'll need to make sure the macOS <code>plist</code> for the app is updated to include the new protocol handler. If you're using <code>electron-packager</code> then you can add the flag <code>--extend-info</code> with a path to the <code>plist</code> you've created. The one for this app is below.</p>
<h5>Renderer Process</h5>
<pre><code>
const {shell} = require('electron')
const path = require('path')
const protocolHandlerBtn = document.getElementById('protocol-handler')
protocolHandlerBtn.addEventListener('click', () => {
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
const pagePath = path.join('file://', pageDirectory, '../../sections/system/protocol-link.html')
shell.openExternal(pagePath)
})
</code></pre>
<h5>Main Process</h5>
<pre><code>
const {app, dialog} = require('electron')
const path = require('path')
<p>Open the <a href="https://www.electronjs.org/docs/api/protocol">full protocol API documentation</a> in your
browser.</p>
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-api-demos', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-api-demos')
}
-----
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})
<h3>Demo</h3>
<p>
First: Launch current page in browser
<button id="open-in-browser" class="js-container-target demo-toggle-button">
Click to Launch Browser
</button>
</p>
</code></pre>
<h5>macOS plist</h5>
<pre><code>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>electron-api-demos</string>
</array>
<key>CFBundleURLName</key>
<string>Electron API Demos Protocol</string>
</dict>
</array>
<key>ElectronTeamID</key>
<string>VEKTX9H2N7</string>
</dict>
</plist>
</code>
</pre>
</div>
</div>
<script type="text/javascript">
require('./renderer.js')
</script>
</section>
<p>
Then: Launch the app from a web link!
<a href="electron-fiddle://open">Click here to launch the app</a>
</p>
----
<p>You can set your app as the default app to open for a specific protocol. For instance, in this demo we set this app
as the default for <code>electron-fiddle://</code>. The demo button above will launch a page in your default
browser with a link. Click that link and it will re-launch this app.</p>
<h3>Packaging</h3>
<p>This feature will only work on macOS when your app is packaged. It will not work when you're launching it in
development from the command-line. When you package your app you'll need to make sure the macOS <code>plist</code>
for the app is updated to include the new protocol handler. If you're using <code>electron-packager</code> then you
can add the flag <code>--extend-info</code> with a path to the <code>plist</code> you've created. The one for this
app is below:</p>
<p>
<h5>macOS plist</h5>
<pre><code>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
&lt;key&gt;CFBundleURLTypes&lt;/key&gt;
&lt;array&gt;
&lt;dict&gt;
&lt;key&gt;CFBundleURLSchemes&lt;/key&gt;
&lt;array&gt;
&lt;string&gt;electron-api-demos&lt;/string&gt;
&lt;/array&gt;
&lt;key&gt;CFBundleURLName&lt;/key&gt;
&lt;string&gt;Electron API Demos Protocol&lt;/string&gt;
&lt;/dict&gt;
&lt;/array&gt;
&lt;key&gt;ElectronTeamID&lt;/key&gt;
&lt;string&gt;VEKTX9H2N7&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;
</code>
</pre>
<p>
<!-- You can also require other files to run in this process -->
<script src="./renderer.js"></script>
</body>
</html>
</body>
</html>
</html>

View File

@@ -1,10 +1,39 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow, dialog } = require('electron')
const { app, BrowserWindow, ipcMain, shell } = require('electron')
const path = require('path')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
let mainWindow;
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-fiddle')
}
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
})
// Create mainWindow, load the rest of the app, etc...
app.whenReady().then(() => {
createWindow()
})
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})
}
function createWindow () {
// Create the browser window.
@@ -12,58 +41,23 @@ function createWindow () {
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
preload: path.join(__dirname, 'preload.js'),
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-api-demos', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-api-demos')
}
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
// Handle window controls via IPC
ipcMain.on('shell:open', () => {
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
const pagePath = path.join('file://', pageDirectory, 'index.html')
shell.openExternal(pagePath)
})

View File

@@ -0,0 +1,11 @@
// All of the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
const { contextBridge, ipcRenderer } = require('electron')
// Set up context bridge between the renderer process and the main process
contextBridge.exposeInMainWorld(
'shell',
{
open: () => ipcRenderer.send('shell:open'),
}
)

View File

@@ -1,14 +1,8 @@
const { shell } = require('electron')
const path = require('path')
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All APIs exposed by the context bridge are available here.
const openInBrowserButton = document.getElementById('open-in-browser')
const openAppLink = document.getElementById('open-app-link')
// Hides openAppLink when loaded inside Electron
openAppLink.style.display = 'none'
openInBrowserButton.addEventListener('click', () => {
console.log('clicked')
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
const pagePath = path.join('file://', pageDirectory, 'index.html')
shell.openExternal(pagePath)
})
// Binds the buttons to the context bridge API.
document.getElementById('open-in-browser').addEventListener('click', () => {
shell.open();
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 32 KiB

0
docs/images/versioning-sketch-2.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,175 @@
---
title: launch-app-from-URL-in-another-app
description: This guide will take you through the process of setting your electron app as the default handler for a specific protocol.
slug: launch-app-from-url-in-another-app
hide_title: true
---
# Launching Your Electron App From A URL In Another App
## Overview
<!-- ✍ Update this section if you want to provide more details -->
This guide will take you through the process of setting your electron app as the default
handler for a specific [protocol](https://www.electronjs.org/docs/api/protocol).
By the end of this tutorial, we will have set our app to intercept and handle
any clicked URLs that start with a specific protocol. In this guide, the protocol
we will use will be "`electron-fiddle://`".
## Examples
### Main Process (main.js)
First we will import the required modules from `electron`. These modules help control our application life and create a native browser window.
```js
const { app, BrowserWindow, shell } = require('electron')
const path = require('path')
```
Next, we will proceed to register our application to handle all "`electron-fiddle://`" protocols.
```js
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-fiddle')
}
```
We will now define the function in charge of creating our browser window and load our application's `index.html` file.
```js
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
```
In this next step, we will create our `BrowserWindow` and tell our application how to handle an event in which an external protocol is clicked.
This code will be different in WindowsOS compared to MacOS and Linux. This is due to Windows requiring additional code in order to open the contents of the protocol link within the same electron instance. Read more about this [here](https://www.electronjs.org/docs/api/app#apprequestsingleinstancelock).
### Windows code:
```js
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
})
// Create mainWindow, load the rest of the app, etc...
app.whenReady().then(() => {
createWindow()
})
// handling the protocol. In this case, we choose to show an Error Box.
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})
}
```
### MacOS and Linux code:
```js
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
})
// handling the protocol. In this case, we choose to show an Error Box.
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})
```
Finally, we will add some additional code to handle when someone closes our application
```js
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
```
## Important Note:
### Packaging
This feature will only work on macOS when your app is packaged. It will not work when you're launching it in development from the command-line. When you package your app you'll need to make sure the macOS `plist` for the app is updated to include the new protocol handler. If you're using [`electron-packager`](https://github.com/electron/electron-packager) then you
can add the flag `--extend-info` with a path to the `plist` you've created. The one for this app is below:
### Plist
```XML
<p>
<h5>macOS plist</h5>
<pre><code>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>electron-api-demos</string>
</array>
<key>CFBundleURLName</key>
<string>Electron API Demos Protocol</string>
</dict>
</array>
<key>ElectronTeamID</key>
<string>VEKTX9H2N7</string>
</dict>
</plist>
</code>
</pre>
<p>
```
## Conclusion
After you start your electron app, you can now enter in a URL in your browser that contains the custom protocol, for example `"electron-fiddle://open"` and observe that the application will respond and show an error dialog box.
<!--
Because Electron examples usually require multiple files (HTML, CSS, JS
for the main and renderer process, etc.), we use this custom code block
for Fiddle (https://www.electronjs.org/fiddle).
Please modify any of the files in the referenced folder to fit your
example.
The content in this codeblock will not be rendered in the website so you
can leave it empty.
-->
```fiddle docs/fiddles/system/protocol-handler/launch-app-from-URL-in-another-app
```
<!-- ✍ Explanation of the code below -->

View File

@@ -130,14 +130,6 @@ if you exceed that limit.
[apple-notification-guidelines]: https://developer.apple.com/macos/human-interface-guidelines/system-capabilities/notifications/
#### Advanced Notifications
Later versions of macOS allow for notifications with an input field, allowing the user
to quickly reply to a notification. In order to send notifications with an input field,
use the userland module [node-mac-notifier][node-mac-notifier].
[node-mac-notifier]: https://github.com/CharlieHess/node-mac-notifier
#### Do not disturb / Session State
To detect whether or not you're allowed to send a notification, use the userland module

View File

@@ -120,9 +120,9 @@ file in the directory you executed it in. Both files can be analyzed using
the Chrome Developer Tools, using the `Performance` and `Memory` tabs
respectively.
![performance-cpu-prof]
![Performance CPU Profile][performance-cpu-prof]
![performance-heap-prof]
![Performance Heap Memory Profile][performance-heap-prof]
In this example, on the author's machine, we saw that loading `request` took
almost half a second, whereas `node-fetch` took dramatically less memory

View File

@@ -223,7 +223,7 @@ app.on('window-all-closed', function () {
[node-platform]: https://nodejs.org/api/process.html#process_process_platform
[window-all-closed]: ../api/app.md#event-window-all-closed
[window-all-closed]: ../api/app.md#appquit
[app-quit]: ../api/app.md#appquit
#### Open a window if none are open (macOS)

View File

@@ -20,23 +20,40 @@ To set the represented file of window, you can use the
## Example
Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript fiddle='docs/fiddles/features/represented-file'
const { app, BrowserWindow } = require('electron')
const os = require('os');
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
}
app.whenReady().then(() => {
const win = new BrowserWindow()
win.setRepresentedFilename('/etc/passwd')
win.setRepresentedFilename(os.homedir())
win.setDocumentEdited(true)
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
After launching the Electron application, click on the title with `Command` or
`Control` key pressed. You should see a popup with the file you just defined:
`Control` key pressed. You should see a popup with the represented file at the top.
In this guide, this is the current user's home directory:
![Represented file](../images/represented-file.png)

View File

@@ -490,63 +490,83 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
}
};
function fsReadFileAsar (pathArgument: string, options: any, callback: any) {
const pathInfo = splitPath(pathArgument);
if (pathInfo.isAsar) {
const { asarPath, filePath } = pathInfo;
if (typeof options === 'function') {
callback = options;
options = { encoding: null };
} else if (typeof options === 'string') {
options = { encoding: options };
} else if (options === null || options === undefined) {
options = { encoding: null };
} else if (typeof options !== 'object') {
throw new TypeError('Bad arguments');
}
const { encoding } = options;
const archive = getOrCreateArchive(asarPath);
if (!archive) {
const error = createError(AsarError.INVALID_ARCHIVE, { asarPath });
nextTick(callback, [error]);
return;
}
const info = archive.getFileInfo(filePath);
if (!info) {
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath });
nextTick(callback, [error]);
return;
}
if (info.size === 0) {
nextTick(callback, [null, encoding ? '' : Buffer.alloc(0)]);
return;
}
if (info.unpacked) {
const realPath = archive.copyFileOut(filePath);
return fs.readFile(realPath, options, callback);
}
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) {
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath });
nextTick(callback, [error]);
return;
}
logASARAccess(asarPath, filePath, info.offset);
fs.read(fd, buffer, 0, info.size, info.offset, (error: Error) => {
callback(error, encoding ? buffer.toString(encoding) : buffer);
});
}
}
const { readFile } = fs;
fs.readFile = function (pathArgument: string, options: any, callback: any) {
const pathInfo = splitPath(pathArgument);
if (!pathInfo.isAsar) return readFile.apply(this, arguments);
const { asarPath, filePath } = pathInfo;
if (typeof options === 'function') {
callback = options;
options = { encoding: null };
} else if (typeof options === 'string') {
options = { encoding: options };
} else if (options === null || options === undefined) {
options = { encoding: null };
} else if (typeof options !== 'object') {
throw new TypeError('Bad arguments');
if (!pathInfo.isAsar) {
return readFile.apply(this, arguments);
}
const { encoding } = options;
const archive = getOrCreateArchive(asarPath);
if (!archive) {
const error = createError(AsarError.INVALID_ARCHIVE, { asarPath });
nextTick(callback, [error]);
return;
}
const info = archive.getFileInfo(filePath);
if (!info) {
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath });
nextTick(callback, [error]);
return;
}
if (info.size === 0) {
nextTick(callback, [null, encoding ? '' : Buffer.alloc(0)]);
return;
}
if (info.unpacked) {
const realPath = archive.copyFileOut(filePath);
return fs.readFile(realPath, options, callback);
}
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) {
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath });
nextTick(callback, [error]);
return;
}
logASARAccess(asarPath, filePath, info.offset);
fs.read(fd, buffer, 0, info.size, info.offset, (error: Error) => {
callback(error, encoding ? buffer.toString(encoding) : buffer);
});
return fsReadFileAsar(pathArgument, options, callback);
};
fs.promises.readFile = util.promisify(fs.readFile);
const { readFile: readFilePromise } = fs.promises;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
fs.promises.readFile = function (pathArgument: string, options: any) {
const pathInfo = splitPath(pathArgument);
if (!pathInfo.isAsar) {
return readFilePromise.apply(this, arguments);
}
const p = util.promisify(fsReadFileAsar);
return p(pathArgument, options);
};
const { readFileSync } = fs;
fs.readFileSync = function (pathArgument: string, options: any) {

View File

@@ -75,6 +75,7 @@ ipcMainInternal.on(
const browserWindowOptions = (event.sender as any)._callWindowOpenHandler(event, url, frameName, features);
if (event.defaultPrevented) {
event.returnValue = null;
return;
}
const guest = openGuestWindow({

View File

@@ -271,7 +271,7 @@ const warnAboutAllowedPopups = function () {
const warnAboutRemoteModuleWithRemoteContent = function (webPreferences?: Electron.WebPreferences) {
if (!webPreferences || isLocalhost()) return;
const remoteModuleEnabled = webPreferences.enableRemoteModule != null ? !!webPreferences.enableRemoteModule : true;
const remoteModuleEnabled = webPreferences.enableRemoteModule != null ? !!webPreferences.enableRemoteModule : false;
if (!remoteModuleEnabled) return;
if (getIsRemoteProtocol()) {
@@ -298,7 +298,9 @@ const logSecurityWarnings = function (
warnAboutEnableBlinkFeatures(webPreferences);
warnAboutInsecureCSP();
warnAboutAllowedPopups();
warnAboutRemoteModuleWithRemoteContent(webPreferences);
if (BUILDFLAG(ENABLE_REMOTE_MODULE)) {
warnAboutRemoteModuleWithRemoteContent(webPreferences);
}
};
const getWebPreferences = async function () {

View File

@@ -12,6 +12,9 @@ require('../common/reset-search-paths');
// Import common settings.
require('@electron/internal/common/init');
// Process command line arguments.
const { hasSwitch, getSwitchValue } = process._linkedBinding('electron_common_command_line');
// Export node bindings to global.
const { makeRequireFunction } = __non_webpack_require__('internal/modules/cjs/helpers') // eslint-disable-line
global.module = new Module('electron/js2c/worker_init');
@@ -32,4 +35,10 @@ if (self.location.protocol === 'file:') {
// For backwards compatibility we fake these two paths here
global.__filename = path.join(process.resourcesPath, 'electron.asar', 'worker', 'init.js');
global.__dirname = path.join(process.resourcesPath, 'electron.asar', 'worker');
const appPath = hasSwitch('app-path') ? getSwitchValue('app-path') : null;
if (appPath) {
// Search for module under the app directory.
global.module.paths = Module._nodeModulePaths(appPath);
}
}

View File

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

View File

@@ -1 +1,2 @@
d3d11_skip_blits_if_there_is_no_intersection_of_dest_areas.patch
cherry-pick-3d4f87ab5b9b.patch

View File

@@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Thu, 20 May 2021 12:22:46 -0400
Subject: D3D11: Fix respecifying 3D textures.
The missing check for the "Depth" dimension could lead to a bug
where we would not recreate a texture when the dimension changed.
Bug: chromium:1210414
Change-Id: Id59097ad14ae77ff80d27081f61786dad17a77ea
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2911032
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 2697358464cf20576701987f60300b6c4086c11e)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2937026
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
index c502d00fac032ea708015bbbf4f51db2dc2b3c59..daa5c3abc3ab4f4460ec48d0aba9649cf66897ac 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
@@ -223,8 +223,8 @@ bool Image11::redefine(gl::TextureType type,
const gl::Extents &size,
bool forceRelease)
{
- if (mWidth != size.width || mHeight != size.height || mInternalFormat != internalformat ||
- forceRelease)
+ if (mWidth != size.width || mHeight != size.height || mDepth != size.depth ||
+ mInternalFormat != internalformat || forceRelease)
{
// End the association with the TextureStorage, since that data will be out of date.
// Also reset mRecoveredFromStorageCount since this Image is getting completely redefined.
diff --git a/src/tests/gl_tests/MipmapTest.cpp b/src/tests/gl_tests/MipmapTest.cpp
index b335d4901ef11b27e57d0ee6445b15ce5e7567fe..4b6046d4f8d3da97d70a837422c2ddd8d7599fc6 100644
--- a/src/tests/gl_tests/MipmapTest.cpp
+++ b/src/tests/gl_tests/MipmapTest.cpp
@@ -2044,6 +2044,22 @@ void main()
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::green);
}
+// Tests respecifying 3D mipmaps.
+TEST_P(MipmapTestES3, Generate3DMipmapRespecification)
+{
+ std::vector<GLColor> pixels(256 * 256 * 100, GLColor::black);
+
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_3D, texture);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 256, 256, 100, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixels.data());
+ glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, 128, 128, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixels.data());
+ glGenerateMipmap(GL_TEXTURE_3D);
+
+ ASSERT_GL_NO_ERROR();
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(MipmapTest);

View File

@@ -130,3 +130,20 @@ media_feeds_disable_media_feeds_and_related_features.patch
remove_tabs_and_line_breaks_from_the_middle_of_app_names_when.patch
autofill_fixed_refill_of_changed_form.patch
x11_fix_window_enumeration_order_when_wm_doesn_t_set.patch
cherry-pick-34d5af37f9ac.patch
m90-lts_longtaskdetector_remove_container_mutation_during.patch
m90-lts_reduce_memory_consumption_on.patch
cherry-pick-b77b38a3380c.patch
cherry-pick-910e9e40d376.patch
cherry-pick-d9556a80a790.patch
cherry-pick-ee6aee64e24c.patch
webview_fullscreen.patch
set_svgimage_page_after_document_install.patch
cherry-pick-e60cc80ff744.patch
cherry-pick-3feda0244490.patch
cherry-pick-cd98d7c0dae9.patch
replace_first_of_two_waitableevents_in_creditcardaccessmanager.patch
cherry-pick-ac9dc1235e28.patch
cherry-pick-4ce2abc17078.patch
cherry-pick-e2123a8e0943.patch
cherry-pick-1227933.patch

View File

@@ -0,0 +1,215 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Koji Ishii <kojii@chromium.org>
Date: Mon, 26 Jul 2021 07:09:18 +0000
Subject: Fix nested inline box fragmentation
This patch fixes when nested inline boxes are fragmented in a
line due to bidi reordering.
Before this change, the fragmented boxes are appended to the
end of |box_data_list_|. Then when |NGInlineLayoutStateStack::
CreateBoxFragments| creates inline boxes in the ascending
order of |box_data_list_|, it failed to add the fragmented
boxes into their parent inline boxes.
This is critical for out-of-flow positioned objects whose
containing block is an inline box, because they expect to be
propagated through all ancestor inline boxes.
|UpdateBoxDataFragmentRange| is a little tricky by appending
to a vector it is iterating. Changing it to insert to the
correct position makes the function even trickier. This patch
changes it to add fragmented boxes to a separate vector, and
let later process |UpdateFragmentedBoxDataEdges| to merge the
vector to |box_data_list_|.
(cherry picked from commit 9c8a39c14a9c80556468593cddf436f5047a16ce)
Bug: 1227933, 1229999
Change-Id: I7edcd209e1fdac06bab01b16d660383e7e9c37bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3038308
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#903356}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3053212
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#145}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
index b257014513cb881d4531694b86c05fd21edb6732..9a3f6f3af7839ebed24f7d8a32b7f95fba66cd9a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h"
+#include "base/containers/adapters.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_offset.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h"
@@ -387,13 +388,14 @@ void NGInlineLayoutStateStack::UpdateAfterReorder(
box_data.fragment_start = box_data.fragment_end = 0;
// Scan children and update start/end from their box_data_index.
- unsigned box_count = box_data_list_.size();
+ Vector<BoxData> fragmented_boxes;
for (unsigned index = 0; index < line_box->size();)
- index = UpdateBoxDataFragmentRange(line_box, index);
+ index = UpdateBoxDataFragmentRange(line_box, index, &fragmented_boxes);
- // If any inline fragmentation due to BiDi reorder, adjust box edges.
- if (box_count != box_data_list_.size())
- UpdateFragmentedBoxDataEdges();
+ // If any inline fragmentation occurred due to BiDi reorder, append them and
+ // adjust box edges.
+ if (UNLIKELY(!fragmented_boxes.IsEmpty()))
+ UpdateFragmentedBoxDataEdges(&fragmented_boxes);
#if DCHECK_IS_ON()
// Check all BoxData have ranges.
@@ -410,7 +412,8 @@ void NGInlineLayoutStateStack::UpdateAfterReorder(
unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
NGLogicalLineItems* line_box,
- unsigned index) {
+ unsigned index,
+ Vector<BoxData>* fragmented_boxes) {
// Find the first line box item that should create a box fragment.
for (; index < line_box->size(); index++) {
NGLogicalLineItem* start = &(*line_box)[index];
@@ -438,7 +441,7 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
// It also changes other BoxData, but not the one we're dealing with here
// because the update is limited only when its |box_data_index| is lower.
while (end->box_data_index && end->box_data_index < box_data_index) {
- UpdateBoxDataFragmentRange(line_box, index);
+ UpdateBoxDataFragmentRange(line_box, index, fragmented_boxes);
}
if (box_data_index != end->box_data_index)
@@ -453,14 +456,9 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
} else {
// This box is fragmented by BiDi reordering. Add a new BoxData for the
// fragmented range.
- box_data_list_[box_data_index - 1].fragmented_box_data_index =
- box_data_list_.size();
- // Do not use `emplace_back()` here because adding to |box_data_list_| may
- // reallocate the buffer, but the `BoxData` ctor must run before the
- // reallocation. Create a new instance and |push_back()| instead.
- BoxData fragmented_box_data(box_data_list_[box_data_index - 1],
- start_index, index);
- box_data_list_.push_back(fragmented_box_data);
+ BoxData& fragmented_box = fragmented_boxes->emplace_back(
+ box_data_list_[box_data_index - 1], start_index, index);
+ fragmented_box.fragmented_box_data_index = box_data_index;
}
// If this box has parent boxes, we need to process it again.
if (box_data_list_[box_data_index - 1].parent_box_data_index)
@@ -470,7 +468,43 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
return index;
}
-void NGInlineLayoutStateStack::UpdateFragmentedBoxDataEdges() {
+void NGInlineLayoutStateStack::UpdateFragmentedBoxDataEdges(
+ Vector<BoxData>* fragmented_boxes) {
+ DCHECK(!fragmented_boxes->IsEmpty());
+ // Append in the descending order of |fragmented_box_data_index| because the
+ // indices will change as boxes are inserted into |box_data_list_|.
+ std::sort(fragmented_boxes->begin(), fragmented_boxes->end(),
+ [](const BoxData& a, const BoxData& b) {
+ if (a.fragmented_box_data_index != b.fragmented_box_data_index) {
+ return a.fragmented_box_data_index <
+ b.fragmented_box_data_index;
+ }
+ DCHECK_NE(a.fragment_start, b.fragment_start);
+ return a.fragment_start < b.fragment_start;
+ });
+ for (BoxData& fragmented_box : base::Reversed(*fragmented_boxes)) {
+ // Insert the fragmented box to right after the box it was fragmented from.
+ // The order in the |box_data_list_| is critical when propagating child
+ // fragment data such as OOF to ancestors.
+ const unsigned insert_at = fragmented_box.fragmented_box_data_index;
+ DCHECK_GT(insert_at, 0u);
+ fragmented_box.fragmented_box_data_index = 0;
+ box_data_list_.insert(insert_at, fragmented_box);
+
+ // Adjust box data indices by the insertion.
+ for (BoxData& box_data : box_data_list_) {
+ if (box_data.fragmented_box_data_index >= insert_at)
+ ++box_data.fragmented_box_data_index;
+ }
+
+ // Set the index of the last fragment to the original box. This is needed to
+ // update fragment edges.
+ const unsigned fragmented_from = insert_at - 1;
+ if (!box_data_list_[fragmented_from].fragmented_box_data_index)
+ box_data_list_[fragmented_from].fragmented_box_data_index = insert_at;
+ }
+
+ // Move the line-right edge to the last fragment.
for (BoxData& box_data : box_data_list_) {
if (box_data.fragmented_box_data_index)
box_data.UpdateFragmentEdges(box_data_list_);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
index 82ecfef8fe4d404d5713f0f67d83b38ecfbfca4c..9d079266efd7f2ccc43cef40d8d89e4fc6edda9e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -156,17 +156,6 @@ class CORE_EXPORT NGInlineLayoutStateStack {
// reordering.
void UpdateAfterReorder(NGLogicalLineItems*);
- // Update start/end of the first BoxData found at |index|.
- //
- // If inline fragmentation is found, a new BoxData is added.
- //
- // Returns the index to process next. It should be given to the next call to
- // this function.
- unsigned UpdateBoxDataFragmentRange(NGLogicalLineItems*, unsigned index);
-
- // Update edges of inline fragmented boxes.
- void UpdateFragmentedBoxDataEdges();
-
// Compute inline positions of fragments and boxes.
LayoutUnit ComputeInlinePositions(NGLogicalLineItems*, LayoutUnit position);
@@ -259,6 +248,19 @@ class CORE_EXPORT NGInlineLayoutStateStack {
scoped_refptr<const NGLayoutResult> CreateBoxFragment(NGLogicalLineItems*);
};
+ // Update start/end of the first BoxData found at |index|.
+ //
+ // If inline fragmentation is found, a new BoxData is added.
+ //
+ // Returns the index to process next. It should be given to the next call to
+ // this function.
+ unsigned UpdateBoxDataFragmentRange(NGLogicalLineItems*,
+ unsigned index,
+ Vector<BoxData>* fragmented_boxes);
+
+ // Update edges of inline fragmented boxes.
+ void UpdateFragmentedBoxDataEdges(Vector<BoxData>* fragmented_boxes);
+
Vector<NGInlineBoxState, 4> stack_;
Vector<BoxData, 4> box_data_list_;
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html b/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..b701d2b5688ace54aa99530c12fa8143f1e6a508
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="author" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://crbug.com/1229999">
+<div style="direction:rtl; width:500px">
+ <span style="border:solid">
+ <span style="position:relative">
+ <div style="display:inline-block; width:1000%; height:10px"></div>
+ <span dir="ltr">
+ <div style="position:absolute"></div>
+ </span>
+ </span>
+ </span>
+</div>

View File

@@ -0,0 +1,101 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Asami Doi <asamidoi@chromium.org>
Date: Thu, 10 Jun 2021 07:03:17 +0000
Subject: BFCache: remove a controllee stored in `bfcached_controllee_map_`
This CL fixes the UAF that happens with the following case:
Let's assume we have 2 service workers (sw1.js and sw2.js) are
registered in the same page. When the second service worker (sw2.js) is
registered, ServiceWorkerContainerHost::UpdateController() is called
and the previous SWVersion (sw1.js) removes a controllee from
`controllee_map_`. If BackForwardCache is enabled, a controllee is
stored in `bfcached_controllee_map_` instead and the controllee will
not be removed in ServiceWorkerContainerHost::UpdateController().
When ServiceWorkerContainerHost::UpdateController() is called and
keep a controllee in `bfcached_controllee_map_`, and a page navigates to
a different page (evicts BFCache), use-after-free (UAF) happens.
This CL updates ServiceWorkerContainerHost::UpdateController()
to remove a controllee from `bfcached_controllee_map_` if it exists.
(cherry picked from commit a2414a05a486ca0ad18ba4caf78e883a668a0555)
(cherry picked from commit 7cd7f6741fc4491c2f7ef21052a370ee23887e37)
Bug: 1212618
Change-Id: I13e023e6d273268a08ea9276a056f7f5acba39cd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919020
Commit-Queue: Asami Doi <asamidoi@chromium.org>
Reviewed-by: Matt Falkenhagen <falken@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#887109}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929401
Reviewed-by: Krishna Govind <govind@chromium.org>
Reviewed-by: Ben Mason <benmason@chromium.org>
Reviewed-by: Prudhvi Kumar Bommana <pbommana@google.com>
Commit-Queue: Krishna Govind <govind@chromium.org>
Owners-Override: Krishna Govind <govind@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4472@{#1375}
Cr-Original-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2944946
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4430@{#1512}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/content/browser/service_worker/service_worker_container_host.cc b/content/browser/service_worker/service_worker_container_host.cc
index 0b1981efd9eb008caea1c94da138a2ed7c386bc5..9a2193ac5a4e8a738bef8e391145deecef9b9ac2 100644
--- a/content/browser/service_worker/service_worker_container_host.cc
+++ b/content/browser/service_worker/service_worker_container_host.cc
@@ -138,7 +138,7 @@ ServiceWorkerContainerHost::~ServiceWorkerContainerHost() {
}
if (IsContainerForClient() && controller_)
- controller_->OnControlleeDestroyed(client_uuid());
+ controller_->Uncontrol(client_uuid());
// Remove |this| as an observer of ServiceWorkerRegistrations.
// TODO(falken): Use ScopedObserver instead of this explicit call.
@@ -1244,7 +1244,7 @@ void ServiceWorkerContainerHost::UpdateController(
}
}
if (previous_version)
- previous_version->RemoveControllee(client_uuid());
+ previous_version->Uncontrol(client_uuid());
// SetController message should be sent only for clients.
DCHECK(IsContainerForClient());
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 798d0bd350976cf2724e4d4b726c24d63e0a5ec3..5e268a5331e80ff7c6c93c425171bbd31ddb342a 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -886,8 +886,7 @@ void ServiceWorkerVersion::RemoveControlleeFromBackForwardCacheMap(
bfcached_controllee_map_.erase(client_uuid);
}
-void ServiceWorkerVersion::OnControlleeDestroyed(
- const std::string& client_uuid) {
+void ServiceWorkerVersion::Uncontrol(const std::string& client_uuid) {
if (!IsBackForwardCacheEnabled()) {
RemoveControllee(client_uuid);
} else {
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index cb5afe636f45b70fce2ff313641834bf7bddff30..a96d2c4575fa3879cf6133fbe656cb20745bd66a 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -394,9 +394,12 @@ class CONTENT_EXPORT ServiceWorkerVersion
void RestoreControlleeFromBackForwardCacheMap(const std::string& client_uuid);
// Called when a back-forward cached controllee is evicted or destroyed.
void RemoveControlleeFromBackForwardCacheMap(const std::string& client_uuid);
- // Called when a controllee is destroyed. Remove controllee from whichever
- // map it belongs to, or do nothing when it is already removed.
- void OnControlleeDestroyed(const std::string& client_uuid);
+ // Called when this version should no longer be the controller of this client.
+ // Called when the controllee is destroyed or it changes controller. Removes
+ // controllee from whichever map it belongs to, or do nothing when it is
+ // already removed. This function is different from RemoveController(), which
+ // can only be called if the controllee is not in the back-forward cache map.
+ void Uncontrol(const std::string& client_uuid);
// Returns true if this version has a controllee.
// Note regarding BackForwardCache:

View File

@@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Reilly Grant <reillyg@chromium.org>
Date: Mon, 28 Jun 2021 21:55:24 +0000
Subject: serial: Fix parent class tracing for SerialPort
When SerialPort was updated to be ActiveScriptWrappable and an
EventTarget the Trace method was not updated to call the parent class
trace methods.
(cherry picked from commit 4059ecc3a5352601a4d79196f90c8ca19262afe1)
Bug: 1220078
Change-Id: If6967a913268bce86d4488359a9418a814530f84
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2965255
Auto-Submit: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#893039}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2992740
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/branch-heads/4472@{#1531}
Cr-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
diff --git a/third_party/blink/renderer/modules/serial/serial_port.cc b/third_party/blink/renderer/modules/serial/serial_port.cc
index b485935f6cfd1b397d86acb90ebf344e22e18a2c..835ac5f3526d1a933f81e3546344aa409a5eec09 100644
--- a/third_party/blink/renderer/modules/serial/serial_port.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -508,7 +508,8 @@ void SerialPort::Trace(Visitor* visitor) const {
visitor->Trace(open_resolver_);
visitor->Trace(signal_resolvers_);
visitor->Trace(close_resolver_);
- ScriptWrappable::Trace(visitor);
+ EventTargetWithInlineData::Trace(visitor);
+ ActiveScriptWrappable<SerialPort>::Trace(visitor);
}
bool SerialPort::HasPendingActivity() const {

View File

@@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Flack <flackr@chromium.org>
Date: Fri, 30 Jul 2021 18:51:38 +0000
Subject: Forbid script execution for entire lifecycle update
We should not execute script during the lifecycle update except in cases where we we know it is safe to do so, either because we will rerun the lifecycle steps if anything is invalidated (resize observers, intersection observers) or because the script does not have access to invalidate the DOM (e.g. paint worklets).
(cherry picked from commit a73237da91de8aa49aaa5d9479bae51cf387f090)
Bug: 1196853
Change-Id: Id1fdbbb25107cfdc6c234123f845406c28d32914
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2815619
Reviewed-by: Stefan Zager <szager@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#901110}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3058973
Auto-Submit: Robert Flack <flackr@chromium.org>
Commit-Queue: Stefan Zager <szager@chromium.org>
Cr-Commit-Position: refs/branch-heads/4472@{#1588}
Cr-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index d3512edd4cad7b7dafbb1c3a6da5cd45ea367e79..69f8e8a598a4aefef652e603f1590c702e288b59 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -96,6 +96,7 @@
#include "third_party/blink/renderer/core/script/classic_script.h"
#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
@@ -804,6 +805,8 @@ void WebPluginContainerImpl::Dispose() {
}
if (web_plugin_) {
+ // Plugins may execute script on being detached during the lifecycle update.
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
CHECK(web_plugin_->Container() == this);
web_plugin_->Destroy();
web_plugin_ = nullptr;
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 dd320dd900b7f556c9216c7faedc2ad35588b0d7..a9e724432440c05d1b3bb9863acb4345e07f77b4 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2484,6 +2484,7 @@ bool LocalFrameView::UpdateLifecyclePhases(
void LocalFrameView::UpdateLifecyclePhasesInternal(
DocumentLifecycle::LifecycleState target_state) {
+ ScriptForbiddenScope forbid_script;
// RunScrollTimelineSteps must not run more than once.
bool should_run_scroll_timeline_steps = true;
@@ -2564,6 +2565,10 @@ void LocalFrameView::UpdateLifecyclePhasesInternal(
continue;
}
+ // At this point in time, script is allowed to run as we will repeat the
+ // lifecycle update if anything is invalidated.
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
+
// ResizeObserver and post-layout IntersectionObserver observation
// deliveries may dirty style and layout. RunResizeObserverSteps will return
// true if any observer ran that may have dirtied style or layout;
@@ -2816,6 +2821,7 @@ bool LocalFrameView::AnyFrameIsPrintingOrPaintingPreview() {
}
void LocalFrameView::RunPaintLifecyclePhase(PaintBenchmarkMode benchmark_mode) {
+ DCHECK(ScriptForbiddenScope::IsScriptForbidden());
TRACE_EVENT0("blink,benchmark", "LocalFrameView::RunPaintLifecyclePhase");
// While printing or capturing a paint preview of a document, the paint walk
// is done into a special canvas. There is no point doing a normal paint step
@@ -2850,17 +2856,11 @@ void LocalFrameView::RunPaintLifecyclePhase(PaintBenchmarkMode benchmark_mode) {
for (PaintLayerScrollableArea* area : *animating_scrollable_areas)
area->UpdateCompositorScrollAnimations();
}
- {
- // Updating animations can notify ready promises which could mutate
- // the DOM. We should delay these until we have finished the lifecycle
- // update. https://crbug.com/1196781
- ScriptForbiddenScope forbid_script;
- frame_view.GetLayoutView()
- ->GetDocument()
- .GetDocumentAnimations()
- .UpdateAnimations(DocumentLifecycle::kPaintClean,
- paint_artifact_compositor_.get());
- }
+ frame_view.GetLayoutView()
+ ->GetDocument()
+ .GetDocumentAnimations()
+ .UpdateAnimations(DocumentLifecycle::kPaintClean,
+ paint_artifact_compositor_.get());
Document& document = frame_view.GetLayoutView()->GetDocument();
total_animations_count +=
document.GetDocumentAnimations().GetAnimationsCount();
@@ -4454,6 +4454,7 @@ void LocalFrameView::RenderThrottlingStatusChanged() {
// so painting the tree should just clear the previous painted output.
DCHECK(!IsUpdatingLifecycle());
AllowThrottlingScope allow_throtting(*this);
+ ScriptForbiddenScope forbid_script;
RunPaintLifecyclePhase();
}
@@ -4989,6 +4990,7 @@ void LocalFrameView::RunPaintBenchmark(int repeat_count,
// quantization when the time is very small.
base::LapTimer timer(kWarmupRuns, kTimeLimit, kTimeCheckInterval);
do {
+ ScriptForbiddenScope forbid_script;
RunPaintLifecyclePhase(mode);
timer.NextLap();
} while (!timer.HasTimeLimitExpired());
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
index e6e0c5b909c4d073963bcbb074bfb091a6ccb83b..618e08fbb5157c06348feee5f0120bd28ed0bc44 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_id_generator.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h"
+#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/graphics/paint_generated_image.h"
namespace blink {
@@ -126,6 +127,10 @@ scoped_refptr<Image> PaintWorklet::Paint(const String& name,
layout_object.GetDocument(), layout_object.StyleRef(),
paint_definition->NativeInvalidationProperties(),
paint_definition->CustomInvalidationProperties());
+ // The PaintWorkletGlobalScope is sufficiently isolated that it is safe to
+ // run during the lifecycle update without concern for it causing
+ // invalidations to the lifecycle.
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
sk_sp<PaintRecord> paint_record = paint_definition->Paint(
container_size, zoom, style_map, data, device_scale_factor);
if (!paint_record)

View File

@@ -0,0 +1,204 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matt Menke <mmenke@chromium.org>
Date: Thu, 10 Jun 2021 07:05:07 +0000
Subject: Fix URLLoader cleanup on CorsURLLoaderFactory destruction.
Destroying one URLLoader can result in other URLLoaders getting errors,
due to to cache interconnectedness. CorsURLLoaderFactory's destructor
was not taking that into account.
Also fix a bonus bug: HttpCache::Transaction::response_ wasn't being
cleared in HttpCache::Transaction::DoHeadersPhaseCannotProceed(), which
could result in DCHECKs when calling GetResponseInfo() when a
transaction that was waiting on a cached response from another
transaction ended up failing.
[M90]: Fixed trivial conflict
(cherry picked from commit 2f49a3c69a2184c95f43a395e4f33a3959cb8dbc)
(cherry picked from commit baf23e3c5b1394982cff718a0e055d4f239245ad)
Bug: 1209769
Change-Id: I2c18caa488767a29011aca1e1b0bace24c1ba8fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2922826
Reviewed-by: Maksim Orlovich <morlovich@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#887522}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2935241
Auto-Submit: Matt Menke <mmenke@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4472@{#1433}
Cr-Original-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2948654
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Reviewed-by: Matt Menke <mmenke@chromium.org>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4430@{#1513}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index bb0b938e71f92c2743df2c12824e8f634f6ed5e2..6a1ccb4657f8de1a14396366b560bc11f4cee829 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -2115,6 +2115,8 @@ int HttpCache::Transaction::DoHeadersPhaseCannotProceed(int result) {
entry_ = nullptr;
new_entry_ = nullptr;
+ SetResponse(HttpResponseInfo());
+
// Bypass the cache for timeout scenario.
if (result == ERR_CACHE_LOCK_TIMEOUT)
effective_load_flags_ |= LOAD_DISABLE_CACHE;
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index 7e4d57cf7f2f8e4e0aa208f53f83833fc0c68112..bf744d52473e31fb100ccf1644abd5e9122ba669 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -228,7 +228,17 @@ CorsURLLoaderFactory::CorsURLLoaderFactory(
&CorsURLLoaderFactory::DeleteIfNeeded, base::Unretained(this)));
}
-CorsURLLoaderFactory::~CorsURLLoaderFactory() = default;
+CorsURLLoaderFactory::~CorsURLLoaderFactory() {
+ // Delete loaders one at a time, since deleting one loader can cause another
+ // loader waiting on it to fail synchronously, which could result in the other
+ // loader calling DestroyURLLoader().
+ while (!loaders_.empty()) {
+ // No need to call context_->LoaderDestroyed(), since this method is only
+ // called from the NetworkContext's destructor, or when there are no
+ // remaining URLLoaders.
+ loaders_.erase(loaders_.begin());
+ }
+}
void CorsURLLoaderFactory::OnLoaderCreated(
std::unique_ptr<mojom::URLLoader> loader) {
diff --git a/services/network/cors/cors_url_loader_factory_unittest.cc b/services/network/cors/cors_url_loader_factory_unittest.cc
index 13811282f5bc922cce50a2d0c0c041d1cdd586c1..dd3361f818590031b8a843595bea1223e012bf3e 100644
--- a/services/network/cors/cors_url_loader_factory_unittest.cc
+++ b/services/network/cors/cors_url_loader_factory_unittest.cc
@@ -7,7 +7,9 @@
#include "base/macros.h"
#include "base/test/task_environment.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "net/base/load_flags.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
@@ -49,6 +51,9 @@ class CorsURLLoaderFactoryTest : public testing::Test {
protected:
// testing::Test implementation.
void SetUp() override {
+ test_server_.AddDefaultHandlers();
+ ASSERT_TRUE(test_server_.Start());
+
network_service_ = NetworkService::CreateForTesting();
auto context_params = mojom::NetworkContextParams::New();
@@ -68,7 +73,7 @@ class CorsURLLoaderFactoryTest : public testing::Test {
auto factory_params = network::mojom::URLLoaderFactoryParams::New();
factory_params->process_id = kProcessId;
factory_params->request_initiator_origin_lock =
- url::Origin::Create(GURL("http://localhost"));
+ url::Origin::Create(test_server_.base_url());
auto resource_scheduler_client =
base::MakeRefCounted<ResourceSchedulerClient>(
kProcessId, kRouteId, &resource_scheduler_,
@@ -81,15 +86,25 @@ class CorsURLLoaderFactoryTest : public testing::Test {
}
void CreateLoaderAndStart(const ResourceRequest& request) {
+ url_loaders_.emplace_back(mojo::Remote<mojom::URLLoader>());
+ test_cors_loader_clients_.emplace_back(
+ std::make_unique<TestURLLoaderClient>());
cors_url_loader_factory_->CreateLoaderAndStart(
- url_loader_.BindNewPipeAndPassReceiver(), kRouteId, kRequestId,
+ url_loaders_.back().BindNewPipeAndPassReceiver(), kRouteId, kRequestId,
mojom::kURLLoadOptionNone, request,
- test_cors_loader_client_.CreateRemote(),
+ test_cors_loader_clients_.back()->CreateRemote(),
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}
void ResetFactory() { cors_url_loader_factory_.reset(); }
+ net::test_server::EmbeddedTestServer* test_server() { return &test_server_; }
+
+ std::vector<std::unique_ptr<TestURLLoaderClient>>&
+ test_cors_loader_clients() {
+ return test_cors_loader_clients_;
+ }
+
private:
// Test environment.
base::test::TaskEnvironment task_environment_;
@@ -99,15 +114,17 @@ class CorsURLLoaderFactoryTest : public testing::Test {
std::unique_ptr<NetworkContext> network_context_;
mojo::Remote<mojom::NetworkContext> network_context_remote_;
+ net::test_server::EmbeddedTestServer test_server_;
+
// CorsURLLoaderFactory instance under tests.
std::unique_ptr<mojom::URLLoaderFactory> cors_url_loader_factory_;
mojo::Remote<mojom::URLLoaderFactory> cors_url_loader_factory_remote_;
- // Holds URLLoader that CreateLoaderAndStart() creates.
- mojo::Remote<mojom::URLLoader> url_loader_;
+ // Holds the URLLoaders that CreateLoaderAndStart() creates.
+ std::vector<mojo::Remote<mojom::URLLoader>> url_loaders_;
- // TestURLLoaderClient that records callback activities.
- TestURLLoaderClient test_cors_loader_client_;
+ // TestURLLoaderClients that record callback activities.
+ std::vector<std::unique_ptr<TestURLLoaderClient>> test_cors_loader_clients_;
// Holds for allowed origin access lists.
OriginAccessList origin_access_list_;
@@ -118,7 +135,7 @@ class CorsURLLoaderFactoryTest : public testing::Test {
// Regression test for https://crbug.com/906305.
TEST_F(CorsURLLoaderFactoryTest, DestructionOrder) {
ResourceRequest request;
- GURL url("http://localhost");
+ GURL url = test_server()->GetURL("/hung");
request.mode = mojom::RequestMode::kNoCors;
request.credentials_mode = mojom::CredentialsMode::kOmit;
request.method = net::HttpRequestHeaders::kGetMethod;
@@ -141,5 +158,36 @@ TEST_F(CorsURLLoaderFactoryTest, DestructionOrder) {
ResetFactory();
}
+TEST_F(CorsURLLoaderFactoryTest, CleanupWithSharedCacheObjectInUse) {
+ // Create a loader for a response that hangs after receiving headers, and run
+ // it until headers are received.
+ ResourceRequest request;
+ GURL url = test_server()->GetURL("/hung-after-headers");
+ request.mode = mojom::RequestMode::kNoCors;
+ request.credentials_mode = mojom::CredentialsMode::kOmit;
+ request.method = net::HttpRequestHeaders::kGetMethod;
+ request.url = url;
+ request.request_initiator = url::Origin::Create(url);
+ CreateLoaderAndStart(request);
+ test_cors_loader_clients().back()->RunUntilResponseReceived();
+
+ // Read only requests will fail synchonously on destruction of the request
+ // they're waiting on if they're in the |done_headers_queue| when the other
+ // request fails. Make a large number of such requests, spin the message loop
+ // so they end up blocked on the hung request, and then destroy all loads. A
+ // large number of loaders is needed because they're stored in a set, indexed
+ // by address, so teardown order is random.
+ request.load_flags =
+ net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION;
+ for (int i = 0; i < 10; ++i)
+ CreateLoaderAndStart(request);
+ base::RunLoop().RunUntilIdle();
+
+ // This should result in a crash if tearing down one URLLoaderFactory
+ // resulting in a another one failing causes a crash during teardown. See
+ // https://crbug.com/1209769.
+ ResetFactory();
+}
+
} // namespace cors
} // namespace network

View File

@@ -0,0 +1,103 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ilya Nikolaevskiy <ilnik@chromium.org>
Date: Mon, 17 May 2021 08:34:41 +0000
Subject: Add locks and empty string checks to FakeV4L2Impl
FakeV4L2Impl is crashed by fuzzer with some weird ASAN errors, which
turned out to be a threading issue.
Bug: 1205059,1196302
Change-Id: Ieb3a917c9a4549b655862e69214774e183a70bc3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2883613
Reviewed-by: Ricky Liang <jcliang@chromium.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#883390}
diff --git a/media/capture/video/linux/fake_v4l2_impl.cc b/media/capture/video/linux/fake_v4l2_impl.cc
index 4a976815d009e68b3740aa71e8c8fd641bf91493..09647474bed3c7c7b34cd9fb161edd2a7d2e170f 100644
--- a/media/capture/video/linux/fake_v4l2_impl.cc
+++ b/media/capture/video/linux/fake_v4l2_impl.cc
@@ -380,10 +380,16 @@ FakeV4L2Impl::~FakeV4L2Impl() = default;
void FakeV4L2Impl::AddDevice(const std::string& device_name,
const FakeV4L2DeviceConfig& config) {
+ base::AutoLock lock(lock_);
device_configs_.emplace(device_name, config);
}
int FakeV4L2Impl::open(const char* device_name, int flags) {
+ if (!device_name)
+ return kInvalidId;
+
+ base::AutoLock lock(lock_);
+
std::string device_name_as_string(device_name);
auto device_configs_iter = device_configs_.find(device_name_as_string);
if (device_configs_iter == device_configs_.end())
@@ -403,6 +409,7 @@ int FakeV4L2Impl::open(const char* device_name, int flags) {
}
int FakeV4L2Impl::close(int fd) {
+ base::AutoLock lock(lock_);
auto device_iter = opened_devices_.find(fd);
if (device_iter == opened_devices_.end())
return kErrorReturnValue;
@@ -412,6 +419,7 @@ int FakeV4L2Impl::close(int fd) {
}
int FakeV4L2Impl::ioctl(int fd, int request, void* argp) {
+ base::AutoLock lock(lock_);
auto device_iter = opened_devices_.find(fd);
if (device_iter == opened_devices_.end())
return EBADF;
@@ -518,6 +526,7 @@ void* FakeV4L2Impl::mmap(void* /*start*/,
int flags,
int fd,
off_t offset) {
+ base::AutoLock lock(lock_);
if (flags & MAP_FIXED) {
errno = EINVAL;
return MAP_FAILED;
@@ -543,10 +552,12 @@ void* FakeV4L2Impl::mmap(void* /*start*/,
}
int FakeV4L2Impl::munmap(void* start, size_t length) {
+ base::AutoLock lock(lock_);
return kSuccessReturnValue;
}
int FakeV4L2Impl::poll(struct pollfd* ufds, unsigned int nfds, int timeout) {
+ base::AutoLock lock(lock_);
if (nfds != 1) {
// We only support polling of a single device.
errno = EINVAL;
diff --git a/media/capture/video/linux/fake_v4l2_impl.h b/media/capture/video/linux/fake_v4l2_impl.h
index 0a035a97dd8761b08eb4cfdbe2865efc346f0e23..ae7167f95163581c756ab4951717fd4352c67757 100644
--- a/media/capture/video/linux/fake_v4l2_impl.h
+++ b/media/capture/video/linux/fake_v4l2_impl.h
@@ -10,6 +10,7 @@
#include <linux/videodev2.h>
+#include "base/synchronization/lock.h"
#include "media/capture/capture_export.h"
#include "media/capture/video/linux/v4l2_capture_device.h"
#include "media/capture/video/video_capture_device_descriptor.h"
@@ -52,11 +53,13 @@ class CAPTURE_EXPORT FakeV4L2Impl : public V4L2CaptureDevice {
private:
class OpenedDevice;
- int next_id_to_return_from_open_;
- std::map<std::string, FakeV4L2DeviceConfig> device_configs_;
- std::map<std::string, int> device_name_to_open_id_map_;
+ base::Lock lock_;
+
+ int next_id_to_return_from_open_ GUARDED_BY(lock_);
+ std::map<std::string, FakeV4L2DeviceConfig> device_configs_ GUARDED_BY(lock_);
+ std::map<std::string, int> device_name_to_open_id_map_ GUARDED_BY(lock_);
std::map<int /*value returned by open()*/, std::unique_ptr<OpenedDevice>>
- opened_devices_;
+ opened_devices_ GUARDED_BY(lock_);
};
} // namespace media

View File

@@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brandon Jones <bajones@chromium.org>
Date: Wed, 16 Jun 2021 21:47:09 +0000
Subject: Ensure that XRLayer includes base EventTarget in Trace
Trace was skipping a level in the class hierarchy and calling
ScriptWrappable::Trace() instead. This was likely the result of the
class inheritance changing in the spec a while back and getting updated
elsewhere but not here, since it didn't raise any warnings.
(cherry picked from commit 01b6f7e0a70648d7c7302454993f0bf86d5a0241)
Bug: 1219857
Change-Id: I4ac9f7b037ac5e5dd0e6d670f1d5a30e6344862f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2964533
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#892650}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2967199
Auto-Submit: Brandon Jones <bajones@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4472@{#1492}
Cr-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
diff --git a/third_party/blink/renderer/modules/xr/xr_layer.cc b/third_party/blink/renderer/modules/xr/xr_layer.cc
index eaa8603c7354a5c8e71e9a2e6161824063804fb6..aa30a4cec88fa11b342695dc675ab572320e9166 100644
--- a/third_party/blink/renderer/modules/xr/xr_layer.cc
+++ b/third_party/blink/renderer/modules/xr/xr_layer.cc
@@ -21,7 +21,7 @@ const AtomicString& XRLayer::InterfaceName() const {
void XRLayer::Trace(Visitor* visitor) const {
visitor->Trace(session_);
- ScriptWrappable::Trace(visitor);
+ EventTargetWithInlineData::Trace(visitor);
}
} // namespace blink

View File

@@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peng Huang <penghuang@chromium.org>
Date: Wed, 7 Jul 2021 20:50:53 +0000
Subject: Fix UAF problem in SharedImageInterfaceInProcess
(cherry picked from commit 38b4905f8d877b27bc2d4ccd4cfc0f82b636deea)
Bug: 1216822
Change-Id: I8ae1f7c406e1899e500ee7ddeaaf18230b1cbcb2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2971144
Commit-Queue: Peng Huang <penghuang@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Auto-Submit: Peng Huang <penghuang@chromium.org>
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#893931}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3011895
Auto-Submit: Mason Freed <masonf@chromium.org>
Reviewed-by: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/branch-heads/4515@{#1369}
Cr-Branched-From: 488fc70865ddaa05324ac00a54a6eb783b4bc41c-refs/heads/master@{#885287}
diff --git a/gpu/ipc/shared_image_interface_in_process.cc b/gpu/ipc/shared_image_interface_in_process.cc
index 54f9777201827e4bca5221af373e39dc021ac6a4..53c2dc489c50367986c46a34e8aaf48b68888ec7 100644
--- a/gpu/ipc/shared_image_interface_in_process.cc
+++ b/gpu/ipc/shared_image_interface_in_process.cc
@@ -86,6 +86,8 @@ void SharedImageInterfaceInProcess::DestroyOnGpu(
sync_point_client_state_->Destroy();
sync_point_client_state_ = nullptr;
}
+
+ context_state_ = nullptr;
completion->Signal();
}
diff --git a/gpu/ipc/shared_image_interface_in_process.h b/gpu/ipc/shared_image_interface_in_process.h
index 8d74513f041564a416c20cab5616c9453555c547..c169b5a86af3e02ec869aae9cf1bfb150fa2ad69 100644
--- a/gpu/ipc/shared_image_interface_in_process.h
+++ b/gpu/ipc/shared_image_interface_in_process.h
@@ -229,10 +229,7 @@ class GL_IN_PROCESS_CONTEXT_EXPORT SharedImageInterfaceInProcess
// Accessed on GPU thread.
// TODO(weiliangc): Check whether can be removed when !UsesSync().
MailboxManager* mailbox_manager_;
- // Used to check if context is lost at destruction time.
- // TODO(weiliangc): SharedImageInterface should become active observer of
- // whether context is lost.
- SharedContextState* context_state_;
+ scoped_refptr<SharedContextState> context_state_;
// Created and only used by this SharedImageInterface.
SyncPointManager* sync_point_manager_;
scoped_refptr<SyncPointClientState> sync_point_client_state_;

View File

@@ -0,0 +1,197 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ted Meyer <tmathmeyer@chromium.org>
Date: Mon, 7 Jun 2021 20:41:16 +0000
Subject: A few fixes to the D3D11H264Accelerator
- Adds a AsD3D11H264Picture method to H264Pictures because sometimes
there can be just normal H264Pictures in the DPB and this could cause
some invalid variable access as we were statically casting the
pointer before.
- Adds a bounds check just in case there are more than 16 items in the
DPB.
(cherry picked from commit 5a3cf91d0f2352e697017e13f4754989f46f2f3e)
Bug: 1194689
Change-Id: Ief2e1d00b451fbc0585dd0b22b5aff7a6918fa11
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2923118
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Reviewed-by: Frank Liberato <liberato@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#888267}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2944579
Auto-Submit: Ted Meyer <tmathmeyer@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4472@{#1455}
Cr-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
diff --git a/media/gpu/h264_dpb.cc b/media/gpu/h264_dpb.cc
index 8ef3bafb255349c6ac602c02a30615f0dd0b7d06..859e184b129f21f6af41b276051ca3a3adc03a7f 100644
--- a/media/gpu/h264_dpb.cc
+++ b/media/gpu/h264_dpb.cc
@@ -55,6 +55,10 @@ VaapiH264Picture* H264Picture::AsVaapiH264Picture() {
return nullptr;
}
+D3D11H264Picture* H264Picture::AsD3D11H264Picture() {
+ return nullptr;
+}
+
H264DPB::H264DPB() : max_num_pics_(0) {}
H264DPB::~H264DPB() = default;
diff --git a/media/gpu/h264_dpb.h b/media/gpu/h264_dpb.h
index 1395f9ecb35302632c49392d11fecb91436cbdf6..36abd4a8984dcb01ce85fc5fffa5ec916ecbf46a 100644
--- a/media/gpu/h264_dpb.h
+++ b/media/gpu/h264_dpb.h
@@ -23,6 +23,7 @@ namespace media {
class V4L2H264Picture;
class VaapiH264Picture;
+class D3D11H264Picture;
// A picture (a frame or a field) in the H.264 spec sense.
// See spec at http://www.itu.int/rec/T-REC-H.264
@@ -40,6 +41,7 @@ class MEDIA_GPU_EXPORT H264Picture : public CodecPicture {
virtual V4L2H264Picture* AsV4L2H264Picture();
virtual VaapiH264Picture* AsVaapiH264Picture();
+ virtual D3D11H264Picture* AsD3D11H264Picture();
// Values calculated per H.264 specification or taken from slice header.
// See spec for more details on each (some names have been converted from
diff --git a/media/gpu/windows/d3d11_h264_accelerator.cc b/media/gpu/windows/d3d11_h264_accelerator.cc
index e87c1ece44f4c2af44e1c626ae69bfede43a0289..82abc9af5ed4255d5e262d539b4462e6e089fc61 100644
--- a/media/gpu/windows/d3d11_h264_accelerator.cc
+++ b/media/gpu/windows/d3d11_h264_accelerator.cc
@@ -52,6 +52,8 @@ class D3D11H264Picture : public H264Picture {
D3D11PictureBuffer* picture;
size_t picture_index_;
+ D3D11H264Picture* AsD3D11H264Picture() override { return this; }
+
protected:
~D3D11H264Picture() override;
};
@@ -101,10 +103,12 @@ DecoderStatus D3D11H264Accelerator::SubmitFrameMetadata(
HRESULT hr;
for (;;) {
+ D3D11H264Picture* d3d11_pic = pic->AsD3D11H264Picture();
+ if (!d3d11_pic)
+ return DecoderStatus::kFail;
hr = video_context_->DecoderBeginFrame(
- video_decoder_.Get(),
- static_cast<D3D11H264Picture*>(pic.get())->picture->output_view().Get(),
- 0, nullptr);
+ video_decoder_.Get(), d3d11_pic->picture->output_view().Get(), 0,
+ nullptr);
if (hr == E_PENDING || hr == D3DERR_WASSTILLDRAWING) {
// Hardware is busy. We should make the call again.
@@ -119,7 +123,7 @@ DecoderStatus D3D11H264Accelerator::SubmitFrameMetadata(
}
sps_ = *sps;
- for (size_t i = 0; i < 16; i++) {
+ for (size_t i = 0; i < media::kRefFrameMaxCount; i++) {
ref_frame_list_[i].bPicEntry = 0xFF;
field_order_cnt_list_[i][0] = 0;
field_order_cnt_list_[i][1] = 0;
@@ -132,8 +136,19 @@ DecoderStatus D3D11H264Accelerator::SubmitFrameMetadata(
int i = 0;
for (auto it = dpb.begin(); it != dpb.end(); i++, it++) {
- D3D11H264Picture* our_ref_pic = static_cast<D3D11H264Picture*>(it->get());
- if (!our_ref_pic->ref)
+ // The DPB is supposed to have a maximum of 16 pictures in it, but there's
+ // nothing actually stopping it from having more. If we run into this case,
+ // something is clearly wrong, and we should just fail decoding rather than
+ // try to sort out which pictures really shouldn't be included.
+ if (i >= media::kRefFrameMaxCount)
+ return DecoderStatus::kFail;
+
+ D3D11H264Picture* our_ref_pic = it->get()->AsD3D11H264Picture();
+ // How does a non-d3d11 picture get here you might ask? The decoder
+ // inserts blank H264Picture objects that we can't use as part of filling
+ // gaps in frame numbers. If we see one, it's not a reference picture
+ // anyway, so skip it.
+ if (!our_ref_pic || !our_ref_pic->ref)
continue;
ref_frame_list_[i].Index7Bits = our_ref_pic->picture_index_;
ref_frame_list_[i].AssociatedFlag = our_ref_pic->long_term;
@@ -279,9 +294,8 @@ void D3D11H264Accelerator::PicParamsFromSliceHeader(
}
void D3D11H264Accelerator::PicParamsFromPic(DXVA_PicParams_H264* pic_param,
- scoped_refptr<H264Picture> pic) {
- pic_param->CurrPic.Index7Bits =
- static_cast<D3D11H264Picture*>(pic.get())->picture_index_;
+ D3D11H264Picture* pic) {
+ pic_param->CurrPic.Index7Bits = pic->picture_index_;
pic_param->RefPicFlag = pic->ref;
pic_param->frame_num = pic->frame_num;
@@ -314,7 +328,11 @@ DecoderStatus D3D11H264Accelerator::SubmitSlice(
if (!PicParamsFromPPS(&pic_param, pps))
return DecoderStatus::kFail;
PicParamsFromSliceHeader(&pic_param, slice_hdr);
- PicParamsFromPic(&pic_param, std::move(pic));
+
+ D3D11H264Picture* d3d11_pic = pic->AsD3D11H264Picture();
+ if (!d3d11_pic)
+ return DecoderStatus::kFail;
+ PicParamsFromPic(&pic_param, d3d11_pic);
memcpy(pic_param.RefFrameList, ref_frame_list_,
sizeof pic_param.RefFrameList);
@@ -573,9 +591,8 @@ void D3D11H264Accelerator::Reset() {
}
bool D3D11H264Accelerator::OutputPicture(scoped_refptr<H264Picture> pic) {
- D3D11H264Picture* our_pic = static_cast<D3D11H264Picture*>(pic.get());
-
- return client_->OutputResult(our_pic, our_pic->picture);
+ D3D11H264Picture* our_pic = pic->AsD3D11H264Picture();
+ return our_pic && client_->OutputResult(our_pic, our_pic->picture);
}
void D3D11H264Accelerator::RecordFailure(const std::string& reason,
diff --git a/media/gpu/windows/d3d11_h264_accelerator.h b/media/gpu/windows/d3d11_h264_accelerator.h
index 00e2bd5cecd34f947c15aed1a7f5873b2ba4736c..c927706fb58b0637b6cf27516495028ead95325c 100644
--- a/media/gpu/windows/d3d11_h264_accelerator.h
+++ b/media/gpu/windows/d3d11_h264_accelerator.h
@@ -27,6 +27,8 @@
namespace media {
+constexpr int kRefFrameMaxCount = 16;
+
class D3D11H264Accelerator;
class MediaLog;
@@ -74,8 +76,7 @@ class D3D11H264Accelerator : public H264Decoder::H264Accelerator {
void PicParamsFromSliceHeader(DXVA_PicParams_H264* pic_param,
const H264SliceHeader* pps);
- void PicParamsFromPic(DXVA_PicParams_H264* pic_param,
- scoped_refptr<H264Picture> pic);
+ void PicParamsFromPic(DXVA_PicParams_H264* pic_param, D3D11H264Picture* pic);
void SetVideoDecoder(ComD3D11VideoDecoder video_decoder);
@@ -95,10 +96,10 @@ class D3D11H264Accelerator : public H264Decoder::H264Accelerator {
// This information set at the beginning of a frame and saved for processing
// all the slices.
- DXVA_PicEntry_H264 ref_frame_list_[16];
+ DXVA_PicEntry_H264 ref_frame_list_[kRefFrameMaxCount];
H264SPS sps_;
- INT field_order_cnt_list_[16][2];
- USHORT frame_num_list_[16];
+ INT field_order_cnt_list_[kRefFrameMaxCount][2];
+ USHORT frame_num_list_[kRefFrameMaxCount];
UINT used_for_reference_flags_;
USHORT non_existing_frame_flags_;

View File

@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tal Pressman <talp@chromium.org>
Date: Wed, 21 Jul 2021 09:11:13 +0000
Subject: Manually post task to bind FileUtilitiesHost.
The FileUtilitiesHost binder is posted to a separate sequence, and the
ServiceWorkerHost may be destroyed by the time the it runs, causing a
UAF.
This CL changes it so that, when we try to bind a new receiver, the
host's worker_process_id() is obtained first (on the service worker's
core thread) and then a task is posted to do the actual binding on a
USER_VISIBLE task runner.
Credit: This issue was first reported (with analysis) by
soulchen8650@gmail.com.
Bug: 1229298
Change-Id: I6d5c05a830ba30f6cb98bf2df70a3df3333f3dd9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3041006
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Commit-Queue: Tal Pressman <talp@google.com>
Cr-Commit-Position: refs/heads/master@{#903832}
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index a45f9d3db09dbc4827c41c254b2b532968930e96..b6f69c1813fc9c66cc6a20205c02cb6e5d810fc5 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -367,10 +367,22 @@ void BindTextSuggestionHostForFrame(
}
#endif
+// Get the service worker's worker process ID and post a task to bind the
+// receiver on a USER_VISIBLE task runner.
+// This is necessary because:
+// - Binding the host itself and checking the ID on the task's thread may cause
+// a UAF if the host has been deleted in the meantime.
+// - The process ID is not yet populated at the time `PopulateInterfaceBinders`
+// is called.
void BindFileUtilitiesHost(
- const ServiceWorkerHost* host,
+ ServiceWorkerHost* host,
mojo::PendingReceiver<blink::mojom::FileUtilitiesHost> receiver) {
- FileUtilitiesHostImpl::Create(host->worker_process_id(), std::move(receiver));
+ auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&FileUtilitiesHostImpl::Create, host->worker_process_id(),
+ std::move(receiver)));
}
template <typename WorkerHost, typename Interface>
@@ -1122,9 +1134,7 @@ void PopulateServiceWorkerBinders(ServiceWorkerHost* host,
// static binders
map->Add<blink::mojom::FileUtilitiesHost>(
- base::BindRepeating(&BindFileUtilitiesHost, host),
- base::ThreadPool::CreateSequencedTaskRunner(
- {base::MayBlock(), base::TaskPriority::USER_VISIBLE}));
+ base::BindRepeating(&BindFileUtilitiesHost, host));
map->Add<shape_detection::mojom::BarcodeDetectionProvider>(
base::BindRepeating(&BindBarcodeDetectionProvider));
map->Add<shape_detection::mojom::FaceDetectionProvider>(

View File

@@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shrek Shao <shrekshao@google.com>
Date: Tue, 29 Jun 2021 01:17:03 +0000
Subject: Fix multidraw validation drawcount + offset out of bounds
(cherry picked from commit 7d0a12ce19fed024d56b95a692d888fe3ef14e2f)
Bug: 1219886
Change-Id: I8a84664150758370d9a77ee22ac5549bead0e37e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2977850
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#895423}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2988885
Reviewed-by: Shrek Shao <shrekshao@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Cr-Commit-Position: refs/branch-heads/4515@{#1101}
Cr-Branched-From: 488fc70865ddaa05324ac00a54a6eb783b4bc41c-refs/heads/master@{#885287}
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc
index 91de853db2b382a7797d22cf741a84f463a2d5f2..c3cae01c63046ce4b8be2c0b03243e9105ed4f23 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc
@@ -34,6 +34,11 @@ bool WebGLMultiDrawCommon::ValidateArray(WebGLExtensionScopedContext* scoped,
outOfBoundsDescription);
return false;
}
+ if (static_cast<uint64_t>(drawcount) + offset > size) {
+ scoped->Context()->SynthesizeGLError(GL_INVALID_OPERATION, function_name,
+ "drawcount plus offset out of bounds");
+ return false;
+ }
return true;
}

View File

@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Toy <rtoy@chromium.org>
Date: Wed, 9 Jun 2021 16:46:08 +0000
Subject: Add AudioHandler to orphan handlers when context is suspended.
If the context is suspended, pulling of the audio graph is stopped.
But we still need to add the handler in this case so that when the
context is resumed, the handler is still alive until it can be safely
removed. Hence, we must still add the handler if the context is
suspended.
Test cases from issue 1176218 manually tested with no failures. Also
this doesn't cause any regressions in issue 1003807 and issue 1017961.
(Manually tested the test cases from those issues.)
(cherry picked from commit 4a38ea3f1f78e0a0ffc1464e227cee6c1f2fd90b)
Bug: 1176218
Change-Id: Icd927c488505dfee9ff716866f98286e286d546a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2874771
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#881533}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2944893
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Owners-Override: Artem Sumaneev <asumaneev@google.com>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4430@{#1508}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node.cc b/third_party/blink/renderer/modules/webaudio/audio_node.cc
index 80a044235e4ff552eb696e8627f74927f622aae0..c036d175f403f239fb67c185f3cef84aabac92f7 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_node.cc
@@ -614,13 +614,13 @@ void AudioNode::Dispose() {
BaseAudioContext::GraphAutoLocker locker(context());
Handler().Dispose();
- // Add the handler to the orphan list if the context is pulling on the audio
- // graph. This keeps the handler alive until it can be deleted at a safe
- // point (in pre/post handler task). If graph isn't being pulled, we can
- // delete the handler now since nothing on the audio thread will be touching
- // it.
+ // Add the handler to the orphan list. This keeps the handler alive until it
+ // can be deleted at a safe point (in pre/post handler task). If the graph is
+ // being processed, the handler must be added. If the context is suspended,
+ // the handler still needs to be added in case the context is resumed.
DCHECK(context());
- if (context()->IsPullingAudioGraph()) {
+ if (context()->IsPullingAudioGraph() ||
+ context()->ContextState() == BaseAudioContext::kSuspended) {
context()->GetDeferredTaskHandler().AddRenderingOrphanHandler(
std::move(handler_));
}

View File

@@ -0,0 +1,99 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yutaka Hirano <yhirano@chromium.org>
Date: Fri, 11 Jun 2021 08:05:05 +0000
Subject: Remove container mutation during iteration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On LongTaskDetector, we call OnLongTaskDetected for all registered
observers. Some observers call LongTaskDetector::UnregisterObserver
in the callback, which is problematic because container mutation is
not allowed during iteration.
Copy the observer set to avoid the violation.
(cherry picked from commit 702f4d4ddb963cafb0d133972282dfc803510b75)
(cherry picked from commit e88c656a9fb4a7bb1c66ddcedae8049a448ebef4)
Bug: 1210487
Change-Id: Iccea748ac144def6884be8cf542cdc3572bed81a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2909934
Reviewed-by: Deep Roy <dproy@chromium.org>
Reviewed-by: Nicolás Peña Moreno <npm@chromium.org>
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#885033}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2939704
Auto-Submit: Yutaka Hirano <yhirano@chromium.org>
Owners-Override: Prudhvi Kumar Bommana <pbommana@google.com>
Reviewed-by: Prudhvi Kumar Bommana <pbommana@google.com>
Cr-Original-Commit-Position: refs/branch-heads/4472@{#1443}
Cr-Original-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2945126
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4430@{#1518}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/third_party/blink/renderer/core/loader/long_task_detector.cc b/third_party/blink/renderer/core/loader/long_task_detector.cc
index 7e1499b1ddde30db2344db6fd9a9d3e7be574033..f040ae5053265fb136c629f106aeefa0b01130f1 100644
--- a/third_party/blink/renderer/core/loader/long_task_detector.cc
+++ b/third_party/blink/renderer/core/loader/long_task_detector.cc
@@ -43,7 +43,10 @@ void LongTaskDetector::DidProcessTask(base::TimeTicks start_time,
if ((end_time - start_time) < LongTaskDetector::kLongTaskThreshold)
return;
- for (auto& observer : observers_) {
+ // We copy `observers_` because it might be mutated in OnLongTaskDetected,
+ // and container mutation is not allowed during iteration.
+ const HeapHashSet<Member<LongTaskObserver>> observers = observers_;
+ for (auto& observer : observers) {
observer->OnLongTaskDetected(start_time, end_time);
}
}
diff --git a/third_party/blink/renderer/core/loader/long_task_detector_test.cc b/third_party/blink/renderer/core/loader/long_task_detector_test.cc
index 3384fa8ebfb0bd3ad1c408390db3fcb26edc4118..04959d3b682ddbf40577adc5799fe57a9ae9d500 100644
--- a/third_party/blink/renderer/core/loader/long_task_detector_test.cc
+++ b/third_party/blink/renderer/core/loader/long_task_detector_test.cc
@@ -27,9 +27,24 @@ class TestLongTaskObserver :
last_long_task_start = start_time;
last_long_task_end = end_time;
}
-}; // Anonymous namespace
+};
+
+class SelfUnregisteringObserver
+ : public GarbageCollected<SelfUnregisteringObserver>,
+ public LongTaskObserver {
+ public:
+ void OnLongTaskDetected(base::TimeTicks, base::TimeTicks) override {
+ called_ = true;
+ LongTaskDetector::Instance().UnregisterObserver(this);
+ }
+ bool IsCalled() const { return called_; }
+
+ private:
+ bool called_ = false;
+};
} // namespace
+
class LongTaskDetectorTest : public testing::Test {
public:
// Public because it's executed on a task queue.
@@ -126,4 +141,13 @@ TEST_F(LongTaskDetectorTest, RegisterSameObserverTwice) {
long_task_end_when_registered);
}
+TEST_F(LongTaskDetectorTest, SelfUnregisteringObserver) {
+ auto* observer = MakeGarbageCollected<SelfUnregisteringObserver>();
+
+ LongTaskDetector::Instance().RegisterObserver(observer);
+ SimulateTask(LongTaskDetector::kLongTaskThreshold +
+ base::TimeDelta::FromMilliseconds(10));
+ EXPECT_TRUE(observer->IsCalled());
+}
+
} // namespace blink

View File

@@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yutaka Hirano <yhirano@chromium.org>
Date: Fri, 11 Jun 2021 08:42:15 +0000
Subject: Reduce memory consumption on LongTaskObserver::DidProcessTask
https://crrev.com/c/2909934 fixed a security issue, but it introduced a
copy operation for each DidProcessTask for a long task. We see a memory
regression on the change, and this is an attempt to mitigate the
regression.
(cherry picked from commit 8097e73295a88e64d8318d982847a5e4f2bcc4d2)
(cherry picked from commit 7be6a34fe2f01af881bb074bc616bf5b6b5f7c31)
Bug: 1210487, 1211539
Change-Id: Ib9101e29d70fadb11b7967754e847bb5cc754feb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2915153
Reviewed-by: Benoit L <lizeb@chromium.org>
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#886221}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2944320
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Original-Commit-Position: refs/branch-heads/4472@{#1460}
Cr-Original-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2948750
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4430@{#1520}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/third_party/blink/renderer/core/loader/long_task_detector.cc b/third_party/blink/renderer/core/loader/long_task_detector.cc
index f040ae5053265fb136c629f106aeefa0b01130f1..3816779cfafaef06295734b4a8a2f033bf752691 100644
--- a/third_party/blink/renderer/core/loader/long_task_detector.cc
+++ b/third_party/blink/renderer/core/loader/long_task_detector.cc
@@ -24,6 +24,7 @@ LongTaskDetector::LongTaskDetector() = default;
void LongTaskDetector::RegisterObserver(LongTaskObserver* observer) {
DCHECK(IsMainThread());
DCHECK(observer);
+ DCHECK(!iterating_);
if (observers_.insert(observer).is_new_entry && observers_.size() == 1) {
// Number of observers just became non-zero.
Thread::Current()->AddTaskTimeObserver(this);
@@ -32,6 +33,10 @@ void LongTaskDetector::RegisterObserver(LongTaskObserver* observer) {
void LongTaskDetector::UnregisterObserver(LongTaskObserver* observer) {
DCHECK(IsMainThread());
+ if (iterating_) {
+ observers_to_be_removed_.push_back(observer);
+ return;
+ }
observers_.erase(observer);
if (observers_.size() == 0) {
Thread::Current()->RemoveTaskTimeObserver(this);
@@ -43,16 +48,21 @@ void LongTaskDetector::DidProcessTask(base::TimeTicks start_time,
if ((end_time - start_time) < LongTaskDetector::kLongTaskThreshold)
return;
- // We copy `observers_` because it might be mutated in OnLongTaskDetected,
- // and container mutation is not allowed during iteration.
- const HeapHashSet<Member<LongTaskObserver>> observers = observers_;
- for (auto& observer : observers) {
+ iterating_ = true;
+ for (auto& observer : observers_) {
observer->OnLongTaskDetected(start_time, end_time);
}
+ iterating_ = false;
+
+ for (const auto& observer : observers_to_be_removed_) {
+ UnregisterObserver(observer);
+ }
+ observers_to_be_removed_.clear();
}
void LongTaskDetector::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
+ visitor->Trace(observers_to_be_removed_);
}
} // namespace blink
diff --git a/third_party/blink/renderer/core/loader/long_task_detector.h b/third_party/blink/renderer/core/loader/long_task_detector.h
index dc6f0dbab5c059b83bfe4212f0126e9690ab1a7f..5fd4bb8d2abcc67dd4e47927daa260fa37bc4aca 100644
--- a/third_party/blink/renderer/core/loader/long_task_detector.h
+++ b/third_party/blink/renderer/core/loader/long_task_detector.h
@@ -49,6 +49,8 @@ class CORE_EXPORT LongTaskDetector final
base::TimeTicks end_time) override;
HeapHashSet<Member<LongTaskObserver>> observers_;
+ HeapVector<Member<LongTaskObserver>> observers_to_be_removed_;
+ bool iterating_ = false;
DISALLOW_COPY_AND_ASSIGN(LongTaskDetector);
};
diff --git a/third_party/blink/renderer/core/loader/long_task_detector_test.cc b/third_party/blink/renderer/core/loader/long_task_detector_test.cc
index 04959d3b682ddbf40577adc5799fe57a9ae9d500..403ba452362a3fa2a6b24f238bad35d9eb1bac0c 100644
--- a/third_party/blink/renderer/core/loader/long_task_detector_test.cc
+++ b/third_party/blink/renderer/core/loader/long_task_detector_test.cc
@@ -39,6 +39,8 @@ class SelfUnregisteringObserver
}
bool IsCalled() const { return called_; }
+ void Reset() { called_ = false; }
+
private:
bool called_ = false;
};
@@ -148,6 +150,11 @@ TEST_F(LongTaskDetectorTest, SelfUnregisteringObserver) {
SimulateTask(LongTaskDetector::kLongTaskThreshold +
base::TimeDelta::FromMilliseconds(10));
EXPECT_TRUE(observer->IsCalled());
+ observer->Reset();
+
+ SimulateTask(LongTaskDetector::kLongTaskThreshold +
+ base::TimeDelta::FromMilliseconds(10));
+ EXPECT_FALSE(observer->IsCalled());
}
} // namespace blink

View File

@@ -0,0 +1,574 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dominic Battre <battre@chromium.org>
Date: Wed, 7 Jul 2021 20:02:45 +0000
Subject: Replace first of two WaitableEvents in CreditCardAccessManager
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry picked from commit 48cf01e4039fecbe119d8223d1f6072aaf44f258)
Bug: 1214234
Change-Id: I38171be7b38982f25abfbb3dff7a41f19a167764
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3001123
Reviewed-by: Jared Saul <jsaul@google.com>
Commit-Queue: Dominic Battré <battre@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#898237}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3011066
Reviewed-by: Dominic Battré <battre@chromium.org>
Reviewed-by: Prudhvi Kumar Bommana <pbommana@google.com>
Owners-Override: Prudhvi Kumar Bommana <pbommana@google.com>
Cr-Commit-Position: refs/branch-heads/4515@{#1366}
Cr-Branched-From: 488fc70865ddaa05324ac00a54a6eb783b4bc41c-refs/heads/master@{#885287}
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 5031372d31e25f8f14905ab1be721c4aaefed7c5..d6254700a20445078cc4c4fa0e821cd2fc3b1a7b 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -237,6 +237,8 @@ static_library("browser") {
"payments/payments_util.cc",
"payments/payments_util.h",
"payments/risk_data_loader.h",
+ "payments/wait_for_signal_or_timeout.cc",
+ "payments/wait_for_signal_or_timeout.h",
"payments/strike_database.cc",
"payments/strike_database.h",
"payments/strike_database_integrator_base.cc",
@@ -680,6 +682,7 @@ source_set("unit_tests") {
"payments/payments_client_unittest.cc",
"payments/payments_service_url_unittest.cc",
"payments/payments_util_unittest.cc",
+ "payments/wait_for_signal_or_timeout_unittest.cc",
"payments/strike_database_integrator_test_strike_database_unittest.cc",
"payments/strike_database_unittest.cc",
"personal_data_manager_unittest.cc",
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.cc b/components/autofill/core/browser/payments/credit_card_access_manager.cc
index 560f30b57c88049842390095ca53eb2e4302bf63..7cab68d4cc6696329dd4739f51e809aa7877cb53 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager.cc
@@ -18,7 +18,6 @@
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
-#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_client.h"
@@ -46,12 +45,6 @@ constexpr int64_t kUnmaskDetailsResponseTimeoutMs = 3 * 1000; // 3 sec
// Time to wait between multiple calls to GetUnmaskDetails().
constexpr int64_t kDelayForGetUnmaskDetails = 3 * 60 * 1000; // 3 min
-// Used for asynchronously waiting for |event| to be signaled.
-bool WaitForEvent(base::WaitableEvent* event) {
- event->declare_only_used_while_idle();
- return event->TimedWait(
- base::TimeDelta::FromMilliseconds(kUnmaskDetailsResponseTimeoutMs));
-}
} // namespace
CreditCardAccessManager::CreditCardAccessManager(
@@ -64,9 +57,6 @@ CreditCardAccessManager::CreditCardAccessManager(
payments_client_(client_->GetPaymentsClient()),
personal_data_manager_(personal_data_manager),
form_event_logger_(form_event_logger),
- ready_to_start_authentication_(
- base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
can_fetch_unmask_details_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::SIGNALED) {
}
@@ -329,12 +319,10 @@ void CreditCardAccessManager::FetchCreditCard(
// Wait for |ready_to_start_authentication_| to be signaled by
// OnDidGetUnmaskDetails() or until timeout before calling Authenticate().
- auto task_runner = base::ThreadPool::CreateTaskRunner({base::MayBlock()});
- cancelable_authenticate_task_tracker_.PostTaskAndReplyWithResult(
- task_runner.get(), FROM_HERE,
- base::BindOnce(&WaitForEvent, &ready_to_start_authentication_),
+ ready_to_start_authentication_.OnEventOrTimeOut(
base::BindOnce(&CreditCardAccessManager::Authenticate,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_ptr_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kUnmaskDetailsResponseTimeoutMs));
} else {
Authenticate(get_unmask_details_returned);
}
@@ -699,7 +687,6 @@ void CreditCardAccessManager::HandleDialogUserResponse(
case WebauthnDialogCallbackType::kVerificationCancelled:
// TODO(crbug.com/949269): Add tests and logging for canceling verify
// pending dialog.
- cancelable_authenticate_task_tracker_.TryCancelAll();
payments_client_->CancelRequest();
SignalCanFetchUnmaskDetails();
ready_to_start_authentication_.Reset();
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.h b/components/autofill/core/browser/payments/credit_card_access_manager.h
index 6bdf8b8c647f885aad5784f737e117b3a55bd2be..99f6581b7320312776f52383b8e8e3b7845268a8 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager.h
+++ b/components/autofill/core/browser/payments/credit_card_access_manager.h
@@ -22,6 +22,7 @@
#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
#include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h"
#include "components/autofill/core/browser/payments/payments_client.h"
+#include "components/autofill/core/browser/payments/wait_for_signal_or_timeout.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#if !defined(OS_IOS)
@@ -295,11 +296,7 @@ class CreditCardAccessManager : public CreditCardCVCAuthenticator::Requester,
// Resets when PrepareToFetchCreditCard() is called, if not already reset.
// Signaled when OnDidGetUnmaskDetails() is called or after timeout.
// Authenticate() is called when signaled.
- base::WaitableEvent ready_to_start_authentication_;
-
- // Tracks the Authenticate() task that is signaled by
- // |ready_to_start_authentication_|, allowing it to be canceled if necessary.
- base::CancelableTaskTracker cancelable_authenticate_task_tracker_;
+ WaitForSignalOrTimeout ready_to_start_authentication_;
// Required to avoid any unnecessary preflight calls to Payments servers.
// Initial state is signaled. Resets when PrepareToFetchCreditCard() is
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
index faa396e337d60167d759f9a616f4a901ac5b9db6..39507d6f45e318d632d73583ebaf9048120ae15a 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -139,8 +139,23 @@ class CreditCardAccessManagerTest : public testing::Test {
public:
CreditCardAccessManagerTest()
: task_environment_(
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME,
base::test::TaskEnvironment::MainThreadType::DEFAULT,
- base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED) {}
+ base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED) {
+ // Advance the mock clock to 2021-01-01, 00:00:00.000.
+ base::Time year_2021;
+ CHECK(base::Time::FromUTCExploded({.year = 2021,
+ .month = 1,
+ .day_of_week = 4,
+ .day_of_month = 1,
+ .hour = 0,
+ .minute = 0,
+ .second = 0,
+ .millisecond = 0},
+ &year_2021));
+ task_environment_.AdvanceClock(year_2021 -
+ task_environment_.GetMockClock()->Now());
+ }
void SetUp() override {
autofill_client_.SetPrefs(test::PrefServiceForTesting());
@@ -930,6 +945,7 @@ TEST_F(CreditCardAccessManagerTest,
ResetFetchCreditCard();
credit_card_access_manager_->PrepareToFetchCreditCard();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(4));
WaitForCallbacks();
credit_card_access_manager_->FetchCreditCard(local_card,
@@ -950,6 +966,7 @@ TEST_F(CreditCardAccessManagerTest,
credit_card_access_manager_->PrepareToFetchCreditCard();
credit_card_access_manager_->FetchCreditCard(server_card,
accessor_->GetWeakPtr());
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(4));
WaitForCallbacks();
histogram_tester.ExpectUniqueSample(
@@ -1023,6 +1040,8 @@ TEST_F(CreditCardAccessManagerTest, Metrics_LoggingTimedOutCvcFallback) {
// Mock a delayed response.
InvokeDelayedGetUnmaskDetailsResponse();
+
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(4));
WaitForCallbacks();
histogram_tester.ExpectUniqueSample(
@@ -1044,6 +1063,7 @@ TEST_F(CreditCardAccessManagerTest, Metrics_LoggingTimedOutCvcFallback) {
credit_card_access_manager_->PrepareToFetchCreditCard();
credit_card_access_manager_->FetchCreditCard(server_card,
accessor_->GetWeakPtr());
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(4));
WaitForCallbacks();
histogram_tester.ExpectUniqueSample(
diff --git a/components/autofill/core/browser/payments/wait_for_signal_or_timeout.cc b/components/autofill/core/browser/payments/wait_for_signal_or_timeout.cc
new file mode 100644
index 0000000000000000000000000000000000000000..713a53e0f006e51f5d9bd64466712bf75b3ba095
--- /dev/null
+++ b/components/autofill/core/browser/payments/wait_for_signal_or_timeout.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "components/autofill/core/browser/payments/wait_for_signal_or_timeout.h"
+
+#include "base/threading/sequenced_task_runner_handle.h"
+
+WaitForSignalOrTimeout::WaitForSignalOrTimeout() = default;
+WaitForSignalOrTimeout::~WaitForSignalOrTimeout() = default;
+
+void WaitForSignalOrTimeout::Signal() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+ SignalHandler(/*triggered_by_signal=*/true);
+}
+
+bool WaitForSignalOrTimeout::IsSignaled() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+ return state_ == State::kSignalReceived || state_ == State::kDone;
+}
+
+void WaitForSignalOrTimeout::OnEventOrTimeOut(Callback callback,
+ base::TimeDelta timeout) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+ switch (state_) {
+ case State::kInitialState:
+ callback_ = std::move(callback);
+ ++generation_id_; // Invalidate previous OnTimeOut tasks.
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&WaitForSignalOrTimeout::OnTimeOut,
+ weak_factory_.GetWeakPtr(), generation_id_),
+ timeout);
+ break;
+
+ case State::kSignalReceived:
+ state_ = State::kDone;
+ std::move(callback).Run(
+ /*triggered_by_signal=*/in_state_signal_received_due_to_signal_call_);
+ break;
+
+ case State::kDone:
+ Reset();
+ OnEventOrTimeOut(std::move(callback), timeout);
+ break;
+ }
+}
+
+void WaitForSignalOrTimeout::Reset() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+ state_ = State::kInitialState;
+ ++generation_id_;
+ callback_ = Callback();
+}
+
+void WaitForSignalOrTimeout::OnTimeOut(int generation_id) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+ if (generation_id == generation_id_)
+ SignalHandler(/*triggered_by_signal=*/false);
+}
+
+void WaitForSignalOrTimeout::SignalHandler(bool triggered_by_signal) {
+ switch (state_) {
+ case State::kInitialState:
+ if (callback_.is_null()) {
+ state_ = State::kSignalReceived;
+ in_state_signal_received_due_to_signal_call_ = triggered_by_signal;
+ } else {
+ state_ = State::kDone;
+ std::move(callback_).Run(triggered_by_signal);
+ }
+ break;
+
+ case State::kSignalReceived:
+ case State::kDone:
+ break;
+ }
+}
diff --git a/components/autofill/core/browser/payments/wait_for_signal_or_timeout.h b/components/autofill/core/browser/payments/wait_for_signal_or_timeout.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b2c451245441f784938e4132e2ab03e7d85f9b6
--- /dev/null
+++ b/components/autofill/core/browser/payments/wait_for_signal_or_timeout.h
@@ -0,0 +1,100 @@
+// 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.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_WAIT_FOR_SIGNAL_OR_TIMEOUT_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_WAIT_FOR_SIGNAL_OR_TIMEOUT_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "base/time/time.h"
+
+// A WaitForSignalOrTimeout waits for Signal() or a time out and calls a
+// callback when either of these happens for the first time.
+//
+// The WaitForSignalOrTimeout is Reset()-able and ensures that the callback will
+// be called at most once (unless Reset() resets the state). The
+// WaitForSignalOrTimeout can be destroyed at any time without negative
+// side-effects. The callback won't be called in this case. If the Signal()
+// arrives before a call for OnEventOrTimeOut(), the callback will be called
+// immediately. If a second Signal() arrives, nothing happens. The
+// WaitForSignalOrTimeout must be used on single task sequence.
+//
+// This class provides the bare minimum needed for a Payment task. If there are
+// more use cases, feel free to spice it up and move it to base/.
+class WaitForSignalOrTimeout {
+ public:
+ // The passed boolean is true if the callback happened by a call of Signal()
+ // (as opposed to a timeout).
+ using Callback = base::OnceCallback<void(bool)>;
+
+ WaitForSignalOrTimeout();
+ ~WaitForSignalOrTimeout();
+ WaitForSignalOrTimeout(const WaitForSignalOrTimeout&) = delete;
+ WaitForSignalOrTimeout& operator=(const WaitForSignalOrTimeout&) = delete;
+
+ // Triggers |callback_| if it has not been called before, or registers that
+ // the signal occurred, so that |callback| of OnEventOrTimeOut() can be
+ // called immediately.
+ void Signal();
+
+ // Returns whether Signal() was called at least once or a timeout happened,
+ // and Reset() has not been called afterwards. Note that this function does
+ // not discriminate whether Signal() was called or a timeout happened.
+ // The |callback_|'s parameter has this distinction, though.
+ bool IsSignaled() const;
+
+ // Registers the |callback| and calls it immediately if Signal() was called
+ // already. Starts a timeout task, so that |callback| is called if no call of
+ // Signal() is observed within |timeout|. A previous timeout is replaced by a
+ // new one.
+ void OnEventOrTimeOut(Callback callback, base::TimeDelta timeout);
+
+ // Resets the state machine so that no Signal() was observed, no callback is
+ // registered and no timeout task is running.
+ void Reset();
+
+ private:
+ enum class State {
+ // Signal() has not been called, yet.
+ kInitialState,
+ // Signal() has been called, but callback is not specified.
+ kSignalReceived,
+ // callback has been called.
+ kDone,
+ };
+
+ // Internal callback for the timeout. |generation_id| is a generation counter
+ // to ensure that old, delayed timeout tasks are ignored.
+ void OnTimeOut(int generation_id);
+
+ // Handler for Signal() and OnTimeOut(). Calls |callback_| if appropriate.
+ // The parameter is true if this function is called via Signal() and false if
+ // the function is called via OnTimeOut(). This parameter is passed to
+ // callback.
+ void SignalHandler(bool triggered_by_signal);
+
+ State state_ = State::kInitialState;
+
+ // This variable is only valid if state_ == State::kSignalReceived. It is
+ // true if we moved into this state due to a Signal() call, and false if
+ // we moved into this state due to an OnTimeOut() call.
+ bool in_state_signal_received_due_to_signal_call_;
+
+ // As the base::ThreadPool does not support cancelable tasks, we just rely on
+ // a generation counter. Every time Reset() or OnEventOrTimeOut() are called,
+ // the generation id is incremented. If outdated delayed OnTimeOut() tasks
+ // trickle in, we recognize them as tasks for which the |generation_id|
+ // parameter is less than the current generation_id_ and ignore them.
+ int generation_id_ = 0;
+
+ // Callback to be called in case of a Signal() or a time out.
+ Callback callback_;
+
+ SEQUENCE_CHECKER(my_sequence_checker_);
+
+ base::WeakPtrFactory<WaitForSignalOrTimeout> weak_factory_{this};
+};
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_WAIT_FOR_SIGNAL_OR_TIMEOUT_H_
diff --git a/components/autofill/core/browser/payments/wait_for_signal_or_timeout_unittest.cc b/components/autofill/core/browser/payments/wait_for_signal_or_timeout_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..eda3fd362221cb9c08c893af02ce33a2826c5d6f
--- /dev/null
+++ b/components/autofill/core/browser/payments/wait_for_signal_or_timeout_unittest.cc
@@ -0,0 +1,188 @@
+// 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.
+
+#include "components/autofill/core/browser/payments/wait_for_signal_or_timeout.h"
+
+#include "base/test/task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class WaitForSignalOrTimeoutTest : public testing::Test {
+ public:
+ WaitForSignalOrTimeoutTest() = default;
+ ~WaitForSignalOrTimeoutTest() override = default;
+
+ WaitForSignalOrTimeout::Callback GetCallback() {
+ return base::BindOnce(&WaitForSignalOrTimeoutTest::Callback,
+ base::Unretained(this));
+ }
+
+ protected:
+ void Callback(bool triggered_by_signal) {
+ callbacks_++;
+ last_callback_triggered_by_signal_ = triggered_by_signal;
+ }
+
+ // Number of observed callbacks.
+ int callbacks_ = 0;
+
+ bool last_callback_triggered_by_signal_ = false;
+
+ base::test::TaskEnvironment task_env_{
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+};
+
+// WaitForSignalOrTimeout is initialized with a callback and then the Signal()
+// happens.
+TEST_F(WaitForSignalOrTimeoutTest, InitThenSignal) {
+ WaitForSignalOrTimeout wait;
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ EXPECT_EQ(0, callbacks_);
+ EXPECT_FALSE(wait.IsSignaled());
+ wait.Signal();
+ EXPECT_EQ(1, callbacks_);
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_TRUE(last_callback_triggered_by_signal_);
+
+ // Another signal call should be ignored.
+ wait.Signal();
+ EXPECT_EQ(1, callbacks_);
+ EXPECT_TRUE(wait.IsSignaled());
+
+ // Also the pending timeout should not trigger further callbacks.
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(35));
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_EQ(1, callbacks_);
+}
+
+// A Signal() is registered before the callback.
+TEST_F(WaitForSignalOrTimeoutTest, SignalThenInit) {
+ WaitForSignalOrTimeout wait;
+ EXPECT_FALSE(wait.IsSignaled());
+
+ // Trigger the signal before a callback handler is registered.
+ wait.Signal();
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_EQ(0, callbacks_);
+
+ // Once the callback handler is registered, it should be called immediately.
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_EQ(1, callbacks_);
+ EXPECT_TRUE(last_callback_triggered_by_signal_);
+
+ // Another signal call should be ignored.
+ wait.Signal();
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_EQ(1, callbacks_);
+
+ // Also the pending timeout should not trigger further callbacks.
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(35));
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_EQ(1, callbacks_);
+}
+
+// A timeout occurs before Signal() is called.
+TEST_F(WaitForSignalOrTimeoutTest, InitThenTimeout) {
+ WaitForSignalOrTimeout wait;
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ EXPECT_FALSE(wait.IsSignaled());
+ EXPECT_EQ(0, callbacks_);
+
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(35));
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_EQ(1, callbacks_);
+ EXPECT_FALSE(last_callback_triggered_by_signal_);
+
+ // A late signal will be ignored.
+ wait.Signal();
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_EQ(1, callbacks_);
+}
+
+// The WaitForSignalOrTimeout gets destroyed before a Signal() or timeout
+// happens.
+TEST_F(WaitForSignalOrTimeoutTest, DestroyedBeforeSignal) {
+ {
+ WaitForSignalOrTimeout wait;
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ }
+ EXPECT_EQ(0, callbacks_);
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(35));
+ EXPECT_EQ(0, callbacks_);
+}
+
+// The WaitForSignalOrTimeout gets signaled, reset, and signaled again.
+TEST_F(WaitForSignalOrTimeoutTest, Reset) {
+ WaitForSignalOrTimeout wait;
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ EXPECT_EQ(0, callbacks_);
+ wait.Signal();
+ EXPECT_EQ(1, callbacks_);
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_TRUE(last_callback_triggered_by_signal_);
+
+ wait.Reset();
+
+ EXPECT_FALSE(wait.IsSignaled());
+
+ // This signal does not trigger a callback because none is registered.
+ wait.Signal();
+ EXPECT_EQ(1, callbacks_);
+ // Now the callback happens immediately.
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ EXPECT_EQ(2, callbacks_);
+ EXPECT_TRUE(last_callback_triggered_by_signal_);
+
+ wait.Reset();
+
+ // Finally, we simulate a timeout after the reset.
+ EXPECT_FALSE(wait.IsSignaled());
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(35));
+ EXPECT_EQ(3, callbacks_);
+ EXPECT_FALSE(last_callback_triggered_by_signal_);
+}
+
+TEST_F(WaitForSignalOrTimeoutTest, OnEventOrTimeOutCalledTwice) {
+ WaitForSignalOrTimeout wait;
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+ EXPECT_EQ(0, callbacks_);
+
+ // Wait some time but not long enough for the timeout to trigger.
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(25));
+ EXPECT_EQ(0, callbacks_);
+ EXPECT_FALSE(wait.IsSignaled());
+
+ // This resets the state machine (currently waiting for a signal or timeout)
+ // and starts a new wait.
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+
+ // Wait some time but not long enough for the timeout to trigger.
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(25));
+ // The first timeout should not have triggered anything.
+ EXPECT_EQ(0, callbacks_);
+ EXPECT_FALSE(wait.IsSignaled());
+
+ // Wait some more time for the second timeout to kick in.
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ EXPECT_EQ(1, callbacks_);
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_FALSE(last_callback_triggered_by_signal_);
+
+ // This resets the state machine (currently in done state) once more and
+ // starts a new wait.
+ wait.OnEventOrTimeOut(GetCallback(), base::TimeDelta::FromSeconds(30));
+
+ // Wait some time but not long enough for the timeout to trigger.
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(25));
+ // The first timeout should not have triggered anything.
+ EXPECT_EQ(1, callbacks_);
+ EXPECT_FALSE(wait.IsSignaled());
+
+ // Wait some more time for the second timeout to kick in.
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ EXPECT_EQ(2, callbacks_);
+ EXPECT_TRUE(wait.IsSignaled());
+ EXPECT_FALSE(last_callback_triggered_by_signal_);
+}

View File

@@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20S=C3=B6derqvist?= <fs@opera.com>
Date: Fri, 9 Jul 2021 08:44:55 +0000
Subject: Set SVGImage::page_ after document install
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We can end up having the associated ImageResource call
SVGImage::ResetAnimation() before the Document has been associated with
the SVGImage's LocalFrame, but after the link to the initial Document
was severed, if a GC is triggered within that window and ends up
collecting the last observer of the ImageResource.
By assigning |SVGImage::page_| after the installing the document, we
close this hole since SVGImage::RootElement() (called by
SVGImage::ResetAnimation()) will now observe a null Page and return null
without attempting to dereference the document.
Bug: 1216190
Change-Id: I26e08848e5b9bd52e3377841eee35e4acc03d320
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3010140
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#899922}
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index 2ce8a78b3537c72206e2d3e6d55f9cc1fc5d3208..0dec91614edb0caa6f8e473f027c3be7b8bf1e4e 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -830,12 +830,15 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
// SVG Images are transparent.
frame->View()->SetBaseBackgroundColor(Color::kTransparent);
- page_ = page;
-
TRACE_EVENT0("blink", "SVGImage::dataChanged::load");
frame->ForceSynchronousDocumentInstall("image/svg+xml", Data());
+ // Set up our Page reference after installing our document. This avoids
+ // tripping on a non-existing (null) Document if a GC is triggered during the
+ // set up and ends up collecting the last owner/observer of this image.
+ page_ = page;
+
// Intrinsic sizing relies on computed style (e.g. font-size and
// writing-mode).
frame->GetDocument()->UpdateStyleAndLayoutTree();

View File

@@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: also propagate fullscreen state for outer frame
When entering fullscreen with Element.requestFullscreen in child frames,
the parent frame should also enter fullscreen mode too. Chromium handles
this for iframes, but not for webviews as they are essentially main
frames instead of child frames.
This patch makes webviews propagate the fullscreen state to embedder.
Note that we also need to manually update embedder's
`api::WebContents::IsFullscreenForTabOrPending` value.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 2e222a1bf9cb50efa990f875b102001998691f06..385080e04ed3fb6b82a1ed993889913546f0ba20 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -4728,6 +4728,15 @@ void RenderFrameHostImpl::EnterFullscreen(
notified_instances.insert(parent_site_instance);
}
+ // Entering fullscreen from webview should also notify its outer frame.
+ if (frame_tree_node()->render_manager()->IsMainFrameForInnerDelegate()) {
+ RenderFrameProxyHost* outer_proxy =
+ frame_tree_node()->render_manager()->GetProxyToOuterDelegate();
+ DCHECK(outer_proxy);
+ outer_proxy->GetAssociatedRemoteFrame()->WillEnterFullscreen(
+ options.Clone());
+ }
+
delegate_->EnterFullscreenMode(this, *options);
delegate_->FullscreenStateChanged(this, true /* is_fullscreen */,
std::move(options));

View File

@@ -17,5 +17,9 @@
"src/electron/patches/nan": "src/third_party/nan",
"src/electron/patches/angle": "src/third_party/angle"
"src/electron/patches/angle": "src/third_party/angle",
"src/electron/patches/usrsctp": "src/third_party/usrsctp/usrsctplib",
"src/electron/patches/sqlite": "src/third_party/sqlite/src"
}

View File

@@ -33,3 +33,4 @@ fix_remove_outdated_--experimental-wasm-bigint_flag.patch
fix_parallel_test-crypto-ecdh-convert-key_to_use_compatible_group.patch
src_inline_asynccleanuphookhandle_in_headers.patch
node-api_faster_threadsafe_function.patch
src_add_missing_context_scopes.patch

View File

@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anna Henningsen <anna@addaleax.net>
Date: Sun, 6 Dec 2020 16:35:06 +0100
Subject: src: add missing context scopes
Add scopes that ensure that the context associated with the
current Environment is always entered when working with it.
PR-URL: https://github.com/nodejs/node/pull/36413
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
diff --git a/src/env.cc b/src/env.cc
index 3ad13dd94a0954a447f5ce342a47823217d8b135..64266ea264448dfbe63a4ecad3cc784608ef3ffa 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -501,6 +501,8 @@ void Environment::InitializeLibuv() {
[](uv_async_t* async) {
Environment* env = ContainerOf(
&Environment::task_queues_async_, async);
+ HandleScope handle_scope(env->isolate());
+ Context::Scope context_scope(env->context());
env->RunAndClearNativeImmediates();
});
uv_unref(reinterpret_cast<uv_handle_t*>(&task_queues_async_));
diff --git a/src/node_file.cc b/src/node_file.cc
index de5c455c7a2a85f0676dfa50238c9bf29446ad58..3baf658961a80f91f08e75d728746c4127dab8bc 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -288,6 +288,7 @@ inline void FileHandle::Close() {
void FileHandle::CloseReq::Resolve() {
Isolate* isolate = env()->isolate();
HandleScope scope(isolate);
+ Context::Scope context_scope(env()->context());
InternalCallbackScope callback_scope(this);
Local<Promise> promise = promise_.Get(isolate);
Local<Promise::Resolver> resolver = promise.As<Promise::Resolver>();
@@ -297,6 +298,7 @@ void FileHandle::CloseReq::Resolve() {
void FileHandle::CloseReq::Reject(Local<Value> reason) {
Isolate* isolate = env()->isolate();
HandleScope scope(isolate);
+ Context::Scope context_scope(env()->context());
InternalCallbackScope callback_scope(this);
Local<Promise> promise = promise_.Get(isolate);
Local<Promise::Resolver> resolver = promise.As<Promise::Resolver>();

2
patches/sqlite/.patches Normal file
View File

@@ -0,0 +1,2 @@
utf-8_q_when_20constructing_20the_20synthensized_20select_20sta.patch
sqlite_fix_an_undefined-integer-overflow_problem_in_fts3_c.patch

View File

@@ -0,0 +1,157 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darwin Huang <huangdarwin@chromium.org>
Date: Wed, 19 May 2021 14:13:15 -0700
Subject: sqlite: Fix an undefined-integer-overflow problem in fts3.c.
Original change: https://sqlite.org/src/info/a0bf931bd712037e
Bug: 1204066
Change-Id: I34704f1cfe36672d10065f4103c91fb4f35d3895
diff --git a/amalgamation/sqlite3.c b/amalgamation/sqlite3.c
index d19e25f98d37686a7fd1bfefe4bd044575abf5d4..175c55f86fa02cbe443b53f656519879f9192765 100644
--- a/amalgamation/sqlite3.c
+++ b/amalgamation/sqlite3.c
@@ -169123,7 +169123,7 @@ static int fts3ScanInteriorNode(
char *zBuffer = 0; /* Buffer to load terms into */
i64 nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
- sqlite3_int64 iChild; /* Block id of child node to descend to */
+ u64 iChild; /* Block id of child node to descend to */
int nBuffer = 0; /* Total term size */
/* Skip over the 'height' varint that occurs at the start of every
@@ -169139,8 +169139,8 @@ static int fts3ScanInteriorNode(
** table, then there are always 20 bytes of zeroed padding following the
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
*/
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
+ zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
+ zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
if( zCsr>zEnd ){
return FTS_CORRUPT_VTAB;
}
@@ -169193,20 +169193,20 @@ static int fts3ScanInteriorNode(
*/
cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer));
if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){
- *piFirst = iChild;
+ *piFirst = (i64)iChild;
piFirst = 0;
}
if( piLast && cmp<0 ){
- *piLast = iChild;
+ *piLast = (i64)iChild;
piLast = 0;
}
iChild++;
};
- if( piFirst ) *piFirst = iChild;
- if( piLast ) *piLast = iChild;
+ if( piFirst ) *piFirst = (i64)iChild;
+ if( piLast ) *piLast = (i64)iChild;
finish_scan:
sqlite3_free(zBuffer);
diff --git a/amalgamation_dev/sqlite3.c b/amalgamation_dev/sqlite3.c
index f4c985513fb7cac3930fe9706ddfc5c440dd3e85..c3ec02ed9124d59ee008548491b2b30e996472ef 100644
--- a/amalgamation_dev/sqlite3.c
+++ b/amalgamation_dev/sqlite3.c
@@ -169636,7 +169636,7 @@ static int fts3ScanInteriorNode(
char *zBuffer = 0; /* Buffer to load terms into */
i64 nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
- sqlite3_int64 iChild; /* Block id of child node to descend to */
+ u64 iChild; /* Block id of child node to descend to */
int nBuffer = 0; /* Total term size */
/* Skip over the 'height' varint that occurs at the start of every
@@ -169652,8 +169652,8 @@ static int fts3ScanInteriorNode(
** table, then there are always 20 bytes of zeroed padding following the
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
*/
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
+ zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
+ zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
if( zCsr>zEnd ){
return FTS_CORRUPT_VTAB;
}
@@ -169706,20 +169706,20 @@ static int fts3ScanInteriorNode(
*/
cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer));
if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){
- *piFirst = iChild;
+ *piFirst = (i64)iChild;
piFirst = 0;
}
if( piLast && cmp<0 ){
- *piLast = iChild;
+ *piLast = (i64)iChild;
piLast = 0;
}
iChild++;
};
- if( piFirst ) *piFirst = iChild;
- if( piLast ) *piLast = iChild;
+ if( piFirst ) *piFirst = (i64)iChild;
+ if( piLast ) *piLast = (i64)iChild;
finish_scan:
sqlite3_free(zBuffer);
diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c
index 79dc5c88ceacb823d16889bd36250597361d6186..62b31373c3c3e9b61b3e1daae8d87d9393779b61 100644
--- a/ext/fts3/fts3.c
+++ b/ext/fts3/fts3.c
@@ -1897,7 +1897,7 @@ static int fts3ScanInteriorNode(
char *zBuffer = 0; /* Buffer to load terms into */
i64 nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
- sqlite3_int64 iChild; /* Block id of child node to descend to */
+ u64 iChild; /* Block id of child node to descend to */
int nBuffer = 0; /* Total term size */
/* Skip over the 'height' varint that occurs at the start of every
@@ -1913,8 +1913,8 @@ static int fts3ScanInteriorNode(
** table, then there are always 20 bytes of zeroed padding following the
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
*/
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
+ zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
+ zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
if( zCsr>zEnd ){
return FTS_CORRUPT_VTAB;
}
@@ -1967,20 +1967,20 @@ static int fts3ScanInteriorNode(
*/
cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer));
if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){
- *piFirst = iChild;
+ *piFirst = (i64)iChild;
piFirst = 0;
}
if( piLast && cmp<0 ){
- *piLast = iChild;
+ *piLast = (i64)iChild;
piLast = 0;
}
iChild++;
};
- if( piFirst ) *piFirst = iChild;
- if( piLast ) *piLast = iChild;
+ if( piFirst ) *piFirst = (i64)iChild;
+ if( piLast ) *piLast = (i64)iChild;
finish_scan:
sqlite3_free(zBuffer);

View File

@@ -0,0 +1,178 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: drh <>
Date: Wed, 19 May 2021 21:55:56 +0000
Subject: When constructing the synthensized SELECT statement that is used to
choose the rows in an UPDATE FROM, make sure the first table is really the
table being updated, and not some common-table expression that happens to
have the same name. [forum:/forumpost/a274248080|forum post a274248080]. More
changes associated with CTE name resolution are pending.
FossilOrigin-Name: 0f0959c6f95046e8e7887716e0a7de95da18d1e926ab1f919527083a56541db5
(cherry picked from commit 1168f810929ede4d8d323a6acf721ff9cd89de90)
diff --git a/amalgamation/sqlite3.c b/amalgamation/sqlite3.c
index 6b4a7899d336d07cf150530440755d25207b594f..d19e25f98d37686a7fd1bfefe4bd044575abf5d4 100644
--- a/amalgamation/sqlite3.c
+++ b/amalgamation/sqlite3.c
@@ -1173,7 +1173,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.34.0"
#define SQLITE_VERSION_NUMBER 3034000
-#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1"
+#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 571f9642d6a6caff9ea5ea572e2f1275e75c8385fbe1b7fb41cf72e4c13ealt1"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -111305,7 +111305,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(
struct SrcList_item *p
){
const char *zDb;
- assert( p->pSchema==0 || p->zDatabase==0 );
+ /* assert( p->pSchema==0 || p->zDatabase==0 ); FIX-ME */
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
zDb = pParse->db->aDb[iDb].zDbSName;
@@ -138346,6 +138346,10 @@ static void updateFromSelect(
assert( pTabList->nSrc>1 );
if( pSrc ){
+ if( pSrc->a[0].zDatabase==0 ){
+ int iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
+ pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iSchema].zDbSName);
+ }
pSrc->a[0].iCursor = -1;
pSrc->a[0].pTab->nTabRef--;
pSrc->a[0].pTab = 0;
@@ -231234,9 +231238,9 @@ SQLITE_API int sqlite3_stmt_init(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
-#if __LINE__!=231237
+#if __LINE__!=231241
#undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt2"
+#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 571f9642d6a6caff9ea5ea572e2f1275e75c8385fbe1b7fb41cf72e4c13ealt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
diff --git a/amalgamation/sqlite3.h b/amalgamation/sqlite3.h
index 44be7872663c9216b30ce6e13b1683ca2d807bd6..4935dd32d6aab4261b758c4c199ef0ad18c23ce9 100644
--- a/amalgamation/sqlite3.h
+++ b/amalgamation/sqlite3.h
@@ -125,7 +125,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.34.0"
#define SQLITE_VERSION_NUMBER 3034000
-#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1"
+#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 571f9642d6a6caff9ea5ea572e2f1275e75c8385fbe1b7fb41cf72e4c13ealt1"
/*
** CAPI3REF: Run-Time Library Version Numbers
diff --git a/amalgamation_dev/sqlite3.c b/amalgamation_dev/sqlite3.c
index d30c9b7dea35e5b4785f78b8bc5789fbc56bba84..f4c985513fb7cac3930fe9706ddfc5c440dd3e85 100644
--- a/amalgamation_dev/sqlite3.c
+++ b/amalgamation_dev/sqlite3.c
@@ -1173,7 +1173,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.34.0"
#define SQLITE_VERSION_NUMBER 3034000
-#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1"
+#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 571f9642d6a6caff9ea5ea572e2f1275e75c8385fbe1b7fb41cf72e4c13ealt1"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -111318,7 +111318,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(
struct SrcList_item *p
){
const char *zDb;
- assert( p->pSchema==0 || p->zDatabase==0 );
+ /* assert( p->pSchema==0 || p->zDatabase==0 ); FIX-ME */
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
zDb = pParse->db->aDb[iDb].zDbSName;
@@ -138359,6 +138359,10 @@ static void updateFromSelect(
assert( pTabList->nSrc>1 );
if( pSrc ){
+ if( pSrc->a[0].zDatabase==0 ){
+ int iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
+ pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iSchema].zDbSName);
+ }
pSrc->a[0].iCursor = -1;
pSrc->a[0].pTab->nTabRef--;
pSrc->a[0].pTab = 0;
@@ -231747,9 +231751,9 @@ SQLITE_API int sqlite3_stmt_init(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
-#if __LINE__!=231750
+#if __LINE__!=231754
#undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt2"
+#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 571f9642d6a6caff9ea5ea572e2f1275e75c8385fbe1b7fb41cf72e4c13ealt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
diff --git a/amalgamation_dev/sqlite3.h b/amalgamation_dev/sqlite3.h
index 44be7872663c9216b30ce6e13b1683ca2d807bd6..4935dd32d6aab4261b758c4c199ef0ad18c23ce9 100644
--- a/amalgamation_dev/sqlite3.h
+++ b/amalgamation_dev/sqlite3.h
@@ -125,7 +125,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.34.0"
#define SQLITE_VERSION_NUMBER 3034000
-#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1"
+#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 571f9642d6a6caff9ea5ea572e2f1275e75c8385fbe1b7fb41cf72e4c13ealt1"
/*
** CAPI3REF: Run-Time Library Version Numbers
diff --git a/manifest b/manifest
index 6c9cbb5ed81ca973f03931cea4d861209dee7037..76872d8b3a63cf623a1903ac0ccfc9b80f5c47d3 100644
--- a/manifest
+++ b/manifest
@@ -483,7 +483,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c ee14224322b9e4172d01e691e2f289f6c630ae39b7906f84b72dc780b9e42a76
F src/btree.h dcdff4037d75b3f032a5de0d922fcfaf35d48589417f634fa8627362709315f9
F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43
-F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81
+F src/build.c 0803beedb8312c4ee4d60e63390ad0480a4ef471a329a56f8887a4b6ffc66da5
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6
@@ -606,7 +606,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 4dc01b267593537e2a0d0efe9f80dabe24c5b6f7627bc6971c487fa6a1dacbbf
F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda
F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10
-F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580
+F src/update.c 3e767f6605ed3adf6085d7e3eb8bbcf7e845b60ebf5590720123b24f907d7414
F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002
diff --git a/src/build.c b/src/build.c
index 9779e93732b6d2f50cf5ac3822df1fbe6802eaa6..29d8ea66c105f9098c49ade70246828c92465f96 100644
--- a/src/build.c
+++ b/src/build.c
@@ -451,7 +451,7 @@ Table *sqlite3LocateTableItem(
struct SrcList_item *p
){
const char *zDb;
- assert( p->pSchema==0 || p->zDatabase==0 );
+ /* assert( p->pSchema==0 || p->zDatabase==0 ); FIX-ME */
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
zDb = pParse->db->aDb[iDb].zDbSName;
diff --git a/src/update.c b/src/update.c
index f8cb2afedb6f9f2931d29d266f65fabcd2cd443c..3e0ec2544a274356c68416d978c8585a143bf8a4 100644
--- a/src/update.c
+++ b/src/update.c
@@ -220,6 +220,10 @@ static void updateFromSelect(
assert( pTabList->nSrc>1 );
if( pSrc ){
+ if( pSrc->a[0].zDatabase==0 ){
+ int iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
+ pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iSchema].zDbSName);
+ }
pSrc->a[0].iCursor = -1;
pSrc->a[0].pTab->nTabRef--;
pSrc->a[0].pTab = 0;

1
patches/usrsctp/.patches Normal file
View File

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

View File

@@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Tuexen <tuexen@fh-muenster.de>
Date: Mon, 3 May 2021 02:29:58 +0200
Subject: Improve restart handling.
This fixes in particular a possible use after free bug reported
Anatoly Korniltsev and Taylor Brandstetter for the userland stack.
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
index 517189fb6a977da7fd57e8720897574b0fe493ab..289c65c61d7d26e88796f71e1df093a051b9086a 100755
--- a/usrsctplib/netinet/sctp_input.c
+++ b/usrsctplib/netinet/sctp_input.c
@@ -2005,11 +2005,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* temp code */
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 12;
- sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net,
- SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
- SCTP_FROM_SCTP_INPUT + SCTP_LOC_17);
-
+ sctp_stop_association_timers(stcb, false);
/* notify upper layer */
*notification = SCTP_NOTIFY_ASSOC_RESTART;
atomic_add_int(&stcb->asoc.refcnt, 1);
@@ -2042,6 +2038,10 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
asoc->str_reset_seq_in = asoc->init_seq_number;
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
asoc->send_sack = 1;
+ asoc->data_pkts_seen = 0;
+ asoc->last_data_chunk_from = NULL;
+ asoc->last_control_chunk_from = NULL;
+ asoc->last_net_cmt_send_started = NULL;
if (asoc->mapping_array) {
memset(asoc->mapping_array, 0,
asoc->mapping_array_size);
@@ -2106,6 +2106,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
SCTP_DECR_CHK_COUNT();
}
+ asoc->ctrl_queue_cnt = 0;
+ asoc->str_reset = NULL;
+ asoc->stream_reset_outstanding = 0;
TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
if (chk->data) {
@@ -2176,12 +2179,13 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
/* respond with a COOKIE-ACK */
- sctp_stop_all_cookie_timers(stcb);
- sctp_toss_old_cookies(stcb, asoc);
sctp_send_cookie_ack(stcb);
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 15;
-
+ if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE) &&
+ (asoc->sctp_autoclose_ticks > 0)) {
+ sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL);
+ }
return (stcb);
}
if (how_indx < sizeof(asoc->cookie_how))

View File

@@ -20,3 +20,9 @@ merged_wasm-simd_ia32_fix_f64x2_min_max_to_use_registers.patch
merged_const-tracking_generalize_constness_when_delete_properties.patch
merged_liftoff_fix_2gb_memory_accesses_on_32-bit.patch
reland_compiler_fix_more_truncation_bugs_in_simplifiedlowering.patch
cherry-pick-d0aadee1a60a.patch
m90-lts_squashed_multiple_commits.patch
cherry-pick-b9ad6a864c79.patch
cherry-pick-50de6a8ddad9.patch
cherry-pick-e76178b896f2.patch
merged_compiler_fix_a_bug_in.patch

View File

@@ -0,0 +1,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kim-Anh Tran <kimanh@chromium.org>
Date: Thu, 6 May 2021 10:02:01 +0200
Subject: M90-LTS: [debugger] Return ServerError if debugger agent is disabled
This returns a server error on setting breakpoints if the
agent is disabled.
(cherry picked from commit 5aa2de8128f885c44df79d38fb4aa5c6a5d94306)
Also-by: bmeurer@chromium.org
Fixed: chromium:1202534
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: I87c80a4bd785fa5c59a8dd0d5ac5f4b31b015ed8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2874662
Commit-Queue: Kim-Anh Tran <kimanh@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Auto-Submit: Kim-Anh Tran <kimanh@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#74399}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2940883
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/9.0@{#59}
Cr-Branched-From: bd0108b4c88e0d6f2350cb79b5f363fbd02f3eb7-refs/heads/9.0.257@{#1}
Cr-Branched-From: 349bcc6a075411f1a7ce2d866c3dfeefc2efa39d-refs/heads/master@{#73001}
diff --git a/src/inspector/v8-debugger-agent-impl.cc b/src/inspector/v8-debugger-agent-impl.cc
index 4e0b83952e25d01d8d69cc3c51606a7f48c5f6ee..1ea1c6fab3fd5cbe92d4724f938c569605c1cf44 100644
--- a/src/inspector/v8-debugger-agent-impl.cc
+++ b/src/inspector/v8-debugger-agent-impl.cc
@@ -499,6 +499,8 @@ Response V8DebuggerAgentImpl::setBreakpointByUrl(
Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition,
String16* outBreakpointId,
std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) {
+ if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
+
*locations = std::make_unique<Array<protocol::Debugger::Location>>();
int specified = (optionalURL.isJust() ? 1 : 0) +
@@ -587,6 +589,8 @@ Response V8DebuggerAgentImpl::setBreakpoint(
String16 breakpointId = generateBreakpointId(
BreakpointType::kByScriptId, location->getScriptId(),
location->getLineNumber(), location->getColumnNumber(0));
+ if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
+
if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
m_breakpointIdToDebuggerBreakpointIds.end()) {
return Response::ServerError(
@@ -605,6 +609,8 @@ Response V8DebuggerAgentImpl::setBreakpoint(
Response V8DebuggerAgentImpl::setBreakpointOnFunctionCall(
const String16& functionObjectId, Maybe<String16> optionalCondition,
String16* outBreakpointId) {
+ if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
+
InjectedScript::ObjectScope scope(m_session, functionObjectId);
Response response = scope.initialize();
if (!response.IsSuccess()) return response;
diff --git a/test/inspector/debugger/set-breakpoint-before-enabling-expected.txt b/test/inspector/debugger/set-breakpoint-before-enabling-expected.txt
index 02bfe0d80cdecd96d37988d9d6850b49c5d7e39d..a85aab6fe0c71f3346fe79694d1a334e2cb12fb2 100644
--- a/test/inspector/debugger/set-breakpoint-before-enabling-expected.txt
+++ b/test/inspector/debugger/set-breakpoint-before-enabling-expected.txt
@@ -1,7 +1,13 @@
Tests that setting breakpoint before enabling debugger produces an error
-setBreakpointByUrl error: undefined
+setBreakpointByUrl error: {
+ "code": -32000,
+ "message": "Debugger agent is not enabled"
+}
setBreakpoint error: {
- "code": -32602,
- "message": "Invalid parameters",
- "data": "Failed to deserialize params.location - BINDINGS: mandatory field missing at <some position>"
+ "code": -32000,
+ "message": "Debugger agent is not enabled"
+}
+setBreakpointOnFunctionCall error: {
+ "code": -32000,
+ "message": "Debugger agent is not enabled"
}
diff --git a/test/inspector/debugger/set-breakpoint-before-enabling.js b/test/inspector/debugger/set-breakpoint-before-enabling.js
index 5af1085c8747089dea15550949130b8ea243b524..4401466a921692bbe94b52e60083d92769407ee3 100644
--- a/test/inspector/debugger/set-breakpoint-before-enabling.js
+++ b/test/inspector/debugger/set-breakpoint-before-enabling.js
@@ -10,12 +10,19 @@ function didSetBreakpointByUrlBeforeEnable(message)
{
InspectorTest.log("setBreakpointByUrl error: " + JSON.stringify(
InspectorTest.trimErrorMessage(message).error, null, 2));
- Protocol.Debugger.setBreakpoint().then(didSetBreakpointBeforeEnable);
+ Protocol.Debugger.setBreakpoint({location: { scriptId: "4", lineNumber: 0, columnNumber: 0 }}).then(didSetBreakpointBeforeEnable);
}
function didSetBreakpointBeforeEnable(message)
{
InspectorTest.log("setBreakpoint error: " + JSON.stringify(
InspectorTest.trimErrorMessage(message).error, null, 2));
+ Protocol.Debugger.setBreakpointOnFunctionCall({objectId: "4"}).then(didSetBreakpointOnFunctionCallBeforeEnable);
+}
+
+function didSetBreakpointOnFunctionCallBeforeEnable(message)
+{
+ InspectorTest.log("setBreakpointOnFunctionCall error: " + JSON.stringify(
+ InspectorTest.trimErrorMessage(message).error, null, 2));
InspectorTest.completeTest();
}

View File

@@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Georg Neis <neis@chromium.org>
Date: Thu, 27 May 2021 13:04:30 +0200
Subject: Reland "Merged: [compiler] Always record constness dependency for
FastDataConstant"
This is a reland of 638d1b238d510a349bdd38648add8d5c85bc5f7d after a
one-character change. A local variable still has a non-optional type
in this version of V8.
Original change's description:
> Merged: [compiler] Always record constness dependency for FastDataConstant
>
> Revision: 1bfa5139966fe0c9e8036fe6362b61c483675775
>
> BUG=chromium:1209558
> NOTRY=true
> NOPRESUBMIT=true
> NOTREECHECKS=true
>
> Change-Id: If4f7243647bcc12ed482796c1353f0717630f6b9
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2919823
> Commit-Queue: Georg Neis <neis@chromium.org>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Cr-Commit-Position: refs/branch-heads/9.1@{#59}
> Cr-Branched-From: 0e4ac64a8cf298b14034a22f9fe7b085d2cb238d-refs/heads/9.1.269@{#1}
> Cr-Branched-From: f565e72d5ba88daae35a59d0f978643e2343e912-refs/heads/master@{#73847}
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
(cherry picked from commit 73666e3f6d6bdbc93ab81cf8b3803dd04930e293)
Bug: chromium:1209558
Change-Id: I0c81353882b0f17942fd92ad4181732f941bcb1d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2939991
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/9.1@{#63}
Cr-Original-Branched-From: 0e4ac64a8cf298b14034a22f9fe7b085d2cb238d-refs/heads/9.1.269@{#1}
Cr-Original-Branched-From: f565e72d5ba88daae35a59d0f978643e2343e912-refs/heads/master@{#73847}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2948651
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/9.0@{#62}
Cr-Branched-From: bd0108b4c88e0d6f2350cb79b5f363fbd02f3eb7-refs/heads/9.0.257@{#1}
Cr-Branched-From: 349bcc6a075411f1a7ce2d866c3dfeefc2efa39d-refs/heads/master@{#73001}
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
index ddf742e7089544807d0565d42d6a26bc0dace56f..74f332456f8bcba4b93ae0f211c299293b9fd5b4 100644
--- a/src/compiler/access-info.cc
+++ b/src/compiler/access-info.cc
@@ -897,7 +897,7 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition(
// Transitioning stores *may* store to const fields. The resulting
// DataConstant access infos can be distinguished from later, i.e. redundant,
// stores to the same constant field by the presence of a transition map.
- switch (details.constness()) {
+ switch (dependencies()->DependOnFieldConstness(transition_map_ref, number)) {
case PropertyConstness::kMutable:
return PropertyAccessInfo::DataField(
zone(), map, std::move(unrecorded_dependencies), field_index,

View File

@@ -0,0 +1,137 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Georg Neis <neis@chromium.org>
Date: Mon, 7 Jun 2021 10:41:38 +0200
Subject: Squashed multiple commits.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Merged: Disable left-trimming when optimizing compile jobs exist
Revision: ac0605a1a486b8d074f116cc365de9d2b6d7c9e5
Merged: [heap] Don't assume that optimizing-compile-dispatcher exists
Revision: 022b312d55e75935cfa99cca7729ae2d3f795bd0
BUG=chromium:1211215,chromium:1215514
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
(cherry picked from commit 8704c7c0b2f79cbe745f293b30d68f4505da7416)
Change-Id: I3b3a37d64402ea464c8e653517928522a1c5e0da
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2940899
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/9.1@{#67}
Cr-Original-Branched-From: 0e4ac64a8cf298b14034a22f9fe7b085d2cb238d-refs/heads/9.1.269@{#1}
Cr-Original-Branched-From: f565e72d5ba88daae35a59d0f978643e2343e912-refs/heads/master@{#73847}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2948656
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/9.0@{#61}
Cr-Branched-From: bd0108b4c88e0d6f2350cb79b5f363fbd02f3eb7-refs/heads/9.0.257@{#1}
Cr-Branched-From: 349bcc6a075411f1a7ce2d866c3dfeefc2efa39d-refs/heads/master@{#73001}
diff --git a/src/compiler-dispatcher/optimizing-compile-dispatcher.cc b/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
index d00b9b524bf2514eef92653f725764d625a43f6f..67d73367ad9373416fc7efa194430465c12106ea 100644
--- a/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
+++ b/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
@@ -50,7 +50,6 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask {
worker_thread_runtime_call_stats_(
isolate->counters()->worker_thread_runtime_call_stats()),
dispatcher_(dispatcher) {
- base::MutexGuard lock_guard(&dispatcher_->ref_count_mutex_);
++dispatcher_->ref_count_;
}
@@ -98,12 +97,7 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask {
};
OptimizingCompileDispatcher::~OptimizingCompileDispatcher() {
-#ifdef DEBUG
- {
- base::MutexGuard lock_guard(&ref_count_mutex_);
- DCHECK_EQ(0, ref_count_);
- }
-#endif
+ DCHECK_EQ(0, ref_count_);
DCHECK_EQ(0, input_queue_length_);
DeleteArray(input_queue_);
}
@@ -234,6 +228,14 @@ void OptimizingCompileDispatcher::InstallOptimizedFunctions() {
}
}
+bool OptimizingCompileDispatcher::HasJobs() {
+ DCHECK_EQ(ThreadId::Current(), isolate_->thread_id());
+ // Note: This relies on {output_queue_} being mutated by a background thread
+ // only when {ref_count_} is not zero. Also, {ref_count_} is never incremented
+ // by a background thread.
+ return !(ref_count_ == 0 && output_queue_.empty());
+}
+
void OptimizingCompileDispatcher::QueueForOptimization(
OptimizedCompilationJob* job) {
DCHECK(IsQueueAvailable());
diff --git a/src/compiler-dispatcher/optimizing-compile-dispatcher.h b/src/compiler-dispatcher/optimizing-compile-dispatcher.h
index 36f285d163101a82e2090d075f69f0f8da82f414..7d7a5bebb74ea4b9fb49cb3c82c9bae1821335a0 100644
--- a/src/compiler-dispatcher/optimizing-compile-dispatcher.h
+++ b/src/compiler-dispatcher/optimizing-compile-dispatcher.h
@@ -53,6 +53,9 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher {
static bool Enabled() { return FLAG_concurrent_recompilation; }
+ // This method must be called on the main thread.
+ bool HasJobs();
+
private:
class CompileTask;
@@ -90,7 +93,7 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher {
int blocked_jobs_;
- int ref_count_;
+ std::atomic<int> ref_count_;
base::Mutex ref_count_mutex_;
base::ConditionVariable ref_count_zero_;
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index eb0231b719e7a0325500d3f2074e1e9782e7c4a4..3f4348b063995eb5c23ddd8af2aa2ac900a88723 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -22,6 +22,7 @@
#include "src/codegen/compilation-cache.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
+#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/debug/debug.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/isolate-utils-inl.h"
@@ -3014,6 +3015,12 @@ bool Heap::CanMoveObjectStart(HeapObject object) {
if (IsLargeObject(object)) return false;
+ // Compilation jobs may have references to the object.
+ if (isolate()->concurrent_recompilation_enabled() &&
+ isolate()->optimizing_compile_dispatcher()->HasJobs()) {
+ return false;
+ }
+
// We can move the object start if the page was already swept.
return Page::FromHeapObject(object)->SweepingDone();
}
diff --git a/test/mjsunit/compiler/regress-1215514.js b/test/mjsunit/compiler/regress-1215514.js
new file mode 100644
index 0000000000000000000000000000000000000000..a597b310498458fd7219c33ff188ca2a6e543f45
--- /dev/null
+++ b/test/mjsunit/compiler/regress-1215514.js
@@ -0,0 +1,7 @@
+// Copyright 2021 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --no-concurrent-recompilation
+
+new Array(4242).shift();

View File

@@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Victor Gomes <victorgomes@chromium.org>
Date: Mon, 31 May 2021 13:16:54 +0200
Subject: Merged: [JSON] Fix GC issue in BuildJsonObject
We must ensure that the sweeper is not running or has already swept
mutable_double_buffer. Otherwise the GC can add it to the free list.
Change-Id: If0fc7617acdb6690f0567215b78f8728e1643ec0
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Bug: v8:11837, chromium:1214842
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2993033
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.1@{#75}
Cr-Branched-From: 0e4ac64a8cf298b14034a22f9fe7b085d2cb238d-refs/heads/9.1.269@{#1}
Cr-Branched-From: f565e72d5ba88daae35a59d0f978643e2343e912-refs/heads/master@{#73847}
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 3f4348b063995eb5c23ddd8af2aa2ac900a88723..5239523c23d63c2af57a3a9795939bd582d7d10c 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -2125,6 +2125,10 @@ void Heap::CompleteSweepingYoung(GarbageCollector collector) {
array_buffer_sweeper()->EnsureFinished();
}
+void Heap::EnsureSweepingCompleted() {
+ mark_compact_collector()->EnsureSweepingCompleted();
+}
+
void Heap::UpdateCurrentEpoch(GarbageCollector collector) {
if (IsYoungGenerationCollector(collector)) {
epoch_young_ = next_epoch();
diff --git a/src/heap/heap.h b/src/heap/heap.h
index 7dc9ef7d447521012c9b110e4fc94589ada3e6f4..b56641f2e1c51197a68d7c96d5bfca428feb1484 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -1068,6 +1068,8 @@ class Heap {
void CompleteSweepingFull();
void CompleteSweepingYoung(GarbageCollector collector);
+ void EnsureSweepingCompleted();
+
IncrementalMarking* incremental_marking() {
return incremental_marking_.get();
}
diff --git a/src/json/json-parser.cc b/src/json/json-parser.cc
index c0109bb77a01f7b6e8e23cd1b2f5d85c4473385b..c9844251cc8659587b3de85066cb0ea993d87014 100644
--- a/src/json/json-parser.cc
+++ b/src/json/json-parser.cc
@@ -633,6 +633,11 @@ Handle<Object> JsonParser<Char>::BuildJsonObject(
DCHECK_EQ(mutable_double_address, end);
}
#endif
+ // Before setting the length of mutable_double_buffer back to zero, we
+ // must ensure that the sweeper is not running or has already swept the
+ // object's page. Otherwise the GC can add the contents of
+ // mutable_double_buffer to the free list.
+ isolate()->heap()->EnsureSweepingCompleted();
mutable_double_buffer->set_length(0);
}
}

View File

@@ -0,0 +1,299 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "ishell@chromium.org" <ishell@chromium.org>
Date: Tue, 8 Jun 2021 17:33:32 +0200
Subject: Squashed multiple commits.
Merged: [runtime] Fix handling of interceptors
Revision: f9857fdf74
Merged: [runtime] Fix handling of interceptors, pt.2
Revision: 1f5113816c
BUG=chromium:1216437
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
(cherry picked from commit 1936d568193b37d50d99218724ebbb76785a30d2)
Change-Id: Ief3da51866c8d0b5e85c76fad00b25ac2379f615
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2947407
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/9.1@{#71}
Cr-Original-Branched-From: 0e4ac64a8cf298b14034a22f9fe7b085d2cb238d-refs/heads/9.1.269@{#1}
Cr-Original-Branched-From: f565e72d5ba88daae35a59d0f978643e2343e912-refs/heads/master@{#73847}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2948661
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/9.0@{#64}
Cr-Branched-From: bd0108b4c88e0d6f2350cb79b5f363fbd02f3eb7-refs/heads/9.0.257@{#1}
Cr-Branched-From: 349bcc6a075411f1a7ce2d866c3dfeefc2efa39d-refs/heads/master@{#73001}
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 5e17fa85fca29e709204950382c610f40d616a64..c5450d50527bb8db1ae67b93aafc4b455b10053b 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -2519,9 +2519,21 @@ Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
if ((maybe_attributes.FromJust() & READ_ONLY) != 0) {
return WriteToReadOnlyProperty(it, value, should_throw);
}
- if (maybe_attributes.FromJust() == ABSENT) break;
- *found = false;
- return Nothing<bool>();
+ // At this point we might have called interceptor's query or getter
+ // callback. Assuming that the callbacks have side effects, we use
+ // Object::SetSuperProperty() which works properly regardless on
+ // whether the property was present on the receiver or not when
+ // storing to the receiver.
+ if (maybe_attributes.FromJust() == ABSENT) {
+ // Proceed lookup from the next state.
+ it->Next();
+ } else {
+ // Finish lookup in order to make Object::SetSuperProperty() store
+ // property to the receiver.
+ it->NotFound();
+ }
+ return Object::SetSuperProperty(it, value, store_origin,
+ should_throw);
}
break;
}
@@ -2596,6 +2608,8 @@ Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
if (found) return result;
}
+ // TODO(ishell): refactor this: both SetProperty and and SetSuperProperty have
+ // this piece of code.
// If the receiver is the JSGlobalObject, the store was contextual. In case
// the property did not exist yet on the global object itself, we have to
// throw a reference error in strict mode. In sloppy mode, we continue.
@@ -2632,6 +2646,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
}
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
+ // Note, the callers rely on the fact that this code is redoing the full own
+ // lookup from scratch.
LookupIterator::Configuration c = LookupIterator::OWN;
LookupIterator own_lookup =
it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
@@ -2694,6 +2710,25 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
}
}
+ // TODO(ishell): refactor this: both SetProperty and and SetSuperProperty have
+ // this piece of code.
+ // If the receiver is the JSGlobalObject, the store was contextual. In case
+ // the property did not exist yet on the global object itself, we have to
+ // throw a reference error in strict mode. In sloppy mode, we continue.
+ if (receiver->IsJSGlobalObject() &&
+ (GetShouldThrow(isolate, should_throw) == ShouldThrow::kThrowOnError)) {
+ if (own_lookup.state() == LookupIterator::TRANSITION) {
+ // The property cell that we have created is garbage because we are going
+ // to throw now instead of putting it into the global dictionary. However,
+ // the cell might already have been stored into the feedback vector, so
+ // we must invalidate it nevertheless.
+ own_lookup.transition_cell()->ClearAndInvalidate(ReadOnlyRoots(isolate));
+ }
+ isolate->Throw(*isolate->factory()->NewReferenceError(
+ MessageTemplate::kNotDefined, own_lookup.GetName()));
+ return Nothing<bool>();
+ }
+
return AddDataProperty(&own_lookup, value, NONE, should_throw, store_origin);
}
diff --git a/test/cctest/test-api-interceptors.cc b/test/cctest/test-api-interceptors.cc
index 236053eb45c02201d3425ea2fd98cf3913084bfe..3d3e970fa52b633ffc9e734077e7971ae37306bc 100644
--- a/test/cctest/test-api-interceptors.cc
+++ b/test/cctest/test-api-interceptors.cc
@@ -875,9 +875,11 @@ THREADED_TEST(InterceptorHasOwnPropertyCausingGC) {
CHECK(!value->BooleanValue(isolate));
}
-static void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
- v8::GenericNamedPropertyQueryCallback query,
- const char* source, int expected) {
+namespace {
+
+void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
+ v8::GenericNamedPropertyQueryCallback query,
+ const char* source, int expected) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
@@ -892,14 +894,13 @@ static void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
CHECK_EQ(expected, value->Int32Value(context.local()).FromJust());
}
-static void CheckInterceptorLoadIC(
- v8::GenericNamedPropertyGetterCallback getter, const char* source,
- int expected) {
+void CheckInterceptorLoadIC(v8::GenericNamedPropertyGetterCallback getter,
+ const char* source, int expected) {
CheckInterceptorIC(getter, nullptr, source, expected);
}
-static void InterceptorLoadICGetter(
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+void InterceptorLoadICGetter(Local<Name> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = CcTest::isolate();
CHECK_EQ(isolate, info.GetIsolate());
@@ -909,6 +910,7 @@ static void InterceptorLoadICGetter(
info.GetReturnValue().Set(v8::Integer::New(isolate, 42));
}
+} // namespace
// This test should hit the load IC for the interceptor case.
THREADED_TEST(InterceptorLoadIC) {
@@ -925,9 +927,23 @@ THREADED_TEST(InterceptorLoadIC) {
// configurations of interceptor and explicit fields works fine
// (those cases are special cased to get better performance).
-static void InterceptorLoadXICGetter(
+namespace {
+
+void InterceptorLoadXICGetter(Local<Name> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ ApiTestFuzzer::Fuzz();
+ info.GetReturnValue().Set(
+ v8_str("x")
+ ->Equals(info.GetIsolate()->GetCurrentContext(), name)
+ .FromJust()
+ ? v8::Local<v8::Value>(v8::Integer::New(info.GetIsolate(), 42))
+ : v8::Local<v8::Value>());
+}
+
+void InterceptorLoadXICGetterWithSideEffects(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
+ CompileRun("interceptor_getter_side_effect()");
info.GetReturnValue().Set(
v8_str("x")
->Equals(info.GetIsolate()->GetCurrentContext(), name)
@@ -936,6 +952,7 @@ static void InterceptorLoadXICGetter(
: v8::Local<v8::Value>());
}
+} // namespace
THREADED_TEST(InterceptorLoadICWithFieldOnHolder) {
CheckInterceptorLoadIC(InterceptorLoadXICGetter,
@@ -1460,6 +1477,18 @@ void HasICQueryToggle(TKey name,
isolate, toggle ? v8::internal::ABSENT : v8::internal::NONE));
}
+template <typename TKey, v8::internal::PropertyAttributes attribute>
+void HasICQuerySideEffect(TKey name,
+ const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ ApiTestFuzzer::Fuzz();
+ v8::Isolate* isolate = CcTest::isolate();
+ CHECK_EQ(isolate, info.GetIsolate());
+ CompileRun("interceptor_query_side_effect()");
+ if (attribute != v8::internal::ABSENT) {
+ info.GetReturnValue().Set(v8::Integer::New(isolate, attribute));
+ }
+}
+
int named_query_counter = 0;
void NamedQueryCallback(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Integer>& info) {
@@ -1525,6 +1554,42 @@ THREADED_TEST(InterceptorHasICQueryToggle) {
500);
}
+THREADED_TEST(InterceptorStoreICWithSideEffectfulCallbacks) {
+ CheckInterceptorIC(EmptyInterceptorGetter,
+ HasICQuerySideEffect<Local<Name>, v8::internal::ABSENT>,
+ "let r;"
+ "let inside_side_effect = false;"
+ "let interceptor_query_side_effect = function() {"
+ " if (!inside_side_effect) {"
+ " inside_side_effect = true;"
+ " r.x = 153;"
+ " inside_side_effect = false;"
+ " }"
+ "};"
+ "for (var i = 0; i < 20; i++) {"
+ " r = { __proto__: o };"
+ " r.x = i;"
+ "}",
+ 19);
+
+ CheckInterceptorIC(InterceptorLoadXICGetterWithSideEffects,
+ nullptr, // query callback is not provided
+ "let r;"
+ "let inside_side_effect = false;"
+ "let interceptor_getter_side_effect = function() {"
+ " if (!inside_side_effect) {"
+ " inside_side_effect = true;"
+ " r.y = 153;"
+ " inside_side_effect = false;"
+ " }"
+ "};"
+ "for (var i = 0; i < 20; i++) {"
+ " r = { __proto__: o };"
+ " r.y = i;"
+ "}",
+ 19);
+}
+
static void InterceptorStoreICSetter(
Local<Name> key, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
@@ -1574,6 +1639,52 @@ THREADED_TEST(InterceptorStoreICWithNoSetter) {
CHECK_EQ(239 + 42, value->Int32Value(context.local()).FromJust());
}
+THREADED_TEST(EmptyInterceptorDoesNotShadowReadOnlyProperty) {
+ // Interceptor should not shadow readonly property 'x' on the prototype, and
+ // attempt to store to 'x' must throw.
+ CheckInterceptorIC(EmptyInterceptorGetter,
+ HasICQuery<Local<Name>, v8::internal::ABSENT>,
+ "'use strict';"
+ "let p = {};"
+ "Object.defineProperty(p, 'x', "
+ " {value: 153, writable: false});"
+ "o.__proto__ = p;"
+ "let result = 0;"
+ "let r;"
+ "for (var i = 0; i < 20; i++) {"
+ " r = { __proto__: o };"
+ " try {"
+ " r.x = i;"
+ " } catch (e) {"
+ " result++;"
+ " }"
+ "}"
+ "result",
+ 20);
+}
+
+THREADED_TEST(InterceptorShadowsReadOnlyProperty) {
+ // Interceptor claims that it has a writable property 'x', so the existence
+ // of the readonly property 'x' on the prototype should not cause exceptions.
+ CheckInterceptorIC(InterceptorLoadXICGetter,
+ nullptr, // query callback
+ "'use strict';"
+ "let p = {};"
+ "Object.defineProperty(p, 'x', "
+ " {value: 153, writable: false});"
+ "o.__proto__ = p;"
+ "let result = 0;"
+ "let r;"
+ "for (var i = 0; i < 20; i++) {"
+ " r = { __proto__: o };"
+ " try {"
+ " r.x = i;"
+ " result++;"
+ " } catch (e) {}"
+ "}"
+ "result",
+ 20);
+}
THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
v8::HandleScope scope(CcTest::isolate());

View File

@@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Georg Neis <neis@chromium.org>
Date: Tue, 13 Jul 2021 17:26:47 +0200
Subject: Merged: [compiler] Fix a bug in
CodeGenerator::AddTranslationForOperand
(cherry picked from commit 374354bfe4a30740b96936b33e522d6fcd1cda67)
Bug: chromium:1228407
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: I358d8736b7b5f87300496cbb39a7689d8207d85f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3027260
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Adam Klein <adamk@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.1@{#77}
Cr-Branched-From: 0e4ac64a8cf298b14034a22f9fe7b085d2cb238d-refs/heads/9.1.269@{#1}
Cr-Branched-From: f565e72d5ba88daae35a59d0f978643e2343e912-refs/heads/master@{#73847}
diff --git a/src/compiler/backend/code-generator.cc b/src/compiler/backend/code-generator.cc
index 83f8fbc4e8fdbbfea81ae5b368f0dbcf5b32b5bb..647444fa58b559cda4aaf257b0a477282eafd569 100644
--- a/src/compiler/backend/code-generator.cc
+++ b/src/compiler/backend/code-generator.cc
@@ -1389,7 +1389,8 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
default:
UNREACHABLE();
}
- if (literal.object().equals(info()->closure())) {
+ if (literal.object().equals(info()->closure()) &&
+ info()->function_context_specializing()) {
translation->StoreJSFrameFunction();
} else {
int literal_id = DefineDeoptimizationLiteral(literal);

View File

@@ -14,6 +14,8 @@
"parallel/test-child-process-fork-exec-path",
"parallel/test-cli-node-print-help",
"parallel/test-code-cache",
"parallel/test-cluster-bind-privileged-port",
"parallel/test-cluster-shared-handle-bind-privileged-port",
"parallel/test-crypto",
"parallel/test-crypto-aes-wrap",
"parallel/test-crypto-authenticated",

View File

@@ -229,6 +229,7 @@ async function callAppVeyor (targetBranch, job, options) {
accountName: 'electron-bot',
projectSlug: appVeyorJobs[job],
branch: targetBranch,
commitId: options.commit || undefined,
environmentVariables
}),
method: 'POST'
@@ -364,7 +365,7 @@ if (require.main === module) {
if (args._.length < 1) {
console.log(`Trigger CI to build release builds of electron.
Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|VSTS|DevOps]
[--ghRelease] [--armTest] [--circleBuildNum=xxx] [--appveyorJobId=xxx] TARGET_BRANCH
[--ghRelease] [--armTest] [--circleBuildNum=xxx] [--appveyorJobId=xxx] [--commit=sha] TARGET_BRANCH
`);
process.exit(0);
}

View File

@@ -9,7 +9,8 @@ const rootPackageJson = require('../../package.json');
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({
userAgent: 'electron-npm-publisher'
userAgent: 'electron-npm-publisher',
auth: process.env.ELECTRON_GITHUB_TOKEN
});
if (!process.env.ELECTRON_NPM_OTP) {

View File

@@ -26,6 +26,7 @@ function getLastBumpCommit (tag) {
async function revertBumpCommit (tag) {
const branch = await getCurrentBranch();
const commitToRevert = getLastBumpCommit(tag).hash;
await GitProcess.exec(['pull', '--rebase']);
await GitProcess.exec(['revert', commitToRevert], ELECTRON_DIR);
const pushDetails = await GitProcess.exec(['push', 'origin', `HEAD:${branch}`, '--follow-tags'], ELECTRON_DIR);
if (pushDetails.exitCode === 0) {

View File

@@ -524,4 +524,8 @@ async function validateChecksums (validationArgs) {
`shasums defined in ${validationArgs.shaSumFile}.`);
}
makeRelease(args.validateRelease);
makeRelease(args.validateRelease)
.catch((err) => {
console.error('Error occurred while making release:', err);
process.exit(1);
});

View File

@@ -103,7 +103,75 @@ namespace crash_reporter {
extern const char kCrashpadProcess[];
}
// In 32-bit builds, the main thread starts with the default (small) stack size.
// The ARCH_CPU_32_BITS blocks here and below are in support of moving the main
// thread to a fiber with a larger stack size.
#if defined(ARCH_CPU_32_BITS)
// The information needed to transfer control to the large-stack fiber and later
// pass the main routine's exit code back to the small-stack fiber prior to
// termination.
struct FiberState {
HINSTANCE instance;
LPVOID original_fiber;
int fiber_result;
};
// A PFIBER_START_ROUTINE function run on a large-stack fiber that calls the
// main routine, stores its return value, and returns control to the small-stack
// fiber. |params| must be a pointer to a FiberState struct.
void WINAPI FiberBinder(void* params) {
auto* fiber_state = static_cast<FiberState*>(params);
// Call the wWinMain routine from the fiber. Reusing the entry point minimizes
// confusion when examining call stacks in crash reports - seeing wWinMain on
// the stack is a handy hint that this is the main thread of the process.
fiber_state->fiber_result =
wWinMain(fiber_state->instance, nullptr, nullptr, 0);
// Switch back to the main thread to exit.
::SwitchToFiber(fiber_state->original_fiber);
}
#endif // defined(ARCH_CPU_32_BITS)
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
#if defined(ARCH_CPU_32_BITS)
enum class FiberStatus { kConvertFailed, kCreateFiberFailed, kSuccess };
FiberStatus fiber_status = FiberStatus::kSuccess;
// GetLastError result if fiber conversion failed.
DWORD fiber_error = ERROR_SUCCESS;
if (!::IsThreadAFiber()) {
// Make the main thread's stack size 4 MiB so that it has roughly the same
// effective size as the 64-bit build's 8 MiB stack.
constexpr size_t kStackSize = 4 * 1024 * 1024; // 4 MiB
// Leak the fiber on exit.
LPVOID original_fiber =
::ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH);
if (original_fiber) {
FiberState fiber_state = {instance, original_fiber};
// Create a fiber with a bigger stack and switch to it. Leak the fiber on
// exit.
LPVOID big_stack_fiber = ::CreateFiberEx(
0, kStackSize, FIBER_FLAG_FLOAT_SWITCH, FiberBinder, &fiber_state);
if (big_stack_fiber) {
::SwitchToFiber(big_stack_fiber);
// The fibers must be cleaned up to avoid obscure TLS-related shutdown
// crashes.
::DeleteFiber(big_stack_fiber);
::ConvertFiberToThread();
// Control returns here after Chrome has finished running on FiberMain.
return fiber_state.fiber_result;
}
fiber_status = FiberStatus::kCreateFiberFailed;
} else {
fiber_status = FiberStatus::kConvertFailed;
}
// If we reach here then creating and switching to a fiber has failed. This
// probably means we are low on memory and will soon crash. Try to report
// this error once crash reporting is initialized.
fiber_error = ::GetLastError();
base::debug::Alias(&fiber_error);
}
// If we are already a fiber then continue normal execution.
#endif // defined(ARCH_CPU_32_BITS)
struct Arguments {
int argc = 0;
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
@@ -198,6 +266,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
return crashpad_status;
}
#if defined(ARCH_CPU_32_BITS)
// Intentionally crash if converting to a fiber failed.
CHECK_EQ(fiber_status, FiberStatus::kSuccess);
#endif // defined(ARCH_CPU_32_BITS)
if (!electron::CheckCommandLineArguments(arguments.argc, arguments.argv))
return -1;

View File

@@ -864,6 +864,10 @@ void BaseWindow::SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) {
}
#if defined(OS_MAC)
std::string BaseWindow::GetAlwaysOnTopLevel() {
return window_->GetAlwaysOnTopLevel();
}
void BaseWindow::SetTrafficLightPosition(const gfx::Point& position) {
window_->SetTrafficLightPosition(position);
}
@@ -1244,6 +1248,7 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isVisibleOnAllWorkspaces",
&BaseWindow::IsVisibleOnAllWorkspaces)
#if defined(OS_MAC)
.SetMethod("_getAlwaysOnTopLevel", &BaseWindow::GetAlwaysOnTopLevel)
.SetMethod("setAutoHideCursor", &BaseWindow::SetAutoHideCursor)
#endif
.SetMethod("setVibrancy", &BaseWindow::SetVibrancy)

View File

@@ -191,6 +191,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
virtual void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value);
#if defined(OS_MAC)
std::string GetAlwaysOnTopLevel();
void SetTrafficLightPosition(const gfx::Point& position);
gfx::Point GetTrafficLightPosition() const;
#endif

View File

@@ -394,6 +394,10 @@ void BrowserWindow::ResetBrowserViews() {
#endif
}
void BrowserWindow::OnDevToolsResized() {
UpdateDraggableRegions(draggable_regions_);
}
void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
v8::Local<v8::Value> value) {
std::string type = gin::V8ToString(isolate, value);

View File

@@ -63,9 +63,7 @@ class BrowserWindow : public BaseWindow,
void OnActivateContents() override;
void OnPageTitleUpdated(const base::string16& title,
bool explicit_set) override;
#if defined(OS_MAC)
void OnDevToolsResized() override;
#endif
// NativeWindowObserver:
void RequestPreferredWidth(int* width) override;
@@ -121,9 +119,7 @@ class BrowserWindow : public BaseWindow,
// it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresponsive_closure_;
#if defined(OS_MAC)
std::vector<mojom::DraggableRegionPtr> draggable_regions_;
#endif
v8::Global<v8::Value> web_contents_;
base::WeakPtr<api::WebContents> api_web_contents_;

View File

@@ -37,10 +37,6 @@ void BrowserWindow::OverrideNSWindowContentView(
[contentView viewDidMoveToWindow];
}
void BrowserWindow::OnDevToolsResized() {
UpdateDraggableRegions(draggable_regions_);
}
void BrowserWindow::UpdateDraggableRegions(
const std::vector<mojom::DraggableRegionPtr>& regions) {
if (window_->has_frame())

View File

@@ -5,6 +5,7 @@
#include "shell/browser/api/electron_api_browser_window.h"
#include "shell/browser/native_window_views.h"
#include "ui/aura/window.h"
namespace electron {
@@ -14,8 +15,20 @@ void BrowserWindow::UpdateDraggableRegions(
const std::vector<mojom::DraggableRegionPtr>& regions) {
if (window_->has_frame())
return;
if (&draggable_regions_ != &regions) {
auto const offset =
web_contents()->GetNativeView()->GetBoundsInRootWindow();
auto snapped_regions = mojo::Clone(regions);
for (auto& snapped_region : snapped_regions) {
snapped_region->bounds.Offset(offset.x(), offset.y());
}
draggable_regions_ = mojo::Clone(snapped_regions);
}
static_cast<NativeWindowViews*>(window_.get())
->UpdateDraggableRegions(regions);
->UpdateDraggableRegions(draggable_regions_);
}
} // namespace api

View File

@@ -236,7 +236,7 @@ base::string16 Menu::GetToolTipAt(int index) const {
return model_->GetToolTipAt(index);
}
#ifdef DCHECK_IS_ON
#if DCHECK_IS_ON()
base::string16 Menu::GetAcceleratorTextAtForTesting(int index) const {
ui::Accelerator accelerator;
model_->GetAcceleratorAtWithParams(index, true, &accelerator);
@@ -297,7 +297,7 @@ v8::Local<v8::ObjectTemplate> Menu::FillObjectTemplate(
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
.SetMethod("popupAt", &Menu::PopupAt)
.SetMethod("closePopupAt", &Menu::ClosePopupAt)
#ifdef DCHECK_IS_ON
#if DCHECK_IS_ON()
.SetMethod("getAcceleratorTextAt", &Menu::GetAcceleratorTextAtForTesting)
#endif
.Build();

View File

@@ -78,7 +78,7 @@ class Menu : public gin::Wrappable<Menu>,
int positioning_item,
base::OnceClosure callback) = 0;
virtual void ClosePopupAt(int32_t window_id) = 0;
#ifdef DCHECK_IS_ON
#if DCHECK_IS_ON()
virtual base::string16 GetAcceleratorTextAtForTesting(int index) const;
#endif

View File

@@ -35,7 +35,7 @@ class MenuMac : public Menu {
int positioning_item,
base::OnceClosure callback);
void ClosePopupAt(int32_t window_id) override;
#ifdef DCHECK_IS_ON
#if DCHECK_IS_ON()
base::string16 GetAcceleratorTextAtForTesting(int index) const override;
#endif

View File

@@ -127,7 +127,7 @@ void MenuMac::ClosePopupAt(int32_t window_id) {
std::move(close_popup));
}
#ifdef DCHECK_IS_ON
#if DCHECK_IS_ON()
base::string16 MenuMac::GetAcceleratorTextAtForTesting(int index) const {
// A least effort to get the real shortcut text of NSMenuItem, the code does
// not need to be perfect since it is test only.

View File

@@ -99,6 +99,7 @@
#include "shell/browser/web_contents_zoom_controller.h"
#include "shell/browser/web_dialog_helper.h"
#include "shell/browser/web_view_guest_delegate.h"
#include "shell/browser/web_view_manager.h"
#include "shell/common/api/electron_api_native_image.h"
#include "shell/common/color_util.h"
#include "shell/common/electron_constants.h"
@@ -1229,31 +1230,29 @@ void WebContents::OnEnterFullscreenModeForTab(
content::RenderFrameHost* requesting_frame,
const blink::mojom::FullscreenOptions& options,
bool allowed) {
if (!allowed)
return;
if (!owner_window_)
if (!allowed || !owner_window_)
return;
auto* source = content::WebContents::FromRenderFrameHost(requesting_frame);
if (IsFullscreenForTabOrPending(source)) {
DCHECK_EQ(fullscreen_frame_, source->GetFocusedFrame());
return;
}
SetHtmlApiFullscreen(true);
owner_window_->NotifyWindowEnterHtmlFullScreen();
if (native_fullscreen_) {
// Explicitly trigger a view resize, as the size is not actually changing if
// the browser is fullscreened, too.
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
}
Emit("enter-html-full-screen");
}
void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
if (!owner_window_)
return;
SetHtmlApiFullscreen(false);
owner_window_->NotifyWindowLeaveHtmlFullScreen();
if (native_fullscreen_) {
// Explicitly trigger a view resize, as the size is not actually changing if
@@ -1261,7 +1260,6 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
// `chrome/browser/ui/exclusive_access/fullscreen_controller.cc`.
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
}
Emit("leave-html-full-screen");
}
void WebContents::RendererUnresponsive(
@@ -1740,6 +1738,8 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry) {
} else {
final_title = title;
}
} else {
final_title = web_contents()->GetTitle();
}
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnPageTitleUpdated(final_title, explicit_set);
@@ -3464,6 +3464,30 @@ void WebContents::DevToolsSearchInPath(int request_id,
file_system_path));
}
void WebContents::DevToolsSetEyeDropperActive(bool active) {
auto* web_contents = GetWebContents();
if (!web_contents)
return;
if (active) {
eye_dropper_ = std::make_unique<DevToolsEyeDropper>(
web_contents, base::BindRepeating(&WebContents::ColorPickedInEyeDropper,
base::Unretained(this)));
} else {
eye_dropper_.reset();
}
}
void WebContents::ColorPickedInEyeDropper(int r, int g, int b, int a) {
base::DictionaryValue color;
color.SetInteger("r", r);
color.SetInteger("g", g);
color.SetInteger("b", b);
color.SetInteger("a", a);
inspectable_web_contents_->CallClientFunction(
"DevToolsAPI.eyeDropperPickedColor", &color, nullptr, nullptr);
}
#if defined(TOOLKIT_VIEWS) && !defined(OS_MAC)
gfx::ImageSkia WebContents::GetDevToolsWindowIcon() {
if (!owner_window())
@@ -3532,13 +3556,13 @@ void WebContents::SetHtmlApiFullscreen(bool enter_fullscreen) {
// Window is already in fullscreen mode, save the state.
if (enter_fullscreen && owner_window_->IsFullscreen()) {
native_fullscreen_ = true;
html_fullscreen_ = true;
UpdateHtmlApiFullscreen(true);
return;
}
// Exit html fullscreen state but not window's fullscreen mode.
if (!enter_fullscreen && native_fullscreen_) {
html_fullscreen_ = false;
UpdateHtmlApiFullscreen(false);
return;
}
@@ -3553,10 +3577,47 @@ void WebContents::SetHtmlApiFullscreen(bool enter_fullscreen) {
owner_window_->SetFullScreen(enter_fullscreen);
}
html_fullscreen_ = enter_fullscreen;
UpdateHtmlApiFullscreen(enter_fullscreen);
native_fullscreen_ = false;
}
void WebContents::UpdateHtmlApiFullscreen(bool fullscreen) {
if (fullscreen == is_html_fullscreen())
return;
html_fullscreen_ = fullscreen;
// Notify renderer of the html fullscreen change.
web_contents()
->GetRenderViewHost()
->GetWidget()
->SynchronizeVisualProperties();
// The embedder WebContents is separated from the frame tree of webview, so
// we must manually sync their fullscreen states.
if (embedder_)
embedder_->SetHtmlApiFullscreen(fullscreen);
if (fullscreen) {
Emit("enter-html-full-screen");
owner_window_->NotifyWindowEnterHtmlFullScreen();
} else {
Emit("leave-html-full-screen");
owner_window_->NotifyWindowLeaveHtmlFullScreen();
}
// Make sure all child webviews quit html fullscreen.
if (!fullscreen && !IsGuest()) {
auto* manager = WebViewManager::GetWebViewManager(web_contents());
manager->ForEachGuest(
web_contents(), base::BindRepeating([](content::WebContents* guest) {
WebContents* api_web_contents = WebContents::From(guest);
api_web_contents->SetHtmlApiFullscreen(false);
return false;
}));
}
}
// static
v8::Local<v8::ObjectTemplate> WebContents::FillObjectTemplate(
v8::Isolate* isolate,

View File

@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "chrome/browser/devtools/devtools_eye_dropper.h"
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
#include "content/common/cursors/webcursor.h"
#include "content/common/frame.mojom.h"
@@ -665,6 +666,7 @@ class WebContents : public gin::Wrappable<WebContents>,
void DevToolsSearchInPath(int request_id,
const std::string& file_system_path,
const std::string& query) override;
void DevToolsSetEyeDropperActive(bool active) override;
// InspectableWebContentsViewDelegate:
#if defined(TOOLKIT_VIEWS) && !defined(OS_MAC)
@@ -678,6 +680,8 @@ class WebContents : public gin::Wrappable<WebContents>,
// Destroy the managed InspectableWebContents object.
void ResetManagedWebContents(bool async);
void ColorPickedInEyeDropper(int r, int g, int b, int a);
// DevTools index event callbacks.
void OnDevToolsIndexingWorkCalculated(int request_id,
const std::string& file_system_path,
@@ -693,6 +697,8 @@ class WebContents : public gin::Wrappable<WebContents>,
// Set fullscreen mode triggered by html api.
void SetHtmlApiFullscreen(bool enter_fullscreen);
// Update the html fullscreen flag in both browser and renderer.
void UpdateHtmlApiFullscreen(bool fullscreen);
v8::Global<v8::Value> session_;
v8::Global<v8::Value> devtools_web_contents_;
@@ -747,6 +753,8 @@ class WebContents : public gin::Wrappable<WebContents>,
scoped_refptr<DevToolsFileSystemIndexer> devtools_file_system_indexer_;
std::unique_ptr<DevToolsEyeDropper> eye_dropper_;
ElectronBrowserContext* browser_context_;
// The stored InspectableWebContents object.

View File

@@ -129,7 +129,7 @@ v8::Local<v8::Value> HttpResponseHeadersToV8(
!value.empty()) {
net::HttpContentDisposition header(value, std::string());
std::string decodedFilename =
header.is_attachment() ? " attachement" : " inline";
header.is_attachment() ? " attachment" : " inline";
decodedFilename += "; filename=" + header.filename();
value = decodedFilename;
}
@@ -214,8 +214,11 @@ void ReadFromResponse(v8::Isolate* isolate,
void ReadFromResponse(v8::Isolate* isolate,
gin::Dictionary* response,
net::HttpRequestHeaders* headers) {
headers->Clear();
response->Get("requestHeaders", headers);
v8::Local<v8::Value> value;
if (response->Get("requestHeaders", &value) && value->IsObject()) {
headers->Clear();
gin::Converter<net::HttpRequestHeaders>::FromV8(isolate, value, headers);
}
}
void ReadFromResponse(v8::Isolate* isolate,

View File

@@ -1232,12 +1232,10 @@ ElectronBrowserClient::GetPlatformNotificationService(
}
base::FilePath ElectronBrowserClient::GetDefaultDownloadDirectory() {
// ~/Downloads
base::FilePath path;
if (base::PathService::Get(base::DIR_HOME, &path))
path = path.Append(FILE_PATH_LITERAL("Downloads"));
return path;
base::FilePath download_path;
if (base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_path))
return download_path;
return base::FilePath();
}
scoped_refptr<network::SharedURLLoaderFactory>

View File

@@ -55,6 +55,7 @@ void BluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, "");
break;
case AdapterPresence::POWERED_ON:
rescan_ = true;
break;
}
}
@@ -87,7 +88,7 @@ void BluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
case DiscoveryState::DISCOVERING:
// The first time this state fires is due to a rescan triggering so set a
// flag to ignore devices
if (!refreshing_) {
if (rescan_ && !refreshing_) {
refreshing_ = true;
} else {
// The second time this state fires we are now safe to pick a device

View File

@@ -42,6 +42,7 @@ class BluetoothChooser : public content::BluetoothChooser {
EventHandler event_handler_;
int num_retries_ = 0;
bool refreshing_ = false;
bool rescan_ = false;
DISALLOW_COPY_AND_ASSIGN(BluetoothChooser);
};

View File

@@ -70,11 +70,15 @@ void LoginHandler::EmitEvent(
details.Set("firstAuthAttempt", first_auth_attempt);
details.Set("responseHeaders", response_headers.get());
auto weak_this = weak_factory_.GetWeakPtr();
bool default_prevented =
api_web_contents->Emit("login", std::move(details), auth_info,
base::BindOnce(&LoginHandler::CallbackFromJS,
weak_factory_.GetWeakPtr()));
if (!default_prevented && auth_required_callback_) {
// ⚠️ NB, if CallbackFromJS is called during Emit(), |this| will have been
// deleted. Check the weak ptr before accessing any member variables to
// prevent UAF.
if (weak_this && !default_prevented && auth_required_callback_) {
std::move(auth_required_callback_).Run(base::nullopt);
}
}

View File

@@ -203,6 +203,7 @@ class NativeWindow : public base::SupportsUserData,
// Traffic Light API
#if defined(OS_MAC)
virtual std::string GetAlwaysOnTopLevel() = 0;
virtual void SetTrafficLightPosition(const gfx::Point& position) = 0;
virtual gfx::Point GetTrafficLightPosition() const = 0;
virtual void RedrawTrafficLights() = 0;

View File

@@ -89,6 +89,7 @@ class NativeWindowMac : public NativeWindow,
void SetAlwaysOnTop(ui::ZOrderLevel z_order,
const std::string& level,
int relativeLevel) override;
std::string GetAlwaysOnTopLevel() override;
ui::ZOrderLevel GetZOrderLevel() override;
void Center() override;
void Invalidate() override;

View File

@@ -498,7 +498,7 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
// Use an NSEvent monitor to listen for the wheel event.
BOOL __block began = NO;
wheel_event_monitor_ = [NSEvent
addLocalMonitorForEventsMatchingMask:NSScrollWheelMask
addLocalMonitorForEventsMatchingMask:NSEventMaskScrollWheel
handler:^(NSEvent* event) {
if ([[event window] windowNumber] !=
[window_ windowNumber])
@@ -539,7 +539,10 @@ void NativeWindowMac::Cleanup() {
DCHECK(!IsClosed());
ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
display::Screen::GetScreen()->RemoveObserver(this);
[NSEvent removeMonitor:wheel_event_monitor_];
if (wheel_event_monitor_) {
[NSEvent removeMonitor:wheel_event_monitor_];
wheel_event_monitor_ = nil;
}
}
void NativeWindowMac::RedrawTrafficLights() {
@@ -706,6 +709,15 @@ void NativeWindowMac::Hide() {
return;
}
// Hide all children of the current window before hiding the window.
// components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
// expects this when window visibility changes.
if ([window_ childWindows]) {
for (NSWindow* child in [window_ childWindows]) {
[child orderOut:nil];
}
}
// Deattach the window from the parent before.
if (parent())
InternalSetParentWindow(parent(), false);
@@ -950,7 +962,7 @@ void NativeWindowMac::SetAspectRatio(double aspect_ratio,
// Reset the behaviour to default if aspect_ratio is set to 0 or less.
if (aspect_ratio > 0.0)
[window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
[window_ setContentAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
else
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
}
@@ -1046,6 +1058,31 @@ void NativeWindowMac::SetAlwaysOnTop(ui::ZOrderLevel z_order,
SetWindowLevel(level + relative_level);
}
std::string NativeWindowMac::GetAlwaysOnTopLevel() {
std::string level_name = "normal";
int level = [window_ level];
if (level == NSFloatingWindowLevel) {
level_name = "floating";
} else if (level == NSTornOffMenuWindowLevel) {
level_name = "torn-off-menu";
} else if (level == NSModalPanelWindowLevel) {
level_name = "modal-panel";
} else if (level == NSMainMenuWindowLevel) {
level_name = "main-menu";
} else if (level == NSStatusWindowLevel) {
level_name = "status";
} else if (level == NSPopUpMenuWindowLevel) {
level_name = "pop-up-menu";
} else if (level == NSScreenSaverWindowLevel) {
level_name = "screen-saver";
} else if (level == NSDockWindowLevel) {
level_name = "dock";
}
return level_name;
}
void NativeWindowMac::SetWindowLevel(int unbounded_level) {
int level = std::min(
std::max(unbounded_level, CGWindowLevelForKey(kCGMinimumWindowLevelKey)),
@@ -1747,8 +1784,6 @@ gfx::Rect NativeWindowMac::WindowBoundsToContentBounds(
}
void NativeWindowMac::SetActive(bool is_key) {
if (is_key)
widget()->Activate();
is_active_ = is_key;
}
@@ -1845,10 +1880,15 @@ void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
// Set new parent window.
// Note that this method will force the window to become visible.
if (parent && attach)
if (parent && attach) {
// Attaching a window as a child window resets its window level, so
// save and restore it afterwards.
NSInteger level = window_.level;
[parent->GetNativeWindow().GetNativeNSWindow()
addChildWindow:window_
ordered:NSWindowAbove];
[window_ setLevel:level];
}
}
void NativeWindowMac::SetForwardMouseMessages(bool forward) {

View File

@@ -14,6 +14,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/features.h"
@@ -305,6 +306,14 @@ void ProxyingURLLoaderFactory::InProgressRequest::OnComplete(
void ProxyingURLLoaderFactory::InProgressRequest::OnLoaderCreated(
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {
// When CORS is involved there may be multiple network::URLLoader associated
// with this InProgressRequest, because CorsURLLoader may create a new
// network::URLLoader for the same request id in redirect handling - see
// CorsURLLoader::FollowRedirect. In such a case the old network::URLLoader
// is going to be detached fairly soon, so we don't need to take care of it.
// We need this explicit reset to avoid a DCHECK failure in mojo::Receiver.
header_client_receiver_.reset();
header_client_receiver_.Bind(std::move(receiver));
if (for_cors_preflight_) {
// In this case we don't have |target_loader_| and
@@ -548,13 +557,17 @@ void ProxyingURLLoaderFactory::InProgressRequest::
override_headers_ = nullptr;
if (for_cors_preflight_) {
// If this is for CORS preflight, there is no associated client. We notify
// the completion here, and deletes |this|.
// If this is for CORS preflight, there is no associated client.
info_->AddResponseInfoFromResourceResponse(*current_response_);
// Do not finish proxied preflight requests that require proxy auth.
// The request is not finished yet, give control back to network service
// which will start authentication process.
if (info_->response_code == net::HTTP_PROXY_AUTHENTICATION_REQUIRED)
return;
// We notify the completion here, and delete |this|.
factory_->web_request_api()->OnResponseStarted(&info_.value(), request_);
factory_->web_request_api()->OnCompleted(&info_.value(), request_, net::OK);
// Deletes |this|.
factory_->RemoveRequest(network_service_request_id_, request_id_);
return;
}

View File

@@ -87,7 +87,7 @@ void URLPipeLoader::OnDataReceived(base::StringPiece string_piece,
producer_->Write(
std::make_unique<mojo::StringDataSource>(
string_piece, mojo::StringDataSource::AsyncWritingMode::
STRING_STAYS_VALID_UNTIL_COMPLETION),
STRING_MAY_BE_INVALIDATED_BEFORE_COMPLETION),
base::BindOnce(&URLPipeLoader::OnWrite, weak_factory_.GetWeakPtr(),
std::move(resume)));
}

View File

@@ -33,7 +33,7 @@ void CocoaNotification::Show(const NotificationOptions& options) {
NSString* identifier =
[NSString stringWithFormat:@"%@:notification:%@",
[[NSBundle mainBundle] bundleIdentifier],
[[[NSUUID alloc] init] UUIDString]];
[[NSUUID UUID] UUIDString]];
[notification_ setTitle:base::SysUTF16ToNSString(options.title)];
[notification_ setSubtitle:base::SysUTF16ToNSString(options.subtitle)];

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 12,0,11,0
PRODUCTVERSION 12,0,11,0
FILEVERSION 12,0,18,0
PRODUCTVERSION 12,0,18,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "12.0.11"
VALUE "FileVersion", "12.0.18"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "12.0.11"
VALUE "ProductVersion", "12.0.18"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -160,13 +160,12 @@
// Switch to new state.
devtools_docked_ = docked;
auto* inspectable_web_contents =
inspectableWebContentsView_->inspectable_web_contents();
auto* devToolsWebContents =
inspectable_web_contents->GetDevToolsWebContents();
auto devToolsView = devToolsWebContents->GetNativeView().GetNativeNSView();
if (!docked) {
auto* inspectable_web_contents =
inspectableWebContentsView_->inspectable_web_contents();
auto* devToolsWebContents =
inspectable_web_contents->GetDevToolsWebContents();
auto devToolsView = devToolsWebContents->GetNativeView().GetNativeNSView();
auto styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
NSMiniaturizableWindowMask | NSWindowStyleMaskResizable |
NSTexturedBackgroundWindowMask |
@@ -189,6 +188,9 @@
devToolsView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[contentView addSubview:devToolsView];
[devToolsView setMouseDownCanMoveWindow:NO];
} else {
[devToolsView setMouseDownCanMoveWindow:YES];
}
[self setDevToolsVisible:YES activate:activate];
}

View File

@@ -787,7 +787,10 @@ void InspectableWebContents::SearchInPath(int request_id,
void InspectableWebContents::SetWhitelistedShortcuts(
const std::string& message) {}
void InspectableWebContents::SetEyeDropperActive(bool active) {}
void InspectableWebContents::SetEyeDropperActive(bool active) {
if (delegate_)
delegate_->DevToolsSetEyeDropperActive(active);
}
void InspectableWebContents::ShowCertificateViewer(
const std::string& cert_chain) {}

View File

@@ -35,6 +35,7 @@ class InspectableWebContentsDelegate {
virtual void DevToolsSearchInPath(int request_id,
const std::string& file_system_path,
const std::string& query) {}
virtual void DevToolsSetEyeDropperActive(bool active) {}
};
} // namespace electron

View File

@@ -38,6 +38,13 @@ int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
bool can_ever_resize = frame_->widget_delegate()
? frame_->widget_delegate()->CanResize()
: false;
// https://github.com/electron/electron/issues/611
// If window isn't resizable, we should always return HTCLIENT, otherwise the
// hover state of DOM will not be cleared probably.
if (!can_ever_resize)
return HTCLIENT;
// Don't allow overlapping resize handles when the window is maximized or
// fullscreen, as it can't be resized in those states.
int resize_border = frame_->IsMaximized() || frame_->IsFullscreen()

View File

@@ -132,6 +132,10 @@ void InspectableWebContentsViewViews::ShowDevTools(bool activate) {
} else {
devtools_window_->ShowInactive();
}
// Update draggable regions to account for the new dock position.
if (GetDelegate())
GetDelegate()->DevToolsResized();
} else {
devtools_web_view_->SetVisible(true);
devtools_web_view_->SetWebContents(
@@ -232,6 +236,9 @@ void InspectableWebContentsViewViews::Layout() {
devtools_web_view_->SetBoundsRect(new_devtools_bounds);
contents_web_view_->SetBoundsRect(new_contents_bounds);
if (GetDelegate())
GetDelegate()->DevToolsResized();
}
} // namespace electron

View File

@@ -105,13 +105,18 @@ content::WebContents* WebViewGuestDelegate::CreateNewGuestWindow(
guest_params.context = embedder_web_contents_->GetNativeView();
std::unique_ptr<content::WebContents> guest_contents =
content::WebContents::Create(guest_params);
content::RenderWidgetHost* render_widget_host =
guest_contents->GetRenderViewHost()->GetWidget();
auto* guest_contents_impl =
static_cast<content::WebContentsImpl*>(guest_contents.release());
guest_contents_impl->GetView()->CreateViewForWidget(render_widget_host);
return guest_contents_impl;
if (!create_params.opener_suppressed) {
auto* guest_contents_impl =
static_cast<content::WebContentsImpl*>(guest_contents.release());
auto* new_guest_view = guest_contents_impl->GetView();
content::RenderWidgetHostView* widget_view =
new_guest_view->CreateViewForWidget(
guest_contents_impl->GetRenderViewHost()->GetWidget());
if (!create_params.initially_hidden)
widget_view->Show();
return guest_contents_impl;
}
return guest_contents.release();
}
} // namespace electron

View File

@@ -25,7 +25,6 @@ class WebViewManager : public content::BrowserPluginGuestManager {
static WebViewManager* GetWebViewManager(content::WebContents* web_contents);
protected:
// content::BrowserPluginGuestManager:
bool ForEachGuest(content::WebContents* embedder,
const GuestCallback& callback) override;

View File

@@ -107,7 +107,7 @@ bool IsSameOrigin(const GURL& l, const GURL& r) {
return url::Origin::Create(l).IsSameOriginWith(url::Origin::Create(r));
}
#ifdef DCHECK_IS_ON
#if DCHECK_IS_ON()
std::vector<v8::Global<v8::Value>> weakly_tracked_values;
void WeaklyTrackValue(v8::Isolate* isolate, v8::Local<v8::Value> value) {
@@ -157,7 +157,7 @@ void Initialize(v8::Local<v8::Object> exports,
dict.SetMethod("requestGarbageCollectionForTesting",
&RequestGarbageCollectionForTesting);
dict.SetMethod("isSameOrigin", &IsSameOrigin);
#ifdef DCHECK_IS_ON
#if DCHECK_IS_ON()
dict.SetMethod("triggerFatalErrorForTesting", &TriggerFatalErrorForTesting);
dict.SetMethod("getWeaklyTrackedValues", &GetWeaklyTrackedValues);
dict.SetMethod("clearWeaklyTrackedValues", &ClearWeaklyTrackedValues);

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