Compare commits

..

114 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
b36b2e3781 Bump v17.4.8 2022-06-20 06:39:47 -07:00
John Kleinschmidt
5646f87c03 build: make sure depot_tools is up to date (#34587)
* build: make sure depot_tools is up to date

* build: update_depot_tools when fixing up sync
2022-06-20 09:36:18 -04:00
trop[bot]
a14c789a4c fix: performance problem in crashReporter.start() on macOS (#34637)
* fix: performance problem in crashReporter.start() on macOS

This change reduces the duration of crashReporter.start() on Intel macOS
from 622 milliseconds to 257 milliseconds!

Backports https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3641386

  posix: Replace DoubleForkAndExec() with ForkAndSpawn()

  The DoubleForkAndExec() function was taking over 622 milliseconds to run
  on macOS 11 (BigSur) on Intel i5-1038NG7. I did some debugging by adding
  some custom traces and found that the fork() syscall is the bottleneck
  here, i.e., the first fork() takes around 359 milliseconds and the
  nested fork() takes around 263 milliseconds. Replacing the nested fork()
  and exec() with posix_spawn() reduces the time consumption to 257
  milliseconds!

  See https://github.com/libuv/libuv/pull/3064 to know why fork() is so
  slow on macOS and why posix_spawn() is a better replacement.

  Another point to note is that even base::LaunchProcess() from Chromium
  calls posix_spawnp() on macOS -
  8f8d82dea0:base/process/launch_mac.cc;l=295-296

  Change-Id: I25c6ee9629a1ae5d0c32b361b56a1ce0b4b0fd26
  Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3641386
  Reviewed-by: Mark Mentovai <mark@chromium.org>
  Commit-Queue: Mark Mentovai <mark@chromium.org>

Fixes: https://github.com/electron/electron/issues/34321
Signed-off-by: Darshan Sen <raisinten@gmail.com>

* Update .patches

* chore: update patches

* Update posix_replace_doubleforkandexec_with_forkandspawn.patch

* chore: update patches

Co-authored-by: Darshan Sen <raisinten@gmail.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-06-20 19:39:09 +09:00
Pedro Pontes
2e6ec46eae chore: cherry-pick b03797bdb1df from chromium (#34632)
* chore: cherry-pick b03797bdb1df from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-06-20 09:33:16 +09:00
Jeremy Rose
d91bcef773 chore: add ffmpeg patch dir to config.json (#34598)
* chore: add ffmpeg patch dir to config.json

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-06-16 17:14:07 -07:00
Jeremy Rose
02992b8ad7 chore: cherry-pick 919b1ffe1fe7 from chromium (#34557)
* chore: cherry-pick 919b1ffe1fe7 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-06-16 16:44:07 +09:00
trop[bot]
0f92cf21a8 test: add missing page-title-updated event spec for webview (#34542)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-06-16 09:42:55 +09:00
Sudowoodo Release Bot
25ed5f2d97 Revert "Bump v17.4.8"
This reverts commit b9400a8ab9.
2022-06-15 13:26:37 -07:00
Jeremy Rose
0fe1a95694 chore: cherry-pick 2782c7bc5bbe from chromium (#34570)
* chore: cherry-pick 2782c7bc5bbe from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-06-15 15:56:55 -04:00
Jeremy Rose
8fb011092a chore: cherry-pick 03aa5ae75c29 from angle (#34567)
* chore: cherry-pick 03aa5ae75c29 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-06-15 15:55:00 -04:00
Jeremy Rose
44fee2f8eb chore: cherry-pick e481fc655a62 from ffmpeg (#34559) 2022-06-15 15:48:35 -04:00
Sudowoodo Release Bot
b9400a8ab9 Bump v17.4.8 2022-06-15 12:40:59 -07:00
Sudowoodo Release Bot
a35a12228d Revert "Bump v17.4.8"
This reverts commit d6c1957d61.
2022-06-15 10:20:42 -07:00
Jeremy Rose
19c126ff6e chore: cherry-pick f1dd785e021e from chromium (#34561)
* chore: cherry-pick f1dd785e021e from chromium

* fix patch

Co-authored-by: Electron Bot <electron@github.com>
2022-06-15 12:53:01 -04:00
Pedro Pontes
9e5aec2f75 chore: cherry-pick f1504440487f from chromium (#34541)
* chore: cherry-pick f1504440487f from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-06-15 11:32:34 -04:00
Sudowoodo Release Bot
d6c1957d61 Bump v17.4.8 2022-06-15 08:31:19 -07:00
Jeremy Rose
65ce13ee56 chore: cherry-pick 801b904aea7d from angle (#34565)
* chore: cherry-pick 801b904aea7d from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-06-15 14:26:15 +09:00
Jeremy Rose
93e609dd58 chore: cherry-pick f3d01ff794dc from chromium (#34555)
* chore: cherry-pick f3d01ff794dc from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-06-15 11:28:22 +09:00
Jeremy Rose
a22683ed73 chore: cherry-pick 6661eb4900da from angle (#34553)
* chore: cherry-pick 6661eb4900da from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-06-15 11:27:58 +09:00
Jeremy Rose
86431323bb chore: cherry-pick 21139756239b from chromium (#34535)
* chore: cherry-pick 21139756239b from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-06-14 15:25:23 -04:00
Pedro Pontes
d15cc63aa4 chore: cherry-pick 9768648fffc9 from angle (#34538)
* chore: cherry-pick 9768648fffc9 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-06-14 12:32:42 -04:00
Sudowoodo Release Bot
66dd03293b Bump v17.4.7 2022-06-01 08:33:02 -07:00
trop[bot]
addd2440c1 fix: zombie windows when fullscreening and closing (#34390)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-05-31 15:36:53 +02:00
Sudowoodo Release Bot
3a1945bd6c Bump v17.4.6 2022-05-25 08:32:53 -07:00
trop[bot]
75290948ac chore: add a TRACE call for crash_reporter::Start() (#34324)
chore: add a TRACE call for crash_reporter::Start()

Initializing the crashReporter takes around 620 milliseconds on Intel
macOS. I have sent a CL to crashpad to partially fix the performance
issue in
https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3641386.
It would be beneficial to log the performance impact of this function in
the traces in case this slows down in the future.

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

Co-authored-by: Darshan Sen <raisinten@gmail.com>
2022-05-24 10:21:46 +02:00
John Kleinschmidt
9bb03e9e03 fix: crash on navigator.serial.getPorts() (#34328)
(cherry picked from commit 7f9431764f)
(cherry picked from commit 1b5738e308)
2022-05-23 15:11:13 -04:00
trop[bot]
d585bf3250 fix: delayed bounds when moving/resizing and preventing default (#34283)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-05-19 13:57:16 +02:00
Sudowoodo Release Bot
fb3abffd16 Bump v17.4.5 2022-05-18 08:35:00 -07:00
Darshan Sen
2a04149140 fix: crash in safeStorage on Linux (#34261)
* fix: fix a crash in `safeStorage` on Linux (#33913)

On Linux, `isEncryptionAvailable()` was crashing instead of returning a
boolean before the 'ready' event was emitted by the app. The reason of
the crash is that [`CreateKeyStorage()`](https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=74;drc=35be6215ec8f09e50176f36753c68f26c63d1885;bpv=1;bpt=0)
expects the config to be set but the function responsible for setting the
config, [`SetConfig()`](https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=237;drc=35be6215ec8f09e50176f36753c68f26c63d1885;bpv=1;bpt=0),
is called only after the app is ready inside [`PostCreateMainMessageLoop()`](https://github.com/electron/electron/blob/main/shell/browser/electron_browser_main_parts.cc#L499).
So this changes `IsEncryptionAvailable()` to return `false` when the app
is not ready on Linux and uses that instead of the raw API in other
places like `EncryptString()` and `DecryptString()`.

Fixes: https://github.com/electron/electron/issues/32206
Signed-off-by: Darshan Sen <raisinten@gmail.com>

* fix: replace BUILDFLAG(IS_LINUX) with defined(OS_LINUX)

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

* Linux: Send OSCrypt raw encryption key to the Network Service

This backports 0e09738b18.

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

* fix: add ifdef guard around NetworkService::SetEncryptionKey()

network::mojom::NetworkService::SetEncryptionKey() is only available on
Windows and macOS.

Signed-off-by: Darshan Sen <raisinten@gmail.com>
2022-05-18 10:33:44 -04:00
trop[bot]
b384447377 fix: crash when loading extension with missing manifest (#34193) 2022-05-18 12:20:32 +02:00
Pedro Pontes
160afc8d19 chore: cherry-pick 2941a90229 from chromium (#34228)
* chore: cherry-pick 2941a90229 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-05-17 15:13:27 -04:00
Pedro Pontes
eb4ce2a84e chore: cherry-pick 14e51893e5b5 from icu (#34222)
* chore: cherry-pick 14e51893e5b5 from icu

* chore: fixup patch for lint

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-17 11:31:43 -04:00
trop[bot]
5dc084c428 docs: add missing explanation for [angle|dawn]_enable_vulkan_validation_layers = false (#34256)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-17 11:18:25 -04:00
Pedro Pontes
52c019c3c7 chore: cherry-pick ec0cce63f47d from chromium (#34232)
* chore: cherry-pick ec0cce63f47d from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-05-16 18:18:55 -04:00
Pedro Pontes
c1cb799e5e chore: cherry-pick 723ed8a9cfff from v8 (#34203)
* chore: cherry-pick 723ed8a9cfff from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-16 16:08:45 -04:00
Pedro Pontes
7118979852 chore: cherry-pick a4f71e40e571 from angle (#34229)
* chore: cherry-pick a4f71e40e571 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-16 14:59:29 -04:00
Darshan Sen
22d81d3054 docs: note safeStorage.isEncryptionAvailable() needs ready event (#34218)
docs: note safeStorage.isEncryptionAvailable() needs ready event (#33724)

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-05-16 12:12:33 -04:00
Pedro Pontes
bd3e9aa527 chore: cherry-pick 99c3f3bfd507 from chromium (#34225)
* chore: cherry-pick 99c3f3bfd507 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-16 12:11:30 -04:00
trop[bot]
7bae935a0d test: fixup done being called multiple times (#34187)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-12 20:22:05 -04:00
Pedro Pontes
bcca5c5bd8 chore: cherry-pick a602a068e022 from angle (#34199)
* chore: cherry-pick a602a068e022 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-12 20:20:07 -04:00
trop[bot]
305d26ce1f fix: tray icon not highlighting on empty menu (#34206)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-05-12 16:20:18 -07:00
Samuel Attard
fe864864ae fix: disable SIGUSR1 when --inspect is disabled (#34181)
* fix: disable SIGUSR1 when --inspect is disabled (#33188)

* Update .patches
2022-05-11 12:38:27 -07:00
Sudowoodo Release Bot
085a15fd95 Bump v17.4.4 2022-05-11 08:32:29 -07:00
trop[bot]
b3281b4f97 build: change upload-to-s3 vars to upload-to-storage (#34144)
* build: change upload-to-s3 vars to upload-to-az

* build: change upload-to-az to upload-to-storage

* build: change linux-ia32-publish var

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-05-11 10:00:06 -04:00
Robo
16b78a4eff chore: backport a536de469 from nod (#34136) 2022-05-10 17:26:19 -07:00
trop[bot]
95277d1580 build: use azure function to hash assets instead of lambda (#34121)
* build: use azure function to hash assets instead of lambda

* chore: empty commit to trigger CI

Co-authored-by: Samuel Attard <sattard@salesforce.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-05-08 09:30:15 -07:00
trop[bot]
f97264499b build: stop uploading assets to S3 (#34115)
* build: remove S3 uploads

* build: remove ending slash upload-index-json (#34125)

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2022-05-06 23:49:39 -07:00
trop[bot]
25b9c1c35e refactor: prevent RemoveFromLoginItems() from mounting volumes from login items (#34107)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-05-05 21:17:27 -07:00
Pedro Pontes
23f6aecf38 chore: cherry-pick d49484c21e3c from angle (#34012)
* chore: cherry-pick d49484c21e3c from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-05 22:29:13 -04:00
trop[bot]
f72cf8c2f5 test: unflake some more tests (#34101)
* test: unflake webview fullscreen test

* test: unflake net throttle test

* Update spec-main/api-net-spec.ts

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: Samuel Attard <sattard@salesforce.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-05-05 21:18:02 -04:00
Pedro Pontes
36f4b59c04 chore: cherry-pick 6b66a45021 from chromium (#34073)
Co-authored-by: Electron Bot <electron@github.com>
2022-05-05 21:04:02 -04:00
trop[bot]
b653897e0f fix: offscreen rendering crash on input select (#34091)
* fix: offscreen rendering crash on input select

* Trigger Build

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-05 13:39:19 -07:00
Sudowoodo Release Bot
322f1c3f89 Bump v17.4.3 2022-05-05 13:32:29 -07:00
Keeley Hammond
3b0832275e build: use large executors for macos publish on 12.4.0 (#34096) 2022-05-05 13:29:32 -07:00
Pedro Pontes
009263c240 chore: cherry-pick cf64617c1cc5 from chromium (#34053) 2022-05-05 11:55:08 -07:00
Pedro Pontes
70aa51cb44 chore: cherry-pick d27d9d059b51 from angle (#34043)
* chore: cherry-pick d27d9d059b51 from angle

* chore: update patches

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-05 09:57:09 -04:00
Pedro Pontes
0a97730080 chore: cherry-pick 5ff02e4d7368 from chromium (#34017)
* chore: cherry-pick 5ff02e4d7368 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-05-05 09:56:46 -04:00
trop[bot]
9b5df7f95c test: unflake some focus tests (#34082)
* spec: unflake some focus tests

* test: disable flaky webFrame visibiilty spec

Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-05-05 09:39:17 -04:00
Pedro Pontes
d8194ea6fd chore: cherry-pick 5361d836aeb1 from chromium (#34007) 2022-05-04 16:43:07 -07:00
Sudowoodo Release Bot
e306e8cd0d Revert "Bump v17.4.3"
This reverts commit 478c25c39d.
2022-05-04 11:52:31 -07:00
Sudowoodo Release Bot
478c25c39d Bump v17.4.3 2022-05-04 08:35:37 -07:00
Pedro Pontes
ca680a14b6 chore: cherry-pick 5be8e065f43e from chromium (#34038)
* chore: cherry-pick 5be8e065f43e from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-05-04 16:30:10 +02:00
trop[bot]
eaf8f6776f test: fix nativeModulesEnabled in spec/webview-spec.js (#34064)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-04 16:28:30 +02:00
trop[bot]
da40d1e7db fix: make BrowserWindow#isFocused() return false when blur() is called on macOS (#34029)
The isFocused() method on macOS works by checking if the selected
BrowserWindow is a key window. Unfortunately, this didn't work well
with blur() because it wasn't calling any macOS APIs that would change
the key status of the window. Hence, this changes the implementation of
blur() to call orderOut first, which removes the key
status of the window. Then when the orderBack function is called, it
moves the window to the back of its level in the screen list, without
changing the key window.

Fixes: https://github.com/electron/electron/issues/33732
Signed-off-by: Darshan Sen <raisinten@gmail.com>

Co-authored-by: Darshan Sen <raisinten@gmail.com>
2022-05-04 00:05:29 -07:00
trop[bot]
252f9cbd50 test: scope internal test fixtures under @electron-ci (#34023)
* test: scope internal test fixtures under `@electron`

* Missed references

* Move packages from @electron to @electron-ci scope

* Fix tests

* fix require

Co-authored-by: Jamie Magee <jamie.magee@gmail.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-03 23:57:01 -07:00
Pedro Pontes
5a91ea8cdb chore: cherry-pick 12ba78f3fa7a from chromium (#34049)
* chore: cherry-pick 12ba78f3fa7a from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-03 16:17:57 -07:00
Pedro Pontes
c460c53c10 chore: cherry-pick d24570fb65 from angle (#34035)
* chore: cherry-pick d24570fb65 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-03 16:16:15 -07:00
Samuel Attard
f7367f0312 build: use smaller resource_class because goma (#33905) (#34033) (#34057) 2022-05-03 16:14:04 -07:00
Keeley Hammond
75ba569e73 build: improve CI speeds and reduce CI costs (#33904) (#33953)
* build: improve CI speeds and reduce CI costs (#33904)

* remove third_party/electron_node:overlapped-checker

target isn't present in older versions

* build: use original arch logic

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-05-02 12:51:05 -04:00
trop[bot]
044399047a build: allow script/spec-runner.js with empty list of runners (#34001)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-02 09:46:19 -04:00
trop[bot]
ecf9633370 spec: allow connections to port 2049 (#33991)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-02 14:47:36 +09:00
Samuel Attard
d6aea2703e build: use dev-cdn instead of sysroots s3 bucket (#33985)
* build: use dev-cdn instead of sysroots s3 bucket (#33922)

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-02 10:31:20 +09:00
Sudowoodo Release Bot
88e44b0d7e Bump v17.4.2 2022-04-29 06:38:36 -07:00
Pedro Pontes
5b4acf406c chore: cherry-pick ac341df436 from webrtc (#33671)
Co-authored-by: Electron Bot <electron@github.com>
2022-04-28 10:26:57 -04:00
Pedro Pontes
af7d3b7171 chore: cherry-pick 57bdd90d8c from chromium (#33886) 2022-04-28 11:52:08 +09:00
trop[bot]
d10adccf3f build: ensure sync-done file exists during git cache save (#33957)
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-04-27 18:25:55 -07:00
Pedro Pontes
26e74b355b chore: cherry-pick 2004594a46c8 from v8 (#33882)
* chore: cherry-pick 2004594a46c8 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-27 16:41:00 -04:00
Pedro Pontes
5463996d00 chore: cherry-pick d88e959e01 from chromium (#33850)
* chore: cherry-pick d88e959e01 from chromium

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-27 16:40:04 -04:00
Samuel Attard
93e6cbb60b build: upload to AZ as well as S3 (#33925)
* build: upload to AZ as well as S3

* build: actually verify az urls too
2022-04-27 10:52:31 -07:00
Samuel Attard
9d02e5d4fd build: improve circleci config (#33943)
* build: improve circleci config (#33881)

* build: fix conditional restore of git cache

* build: split lint out of setup.yml

* ci: update release script to handle new CircleCI configs (#33914)

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-04-27 10:13:09 -07:00
Sudowoodo Release Bot
7f002fe3a3 Revert "Bump v17.4.2"
This reverts commit cc77aba367.
2022-04-27 09:33:57 -07:00
Sudowoodo Release Bot
cc77aba367 Bump v17.4.2 2022-04-27 08:33:17 -07:00
trop[bot]
7d46fb5d40 chore: use semantic-commit-action (#33865)
* chore: use semantic-commit-action

* Update semantic.yml

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-04-26 19:06:43 +09:00
Pedro Pontes
14e85ae55d chore: cherry-pick e42dbcdedb7a from v8 (#33829)
* chore: cherry-pick e42dbcdedb7a from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-25 09:43:44 +09:00
Pedro Pontes
cb8925c454 chore: cherry-pick 1a31e2110440 from chromium (#33854)
* chore: cherry-pick 1a31e2110440 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-25 09:36:47 +09:00
trop[bot]
032c0a1416 build: fix intermittent compilation failures on macOS (#33877)
* build: fix intermittent compilation failures on macOS

* chore: remove //base dependency from main executable

* chore: fix lint

* build: add missing #include "base/compiler_specific.h"

Co-authored-by: Milan Burda <milan.burda@gmail.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-04-22 21:17:59 -04:00
trop[bot]
27009989fe chore: backport 7c9b3938d from libuv (#33870)
* chore: backport 7c9b3938d from libuv

Backports https://github.com/libuv/libuv/pull/3597

* Update .patches

* chore: update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-21 03:13:43 -07:00
Pedro Pontes
cf1d2103b8 chore: cherry-pick 5cb934a23ddf from chromium (#33858)
* chore: cherry-pick 5cb934a23ddf from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-21 17:24:12 +09:00
Pedro Pontes
3eb78b89e3 chore: cherry-pick b2d3ef69ef99 from v8 (#33834)
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-04-20 13:51:04 -07:00
Milan Burda
a8a5c44b3e fix: building with printing disabled (#33838) 2022-04-20 13:50:45 -07:00
Sudowoodo Release Bot
73c87bcfc6 Bump v17.4.1 2022-04-20 08:31:55 -07:00
Pedro Pontes
39ff8744ea chore: cherry-pick a1dc371d6680 from chromium (#33677)
* chore: cherry-pick a1dc371d6680 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-14 19:17:06 +09:00
Pedro Pontes
2bbc560e22 chore: cherry-pick f546ac11eec7 from v8 (#33761)
* chore: cherry-pick f546ac11eec7 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-14 16:29:04 +09:00
trop[bot]
590711fdd8 fix: apply senderFrame details to ipcMain port event (#33781)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-04-14 16:25:19 +09:00
trop[bot]
14baae0436 chore: interpret bytes to string (#33776)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-04-13 21:50:31 -07:00
Pedro Pontes
76c6e64d18 chore: cherry-pick 1665a1d16d46 from chromium (#33680)
* chore: cherry-pick 1665a1d16d46 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-13 19:10:46 +02:00
Pedro Pontes
a09db1f6fe chore: cherry-pick 652dd12a85 from chromium (#33668)
Co-authored-by: Electron Bot <electron@github.com>
2022-04-13 10:46:25 +02:00
trop[bot]
66ac88bc82 build: migrate urllib to python3 (#33743)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-04-12 22:00:02 -07:00
trop[bot]
6654e37197 build: explicitly run scripts with python3 (#33727)
* build: explicitly run scripts with python3

* chore: update patches

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-12 20:22:00 -07:00
trop[bot]
ff50d30a42 build: use python3 to lint (#33717)
* build: use python3 to lint

* also run-gn-format

* specify encoding

* remove some outdated python2 info from docs

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2022-04-12 12:42:34 -07:00
trop[bot]
609f2d5e64 docs: recommend setting e.returnValue (#33644)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-04-12 12:08:57 +02:00
Pedro Pontes
9716ae5a35 chore: cherry-pick 4d26949260aa from chromium (#33674)
* chore: cherry-pick 4d26949260aa from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-12 11:04:37 +02:00
Jeremy Rose
7d79120dac chore: cherry-pick a18fddcb53e6 from webrtc (#33709)
* chore: cherry-pick a18fddcb53e6 from webrtc

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-12 11:03:37 +02:00
trop[bot]
ee521475e3 fix: report more detailed errors in shell.openExternal() on Windows (#33658)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-04-11 08:52:45 -07:00
David Sanders
3c6be55e13 fix: on macOS show BrowserWindow on maximize if not currently shown (#33536) 2022-04-06 17:14:12 -04:00
Sudowoodo Release Bot
0b031afcef Bump v17.4.0 2022-04-05 11:31:48 -07:00
trop[bot]
3a61e4ce16 Revert "fix: some frameless windows showing a frame on Windows (#32692)" (#33611)
This reverts commit 7c701367c0.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2022-04-05 11:30:02 -07:00
Jeremy Rose
f4fc41b877 chore: cherry-pick 36b66b5cc991 from v8 (#33613) 2022-04-05 09:42:31 -07:00
Robo
bd1e0176f5 chore: cherry-pick be623b0f from chromium (#33618)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/3488608
2022-04-05 12:28:46 -04:00
trop[bot]
16b72c0315 fix: getting focused window with destroyed webContents (#33539)
* fix: getting focused window with destroyed webContents

* fix: add extra safeguards

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-04-05 11:25:50 -05:00
Shelley Vohr
e9f673f322 fix: pend bounds change when moving BrowserWindows (#33543)
* fix: ensure bounds changes apply when moving windows

* chore: remove unused queue include
2022-04-04 10:47:56 +02:00
trop[bot]
e78bfc119c fix: don't unmaximize on macOS if user set max bounds (#33551)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-04-04 17:32:47 +09:00
trop[bot]
1b4eeda7eb fix: create userData on requestSingleInstanceLock() if needed (#33559) (#33591)
* test: use custom userData folder for requestSingleInstanceLock()

* update test

* prefix test folder path

* fix: create userDataDir on requestSingleInstanceLock() if needed

* Trigger Build

Co-authored-by: Micha Hanselmann <micha.hanselmann@gmail.com>
2022-04-04 17:31:07 +09:00
trop[bot]
90c299f3ad feat: add WCO title bar style setters (#33439)
* feat: add wco title bar style setters

* return after throwing

* use def checks instead of build flags

Co-authored-by: clavin <clavin@electronjs.org>
2022-03-30 19:03:38 -04:00
177 changed files with 8787 additions and 830 deletions

1
.circleci/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
config-staging

View File

@@ -6,6 +6,7 @@ setup: true
# Orbs
orbs:
path-filtering: circleci/path-filtering@0.1.0
continuation: circleci/continuation@0.2.0
# All input parameters to pass to build config
parameters:
@@ -13,7 +14,7 @@ parameters:
type: boolean
default: false
upload-to-s3:
upload-to-storage:
type: string
default: '1'
@@ -43,103 +44,33 @@ parameters:
default: all
enum: ["all", "osx-x64", "osx-arm64", "mas-x64", "mas-arm64"]
# Envs
env-global: &env-global
ELECTRON_OUT_DIR: Default
env-linux-medium: &env-linux-medium
<<: *env-global
NUMBER_OF_NINJA_PROCESSES: 3
# Executors
executors:
linux-docker:
parameters:
size:
description: "Docker executor size"
default: 2xlarge+
type: enum
enum: ["medium", "xlarge", "2xlarge+"]
docker:
- image: ghcr.io/electron/build:27db4a3e3512bfd2e47f58cea69922da0835f1d9
resource_class: << parameters.size >>
# List of always run steps
step-checkout-electron: &step-checkout-electron
checkout:
path: src/electron
steps-lint: &steps-lint
steps:
- *step-checkout-electron
- run:
name: Setup third_party Depot Tools
command: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
- run:
name: Download GN Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . \<<-CIPD
\$ServiceURL https://chrome-infra-packages.appspot.com/
@Subdir src/buildtools/linux64
gn/gn/linux-amd64 $gn_version
CIPD
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
- run:
name: Download clang-format Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
sha1_path='buildtools/linux64/clang-format.sha1'
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/${sha1_path}?format=TEXT" | base64 -d > "src/${sha1_path}"
download_from_google_storage.py --no_resume --no_auth --bucket chromium-clang-format -s "src/${sha1_path}"
- run:
name: Run Lint
command: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
# Another option would be to checkout "buildtools" inside the Electron checkout,
# but then we would lint its contents (at least gn format), and it doesn't pass it.
cd src/electron
node script/yarn install --frozen-lockfile
node script/yarn lint
- run:
name: Run Script Typechecker
command: |
cd src/electron
node script/yarn tsc -p tsconfig.script.json
# List of always run jobs.
jobs:
lint:
executor:
name: linux-docker
size: medium
environment:
<<: *env-linux-medium
<<: *steps-lint
# Initial setup workflow
workflows:
lint:
jobs:
# Job inherited from path-filtering orb
- path-filtering/filter:
generate-config:
docker:
- image: cimg/node:16.14
steps:
- checkout
- path-filtering/set-parameters:
base-revision: main
# Params for mapping; `path-to-test parameter-to-set value-for-parameter` for each row
mapping: |
^((?!docs/).)*$ run-build-mac true
^((?!docs/).)*$ run-build-linux true
docs/.* run-docs-only true
^((?!docs/).)*$ run-docs-only false
config-path: .circleci/build_config.yml
- lint
- run:
command: |
cd .circleci/config
yarn
export CIRCLECI_BINARY="$HOME/circleci"
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | DESTDIR=$CIRCLECI_BINARY bash
node build.js
name: Pack config.yml
- continuation/continue:
configuration_path: .circleci/config-staging/built.yml
parameters: /tmp/pipeline-parameters.json
# Initial setup workflow
workflows:
setup:
jobs:
- generate-config

File diff suppressed because it is too large Load Diff

34
.circleci/config/build.js Normal file
View File

@@ -0,0 +1,34 @@
const cp = require('child_process');
const fs = require('fs-extra');
const path = require('path');
const yaml = require('js-yaml');
const STAGING_DIR = path.resolve(__dirname, '..', 'config-staging');
function copyAndExpand(dir = './') {
const absDir = path.resolve(__dirname, dir);
const targetDir = path.resolve(STAGING_DIR, dir);
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir);
}
for (const file of fs.readdirSync(absDir)) {
if (!file.endsWith('.yml')) {
if (fs.statSync(path.resolve(absDir, file)).isDirectory()) {
copyAndExpand(path.join(dir, file));
}
continue;
}
fs.writeFileSync(path.resolve(targetDir, file), yaml.dump(yaml.load(fs.readFileSync(path.resolve(absDir, file), 'utf8')), {
noRefs: true,
}));
}
}
if (fs.pathExists(STAGING_DIR)) fs.removeSync(STAGING_DIR);
copyAndExpand();
const output = cp.spawnSync(process.env.CIRCLECI_BINARY || 'circleci', ['config', 'pack', STAGING_DIR]);
fs.writeFileSync(path.resolve(STAGING_DIR, 'built.yml'), output.stdout.toString());

View File

@@ -0,0 +1,51 @@
executor:
name: linux-docker
size: medium
steps:
- checkout:
path: src/electron
- run:
name: Setup third_party Depot Tools
command: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
- run:
name: Download GN Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . \<<-CIPD
\$ServiceURL https://chrome-infra-packages.appspot.com/
@Subdir src/buildtools/linux64
gn/gn/linux-amd64 $gn_version
CIPD
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
- run:
name: Download clang-format Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
sha1_path='buildtools/linux64/clang-format.sha1'
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/${sha1_path}?format=TEXT" | base64 -d > "src/${sha1_path}"
download_from_google_storage.py --no_resume --no_auth --bucket chromium-clang-format -s "src/${sha1_path}"
- run:
name: Run Lint
command: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
# Another option would be to checkout "buildtools" inside the Electron checkout,
# but then we would lint its contents (at least gn format), and it doesn't pass it.
cd src/electron
node script/yarn install --frozen-lockfile
node script/yarn lint
- run:
name: Run Script Typechecker
command: |
cd src/electron
node script/yarn tsc -p tsconfig.script.json

View File

@@ -0,0 +1,10 @@
{
"name": "@electron/circleci-config",
"version": "0.0.0",
"private": true,
"license": "MIT",
"dependencies": {
"fs-extra": "^10.1.0",
"js-yaml": "^4.1.0"
}
}

View File

@@ -0,0 +1,43 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
fs-extra@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
dependencies:
universalify "^2.0.0"
optionalDependencies:
graceful-fs "^4.1.6"
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==

20
.github/workflows/semantic.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: "Check Semantic Commit"
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
main:
name: Validate PR Title
runs-on: ubuntu-latest
steps:
- name: semantic-pull-request
uses: amannn/action-semantic-pull-request@v4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
validateSingleCommit: false

View File

@@ -1047,7 +1047,6 @@ if (is_mac) {
"shell/app/electron_main_mac.cc",
"shell/app/uv_stdio_fix.cc",
"shell/app/uv_stdio_fix.h",
"shell/common/electron_constants.cc",
]
include_dirs = [ "." ]
deps = [
@@ -1264,6 +1263,10 @@ if (is_mac) {
if (!is_component_build && is_component_ffmpeg) {
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
}
if (is_linux) {
deps += [ "//sandbox/linux:chrome_sandbox" ]
}
}
}

View File

@@ -1 +1 @@
17.3.1
17.4.8

View File

@@ -11,7 +11,7 @@
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64', 'mips64el'}.
# Is used in some publishing scripts, but does NOT affect the Electron binary.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
# - "UPLOAD_TO_S3" Set it to '1' upload a release to the S3 bucket.
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
# Otherwise the release will be uploaded to the Github Releases.
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
#
@@ -231,9 +231,9 @@ deploy_script:
- cd electron
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_S3) {
Write-Output "Uploading Electron release distribution to s3"
& python script\release\uploaders\upload.py --verbose --upload_to_s3
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
Write-Output "Uploading Electron release distribution to azure"
& python script\release\uploaders\upload.py --verbose --upload_to_storage
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py --verbose

View File

@@ -19,6 +19,9 @@ proprietary_codecs = true
ffmpeg_branding = "Chrome"
enable_basic_printing = true
# Removes DLLs from the build, which are only meant to be used for Chromium development.
# See https://github.com/electron/electron/pull/17985
angle_enable_vulkan_validation_layers = false
dawn_enable_vulkan_validation_layers = false

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import os
import subprocess

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os
import subprocess

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import os
import subprocess
import sys

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os
import subprocess

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os
import subprocess

View File

@@ -457,7 +457,7 @@ window.onbeforeunload = (e) => {
// a non-void value will silently cancel the close.
// It is recommended to use the dialog API to let the user confirm closing the
// application.
e.returnValue = false // equivalent to `return false` but not recommended
e.returnValue = false
}
```
@@ -1811,6 +1811,16 @@ with `addBrowserView` or `setBrowserView`.
**Note:** The BrowserView API is currently experimental and may change or be
removed in future Electron releases.
#### `win.setTitleBarOverlay(options)` _Windows_
* `options` Object
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled.
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled.
* `height` Integer (optional) _Windows_ - The height of the title bar and Window Controls Overlay in pixels.
On a Window with Window Controls Overlay already enabled, this method updates
the style of the title bar overlay.
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
[page-visibility-api]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look

View File

@@ -18,9 +18,9 @@ The `safeStorage` module has the following methods:
Returns `boolean` - Whether encryption is available.
On Linux, returns true if the secret key is
available. On MacOS, returns true if Keychain is available.
On Windows, returns true with no other preconditions.
On Linux, returns true if the app has emitted the `ready` event and the secret key is available.
On MacOS, returns true if Keychain is available.
On Windows, returns true once the app has emitted the `ready` event.
### `safeStorage.encryptString(plainText)`

View File

@@ -7,21 +7,7 @@ Follow the guidelines below for building **Electron itself** on Linux, for the p
## Prerequisites
* At least 25GB disk space and 8GB RAM.
* Python 2.7.x. Some distributions like CentOS 6.x still use Python 2.6.x
so you may need to check your Python version with `python -V`.
Please also ensure that your system and Python version support at least TLS 1.2.
For a quick test, run the following script:
```sh
$ npx @electron/check-python-tls
```
If the script returns that your configuration is using an outdated security
protocol, use your system's package manager to update Python to the latest
version in the 2.7.x branch. Alternatively, visit https://www.python.org/downloads/
for detailed instructions.
* Python >= 3.7.
* Node.js. There are various ways to install Node. You can download
source code from [nodejs.org](https://nodejs.org) and compile it.
Doing so permits installing Node on your own home directory as a standard user.

View File

@@ -6,45 +6,12 @@ Follow the guidelines below for building **Electron itself** on macOS, for the p
## Prerequisites
* macOS >= 10.11.6
* [Xcode](https://developer.apple.com/technologies/tools/) >= 9.0.0
* macOS >= 11.6.0
* [Xcode](https://developer.apple.com/technologies/tools/). The exact version
needed depends on what branch you are building, but the latest version of
Xcode is generally a good bet for building `main`.
* [node.js](https://nodejs.org) (external)
* Python 2.7 with support for TLS 1.2
## Python
Please also ensure that your system and Python version support at least TLS 1.2.
This depends on both your version of macOS and Python. For a quick test, run:
```sh
$ npx @electron/check-python-tls
```
If the script returns that your configuration is using an outdated security
protocol, you can either update macOS to High Sierra or install a new version
of Python 2.7.x. To upgrade Python, use [Homebrew](https://brew.sh/):
```sh
$ brew install python@2 && brew link python@2 --force
```
If you are using Python as provided by Homebrew, you also need to install
the following Python modules:
* [pyobjc](https://pypi.org/project/pyobjc/#description)
You can use `pip` to install it:
```sh
$ pip install pyobjc
```
## macOS SDK
If you're developing Electron and don't plan to redistribute your
custom Electron build, you may skip this section.
Official Electron builds are built with [Xcode 12.2](https://download.developer.apple.com/Developer_Tools/Xcode_12.2/Xcode_12.2.xip), and the macOS 11.0 SDK. Building with a newer SDK works too, but the releases currently use the 11.0 SDK.
* Python >= 3.7
## Building Electron

View File

@@ -28,7 +28,7 @@ For C++ and Python, we follow Chromium's [Coding
Style](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/styleguide.md).
There is also a script `script/cpplint.py` to check whether all files conform.
The Python version we are using now is Python 2.7.
The Python version we are using now is Python 3.9.
The C++ code uses a lot of Chromium's abstractions and types, so it's
recommended to get acquainted with them. A good place to start is

View File

@@ -177,6 +177,7 @@ template("electron_paks") {
"${root_gen_dir}/components/strings/components_strings_",
"${root_gen_dir}/third_party/blink/public/strings/blink_strings_",
"${root_gen_dir}/device/bluetooth/strings/bluetooth_strings_",
"${root_gen_dir}/extensions/strings/extensions_strings_",
"${root_gen_dir}/services/strings/services_strings_",
"${root_gen_dir}/ui/strings/app_locale_settings_",
"${root_gen_dir}/ui/strings/ax_strings_",
@@ -186,6 +187,7 @@ template("electron_paks") {
"//chrome/app/resources:platform_locale_settings",
"//components/strings:components_strings",
"//device/bluetooth/strings",
"//extensions/strings",
"//services/strings",
"//third_party/blink/public/strings",
"//ui/strings:app_locale_settings",

View File

@@ -72,7 +72,10 @@ BrowserWindow.getAllWindows = () => {
BrowserWindow.getFocusedWindow = () => {
for (const window of BrowserWindow.getAllWindows()) {
if (window.isFocused() || window.isDevToolsFocused()) return window;
const hasWC = window.webContents && !window.webContents.isDestroyed();
if (!window.isDestroyed() && hasWC) {
if (window.isFocused() || window.isDevToolsFocused()) return window;
}
}
return null;
};

View File

@@ -613,6 +613,7 @@ WebContents.prototype._init = function () {
});
this.on('-ipc-ports' as any, function (event: Electron.IpcMainEvent, internal: boolean, channel: string, message: any, ports: any[]) {
addSenderFrameToEvent(event);
event.ports = ports.map(p => new MessagePortMain(p));
ipcMain.emit(channel, event, message);
});

View File

@@ -1,9 +1,10 @@
{
"name": "electron",
"version": "17.3.1",
"version": "17.4.8",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@electron/docs-parser": "^0.12.3",
"@electron/typescript-definitions": "^8.9.5",
"@octokit/auth-app": "^2.10.0",
@@ -78,14 +79,14 @@
"generate-version-json": "node script/generate-version-json.js",
"lint": "node ./script/lint.js && npm run lint:clang-format && npm run lint:docs",
"lint:js": "node ./script/lint.js --js",
"lint:clang-format": "python script/run-clang-format.py -r -c shell/ || (echo \"\\nCode not formatted correctly.\" && exit 1)",
"lint:clang-format": "python3 script/run-clang-format.py -r -c shell/ || (echo \"\\nCode not formatted correctly.\" && exit 1)",
"lint:clang-tidy": "ts-node ./script/run-clang-tidy.ts",
"lint:cpp": "node ./script/lint.js --cc",
"lint:objc": "node ./script/lint.js --objc",
"lint:py": "node ./script/lint.js --py",
"lint:gn": "node ./script/lint.js --gn",
"lint:docs": "remark docs -qf && npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:docs-relative-links && npm run lint:markdownlint",
"lint:docs-relative-links": "python ./script/check-relative-doc-links.py",
"lint:docs-relative-links": "python3 ./script/check-relative-doc-links.py",
"lint:markdownlint": "markdownlint \"*.md\" \"docs/**/*.md\"",
"lint:js-in-markdown": "standard-markdown docs",
"create-api-json": "electron-docs-parser --dir=./",
@@ -116,14 +117,14 @@
"ts-node script/gen-filenames.ts"
],
"*.{cc,mm,c,h}": [
"python script/run-clang-format.py -r -c --fix"
"python3 script/run-clang-format.py -r -c --fix"
],
"*.md": [
"npm run lint:docs"
],
"*.{gn,gni}": [
"npm run gn-check",
"python script/run-gn-format.py"
"python3 script/run-gn-format.py"
],
"*.py": [
"node script/lint.js --py --fix --only --"

9
patches/angle/.patches Normal file
View File

@@ -0,0 +1,9 @@
cherry-pick-d27d9d059b51.patch
m100_fix_crash_when_pausing_xfb_then_deleting_a_buffer.patch
cherry-pick-d49484c21e3c.patch
cherry-pick-a602a068e022.patch
cherry-pick-a4f71e40e571.patch
cherry-pick-9768648fffc9.patch
cherry-pick-03aa5ae75c29.patch
cherry-pick-801b904aea7d.patch
cherry-pick-6661eb4900da.patch

View File

@@ -0,0 +1,76 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@google.com>
Date: Wed, 1 Jun 2022 11:22:42 -0400
Subject: M102: Ignore eglBind/ReleaseTexImage calls for lost contexts.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
eglBindTexImage and eglReleaseTexImage no-op when no context is
current. Extend this to lost contexts to match the behaviour of making
a GL call on a lost context.
This avoids potential unexpected bad accesses in the backends.
Bug: chromium:1316578
Change-Id: I7b309c297e0c803019720733dee2950abb4c4b5f
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3683869
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Alexis Hétu <sugoi@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
(cherry picked from commit bfab7e60a15dc6f72e34406d3f2a3996cd8d0be2)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3691180
diff --git a/src/libANGLE/validationEGL.cpp b/src/libANGLE/validationEGL.cpp
index 7d2d43afa2cacf4445c528209b1fba6c1c6485c4..49d92219af76cbc8049f5c29a60fba3b26459bd0 100644
--- a/src/libANGLE/validationEGL.cpp
+++ b/src/libANGLE/validationEGL.cpp
@@ -4762,7 +4762,7 @@ bool ValidateBindTexImage(const ValidationContext *val,
}
gl::Context *context = val->eglThread->getContext();
- if (context)
+ if (context && !context->isContextLost())
{
gl::TextureType type = egl_gl::EGLTextureTargetToTextureType(surface->getTextureTarget());
gl::Texture *textureObject = context->getTextureByType(type);
diff --git a/src/libGLESv2/egl_stubs.cpp b/src/libGLESv2/egl_stubs.cpp
index fa37ae68e8e87aefd111440463611f737665691b..0b9d155d0d74f5b6b60667243d03182cc8b4d442 100644
--- a/src/libGLESv2/egl_stubs.cpp
+++ b/src/libGLESv2/egl_stubs.cpp
@@ -61,7 +61,7 @@ EGLBoolean BindTexImage(Thread *thread, Display *display, Surface *eglSurface, E
GetDisplayIfValid(display), EGL_FALSE);
gl::Context *context = thread->getContext();
- if (context)
+ if (context && !context->isContextLost())
{
gl::TextureType type =
egl_gl::EGLTextureTargetToTextureType(eglSurface->getTextureTarget());
@@ -569,15 +569,18 @@ EGLBoolean ReleaseTexImage(Thread *thread, Display *display, Surface *eglSurface
{
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglReleaseTexImage",
GetDisplayIfValid(display), EGL_FALSE);
- gl::Texture *texture = eglSurface->getBoundTexture();
-
- if (texture)
+ gl::Context *context = thread->getContext();
+ if (context && !context->isContextLost())
{
- ANGLE_EGL_TRY_RETURN(thread, eglSurface->releaseTexImage(thread->getContext(), buffer),
- "eglReleaseTexImage", GetSurfaceIfValid(display, eglSurface),
- EGL_FALSE);
- }
+ gl::Texture *texture = eglSurface->getBoundTexture();
+ if (texture)
+ {
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->releaseTexImage(thread->getContext(), buffer),
+ "eglReleaseTexImage", GetSurfaceIfValid(display, eglSurface),
+ EGL_FALSE);
+ }
+ }
thread->setSuccess();
return EGL_TRUE;
}

View File

@@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Mon, 2 May 2022 15:42:23 -0400
Subject: Fix validation cache when deleting a Transform Feedback.
Bug: chromium:1320024
Change-Id: I76ef85a3c65c663c138d8caebd4ef2c0da53cd4f
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3621780
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
(cherry picked from commit 84e42c3b04da9e2c9d93d35bb6f2b1830fef22f4)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3650697
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 141d106c8ea4c92ecf1e01b3fa7c3bf11ba7d5d3..e74d323b833d66e2891eaf77deb4225d98766036 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -3020,6 +3020,7 @@ void Context::detachTransformFeedback(TransformFeedbackID transformFeedback)
if (mState.removeTransformFeedbackBinding(this, transformFeedback))
{
bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
+ mStateCache.onActiveTransformFeedbackChange(this);
}
}

View File

@@ -0,0 +1,238 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Fri, 20 May 2022 10:26:15 -0400
Subject: D3D: Fix race condition with parallel shader compile.
Bug: chromium:1317673
Change-Id: I0fb7c9a66248852e41e8700e80c295393ef941e8
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3651153
Reviewed-by: Jie A Chen <jie.a.chen@intel.com>
Reviewed-by: Lingfeng Yang <lfy@google.com>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 4a20c9143abbf29c649cf643182735e8952089e3)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3691050
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 59fe34fc46a1bfbc7b4be1aad6ad84b6da303b5b..3256357a80d69739661ec1fd32220d3037145875 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1687,12 +1687,6 @@ class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask
angle::Result run() override
{
ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetVertexExecutableTask::run");
- if (!mProgram->mState.getAttachedShader(gl::ShaderType::Vertex))
- {
- return angle::Result::Continue;
- }
-
- mProgram->updateCachedInputLayoutFromShader();
ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog));
@@ -2147,6 +2141,11 @@ std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context,
linkResources(resources);
+ if (mState.getAttachedShader(gl::ShaderType::Vertex))
+ {
+ updateCachedInputLayoutFromShader();
+ }
+
return compileProgramExecutables(context, infoLog);
}
}
diff --git a/src/tests/gl_tests/ParallelShaderCompileTest.cpp b/src/tests/gl_tests/ParallelShaderCompileTest.cpp
index bcd88ef01308759085c8244ad2058efe68686f2b..a98aff540c642617bba366b2e238519942d7e349 100644
--- a/src/tests/gl_tests/ParallelShaderCompileTest.cpp
+++ b/src/tests/gl_tests/ParallelShaderCompileTest.cpp
@@ -58,9 +58,10 @@ class ParallelShaderCompileTest : public ANGLETest
Task(int id) : mID(id) {}
virtual ~Task() {}
- virtual bool compile() = 0;
- virtual bool isCompileCompleted() = 0;
- virtual bool link() = 0;
+ virtual bool compile() = 0;
+ virtual bool isCompileCompleted() = 0;
+ virtual bool link() = 0;
+ virtual void postLink() {}
virtual void runAndVerify(ParallelShaderCompileTest *test) = 0;
bool isLinkCompleted()
@@ -71,7 +72,7 @@ class ParallelShaderCompileTest : public ANGLETest
}
protected:
- std::string insertRandomString(const std::string &source)
+ static std::string InsertRandomString(const std::string &source)
{
RNG rng;
std::ostringstream ostream;
@@ -80,7 +81,7 @@ class ParallelShaderCompileTest : public ANGLETest
return ostream.str();
}
- GLuint CompileShader(GLenum type, const std::string &source)
+ static GLuint CompileShader(GLenum type, const std::string &source)
{
GLuint shader = glCreateShader(type);
@@ -90,7 +91,14 @@ class ParallelShaderCompileTest : public ANGLETest
return shader;
}
- bool checkShader(GLuint shader)
+ static void RecompileShader(GLuint shader, const std::string &source)
+ {
+ const char *sourceArray[1] = {source.c_str()};
+ glShaderSource(shader, 1, sourceArray, nullptr);
+ glCompileShader(shader);
+ }
+
+ static bool CheckShader(GLuint shader)
{
GLint compileResult;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
@@ -129,7 +137,7 @@ class ParallelShaderCompileTest : public ANGLETest
TaskRunner() {}
~TaskRunner() {}
- void run(ParallelShaderCompileTest *test)
+ void run(ParallelShaderCompileTest *test, unsigned int pollInterval)
{
std::vector<std::unique_ptr<T>> compileTasks;
@@ -151,6 +159,7 @@ class ParallelShaderCompileTest : public ANGLETest
if (task->isCompileCompleted())
{
bool isLinking = task->link();
+ task->postLink();
ASSERT_TRUE(isLinking);
linkTasks.push_back(std::move(task));
compileTasks.erase(compileTasks.begin() + i);
@@ -158,7 +167,10 @@ class ParallelShaderCompileTest : public ANGLETest
}
++i;
}
- angle::Sleep(kPollInterval);
+ if (pollInterval != 0)
+ {
+ angle::Sleep(pollInterval);
+ }
}
while (!linkTasks.empty())
@@ -173,9 +185,16 @@ class ParallelShaderCompileTest : public ANGLETest
linkTasks.erase(linkTasks.begin() + i);
continue;
}
+ else
+ {
+ task->postLink();
+ }
++i;
}
- angle::Sleep(kPollInterval);
+ if (pollInterval != 0)
+ {
+ angle::Sleep(pollInterval);
+ }
}
}
};
@@ -192,9 +211,9 @@ class ParallelShaderCompileTest : public ANGLETest
bool compile() override
{
mVertexShader =
- CompileShader(GL_VERTEX_SHADER, insertRandomString(essl1_shaders::vs::Simple()));
+ CompileShader(GL_VERTEX_SHADER, InsertRandomString(essl1_shaders::vs::Simple()));
mFragmentShader = CompileShader(GL_FRAGMENT_SHADER,
- insertRandomString(essl1_shaders::fs::UniformColor()));
+ InsertRandomString(essl1_shaders::fs::UniformColor()));
return (mVertexShader != 0 && mFragmentShader != 0);
}
@@ -213,7 +232,7 @@ class ParallelShaderCompileTest : public ANGLETest
bool link() override
{
mProgram = 0;
- if (checkShader(mVertexShader) && checkShader(mFragmentShader))
+ if (CheckShader(mVertexShader) && CheckShader(mFragmentShader))
{
mProgram = glCreateProgram();
glAttachShader(mProgram, mVertexShader);
@@ -244,10 +263,25 @@ class ParallelShaderCompileTest : public ANGLETest
ASSERT_GL_NO_ERROR();
}
+ protected:
+ void recompile()
+ {
+ RecompileShader(mVertexShader, essl1_shaders::vs::Simple());
+ RecompileShader(mFragmentShader, essl1_shaders::fs::UniformColor());
+ }
+
private:
- GLColor mColor;
GLuint mVertexShader;
GLuint mFragmentShader;
+ GLColor mColor;
+ };
+
+ class ClearColorWithDrawRecompile : public ClearColorWithDraw
+ {
+ public:
+ ClearColorWithDrawRecompile(int taskID) : ClearColorWithDraw(taskID) {}
+
+ void postLink() override { recompile(); }
};
class ImageLoadStore : public Task
@@ -268,7 +302,7 @@ void main()
imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
})";
- mShader = CompileShader(GL_COMPUTE_SHADER, insertRandomString(kCSSource));
+ mShader = CompileShader(GL_COMPUTE_SHADER, InsertRandomString(kCSSource));
return mShader != 0;
}
@@ -282,7 +316,7 @@ void main()
bool link() override
{
mProgram = 0;
- if (checkShader(mShader))
+ if (CheckShader(mShader))
{
mProgram = glCreateProgram();
glAttachShader(mProgram, mShader);
@@ -370,7 +404,18 @@ TEST_P(ParallelShaderCompileTest, LinkAndDrawManyPrograms)
ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
TaskRunner<ClearColorWithDraw> runner;
- runner.run(this);
+ runner.run(this, kPollInterval);
+}
+
+// Tests no crash in case that the Shader starts another compile while the Program being attached
+// to is still linking.
+// crbug.com/1317673
+TEST_P(ParallelShaderCompileTest, LinkProgramAndRecompileShader)
+{
+ ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
+
+ TaskRunner<ClearColorWithDrawRecompile> runner;
+ runner.run(this, 0);
}
class ParallelShaderCompileTestES31 : public ParallelShaderCompileTest
@@ -389,7 +434,7 @@ TEST_P(ParallelShaderCompileTestES31, LinkAndDispatchManyPrograms)
ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
TaskRunner<ImageLoadStore> runner;
- runner.run(this);
+ runner.run(this, kPollInterval);
}
ANGLE_INSTANTIATE_TEST_ES2(ParallelShaderCompileTest);

View File

@@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SeongHwan Park <ggabu423@gmail.com>
Date: Tue, 31 May 2022 02:41:32 +0900
Subject: Fix to invalidate cache when binding Transform Feedback.
Bug: chromium:1330379
Change-Id: I091116286ac511c50f9abcffa4d3cf350be920b4
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3677115
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit d96cee6685099f6bcc392a4d20d28c8ec484673a)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3691799
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 6b4d8d826ef3518ad11b1b39c78634f05d464b39..141d106c8ea4c92ecf1e01b3fa7c3bf11ba7d5d3 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -1306,6 +1306,7 @@ void Context::bindTransformFeedback(GLenum target, TransformFeedbackID transform
TransformFeedback *transformFeedback =
checkTransformFeedbackAllocation(transformFeedbackHandle);
mState.setTransformFeedbackBinding(this, transformFeedback);
+ mStateCache.onActiveTransformFeedbackChange(this);
}
void Context::bindProgramPipeline(ProgramPipelineID pipelineHandle)

View File

@@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@google.com>
Date: Fri, 1 Apr 2022 11:38:17 -0400
Subject: Fix CheckedNumeric using the wrong type.
Validation for glBufferSubData checks that the buffer is large enough
for size+offset but verifies they fit in a size_t which is a different
type than the deduced type for size+offset on 32-bit systems.
Use decltype to ensure that we always verify there is no overflow on the
correct type.
Bug: chromium:1298867
Change-Id: I82f534b2d227d3273a763e626ebeae068dc918dc
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3563515
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jonah Ryan-Davis <jonahr@google.com>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
(cherry picked from commit c458b5add432c3da98ef370680518d0af7e4d4e3)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3630020
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 947bed25cad67a0182a0396e635f2e52f5cd5704..cbe932a6d2131322d6dbb3c17a0cd05af551e462 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -3620,7 +3620,7 @@ bool ValidateBufferSubData(const Context *context,
}
// Check for possible overflow of size + offset
- angle::CheckedNumeric<size_t> checkedSize(size);
+ angle::CheckedNumeric<decltype(size + offset)> checkedSize(size);
checkedSize += offset;
if (!checkedSize.IsValid())
{
diff --git a/src/tests/gl_tests/BufferDataTest.cpp b/src/tests/gl_tests/BufferDataTest.cpp
index 325ba67bc6997afbdadf80ccbd994ec8b3ce9521..b993f95c1d8e103f24054f21853fb326c2e12112 100644
--- a/src/tests/gl_tests/BufferDataTest.cpp
+++ b/src/tests/gl_tests/BufferDataTest.cpp
@@ -824,6 +824,19 @@ TEST_P(BufferDataTest, MapWriteArrayBufferDataDrawArrays)
EXPECT_GL_NO_ERROR();
}
+// Verify that buffer sub data uploads are properly validated within the buffer size range on 32-bit
+// systems.
+TEST_P(BufferDataTest, BufferSizeValidation32Bit)
+{
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ glBufferData(GL_ARRAY_BUFFER, 100, nullptr, GL_STATIC_DRAW);
+
+ GLubyte data = 0;
+ glBufferSubData(GL_ARRAY_BUFFER, std::numeric_limits<uint32_t>::max(), 1, &data);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+}
+
// Tests a null crash bug caused by copying from null back-end buffer pointer
// when calling bufferData again after drawing without calling bufferData in D3D11.
TEST_P(BufferDataTestES3, DrawWithNotCallingBufferData)

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Tue, 19 Apr 2022 17:01:20 -0400
Subject: Fix validate state cache after XFB buffer deleted.
Bug: chromium:1317650
Change-Id: Iec9f1167c3b2957091dd0f4ef3efcfcd7c4bf3c0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3594250
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Auto-Submit: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 4efc4ee6830a8a53a0daf9daa3c7aa835db4220f)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3621779
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index ae245e4abdf9818d6aec83e4badad9811ed492b3..e9635038a1d4cc0ab5211b94c22d44f353388d64 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -2174,10 +2174,7 @@ angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
if (curTransformFeedback)
{
ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID));
- if (isTransformFeedbackActiveUnpaused())
- {
- context->getStateCache().onActiveTransformFeedbackChange(context);
- }
+ context->getStateCache().onActiveTransformFeedbackChange(context);
}
if (getVertexArray()->detachBuffer(context, bufferID))

View File

@@ -0,0 +1,100 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charlie Lao <cclao@google.com>
Date: Tue, 15 Mar 2022 09:39:36 -0700
Subject: Vulkan: Update mCurrentElementArrayBuffersync based on dirty bit
M96 merge issues:
ContextVk.cpp:
ContextVk::setupIndexedDraw: vertexArrayVk/getVertexArray() isn't present in M96
ContextVk::syncState: M96 uses mVertexArray instead of vertexArrayVk
VertexArrayVk.cpp:
VertexArrayVk::updateCurrentElementArrayBuffer doesn't exist in M9
Created it and kept M96 logic for retrieving buffer/offset
The previous fix crrev.com/c/3513553 has run into corner case that
requires more follow up change crrev.com/c/3522565. But with that, there
is report that now we are hitting assertion in
handleDirtyGraphicsIndexBuffer(). This becomes a bit fragile This new
fix relies on the DIRTY_BIT_INDEX_BUFFER dirty bit and should be more
reliable as long as the dirty bit is set properly (if not, then we have
other bug that it won't even send down vulkan command to bind the
correct element buffer). We could further optimize the code path and
create a fast path for most common usages in the future.
Bug: chromium:1299261
Change-Id: Ifa8f86d431798c9ca4c128ed71a3e9e0a3537ccb
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3526021
Commit-Queue: Charlie Lao <cclao@google.com>
(cherry picked from commit 349636a05a3577a127adb6c79a1e947890bbe462)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3605834
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Charlie Lao <cclao@google.com>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index aa1e5fa793e98a284b3d5dbda58778b8c2f1eeef..d9f6bcd54943bd211f1dc2b1ea149c21a79979a0 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -1062,6 +1062,17 @@ angle::Result ContextVk::setupIndexedDraw(const gl::Context *context,
mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
mLastIndexBufferOffset = indices;
}
+
+ // When you draw with LineLoop mode or GL_UNSIGNED_BYTE type, we may allocate its own
+ // element buffer and modify mCurrentElementArrayBuffer. When we switch out of that draw
+ // mode, we must reset mCurrentElementArrayBuffer back to the vertexArray's element buffer.
+ // Since in either case we set DIRTY_BIT_INDEX_BUFFER dirty bit, we use this bit to re-sync
+ // mCurrentElementArrayBuffer.
+ if (mGraphicsDirtyBits[DIRTY_BIT_INDEX_BUFFER])
+ {
+ mVertexArray->updateCurrentElementArrayBuffer();
+ }
+
if (shouldConvertUint8VkIndexType(indexType) && mGraphicsDirtyBits[DIRTY_BIT_INDEX_BUFFER])
{
ANGLE_VK_PERF_WARNING(this, GL_DEBUG_SEVERITY_LOW,
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index eb401bfd8c1ccfc750d34b46e95d97c54a5a0fac..fd6fcf4c339f7d189217545e10c4c808e103f671 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -454,6 +454,17 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
return angle::Result::Continue;
}
+void VertexArrayVk::updateCurrentElementArrayBuffer()
+{
+ ASSERT(mState.getElementArrayBuffer() != nullptr);
+ ASSERT(mState.getElementArrayBuffer()->getSize() > 0);
+ gl::Buffer *bufferGL = mState.getElementArrayBuffer();
+ BufferVk *bufferVk = vk::GetImpl(bufferGL);
+ mCurrentElementArrayBuffer =
+ &bufferVk->getBufferAndOffset(&mCurrentElementArrayBufferOffset);
+
+}
+
angle::Result VertexArrayVk::syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits,
gl::VertexArray::DirtyAttribBitsArray *attribBits,
@@ -479,9 +490,7 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
{
// Note that just updating buffer data may still result in a new
// vk::BufferHelper allocation.
- BufferVk *bufferVk = vk::GetImpl(bufferGL);
- mCurrentElementArrayBuffer =
- &bufferVk->getBufferAndOffset(&mCurrentElementArrayBufferOffset);
+ updateCurrentElementArrayBuffer();
}
else
{
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.h b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
index c198265bf8ba2017a13fce558826862f450218b5..0b98a9ed46b7cd4b9588973c74b0bbaf9172ab6c 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.h
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
@@ -34,6 +34,8 @@ class VertexArrayVk : public VertexArrayImpl
angle::Result updateActiveAttribInfo(ContextVk *contextVk);
+ void updateCurrentElementArrayBuffer();
+
angle::Result updateDefaultAttrib(ContextVk *contextVk,
size_t attribIndex,
VkBuffer bufferHandle,

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Mon, 11 Apr 2022 12:29:00 -0400
Subject: Add error check on resuming XFB with deleted buffer.
Bug: chromium:1313905
Change-Id: I22c6f6400b05ca32c922fba9a3b9d4b5841ca8b8
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3578378
Auto-Submit: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 5c85fd4e11a3835a0719223a7cedb978d309da21)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3594103
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 6fd5489332361c50c160228b089ec6108303f363..8d2f294b3a766b1cc3fff1472726503a11df0bcb 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -4287,6 +4287,13 @@ bool ValidateResumeTransformFeedback(const Context *context, angle::EntryPoint e
return false;
}
+ if (!ValidateProgramExecutableXFBBuffersPresent(context,
+ context->getState().getProgramExecutable()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
+ return false;
+ }
+
return true;
}

View File

@@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Mon, 14 Mar 2022 10:37:31 -0400
Subject: Fix crash when pausing XFB then deleting a buffer.
Fix is to validate XFB buffer bindings even if we're paused.
This is undefined behaviour so we can use any non-crashing solution.
Bug: chromium:1305190
Change-Id: Ib95404cdb13adbde7f34d6cc77473a8b3cbf1de7
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3522283
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 708ce9cfd63bc8eab7c48987612a2dedce78c69a)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3594105
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index e0281742d46d709f5f20a9d472256c5e475b627a..4cd36918f485f51cef2d6532a90bb8583b2861ab 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -4087,7 +4087,7 @@ const char *ValidateDrawStates(const Context *context)
}
}
- if (state.isTransformFeedbackActiveUnpaused())
+ if (state.isTransformFeedbackActive())
{
if (!ValidateProgramExecutableXFBBuffersPresent(context, executable))
{
diff --git a/src/tests/gl_tests/TransformFeedbackTest.cpp b/src/tests/gl_tests/TransformFeedbackTest.cpp
index c93cd02406390471f24005b61c7cf3e4703700a9..d495f8bf7ffe917cc6722a05c92ac2fa71d0376b 100644
--- a/src/tests/gl_tests/TransformFeedbackTest.cpp
+++ b/src/tests/gl_tests/TransformFeedbackTest.cpp
@@ -3902,6 +3902,25 @@ void main()
EXPECT_GL_NO_ERROR();
}
+// Same as the above, with a paused transform feedback.
+TEST_P(TransformFeedbackTest, DeletePausedTransformFeedbackBuffer)
+{
+ ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(testProgram, essl1_shaders::vs::Simple(),
+ essl1_shaders::fs::Green(), {"gl_Position"},
+ GL_INTERLEAVED_ATTRIBS);
+ glUseProgram(testProgram);
+
+ GLBuffer buffer;
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, 3, nullptr, GL_STATIC_DRAW);
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
+
+ glBeginTransformFeedback(GL_POINTS);
+ glPauseTransformFeedback();
+ buffer.reset();
+ glDrawArrays(GL_POINTS, 0, 1);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TransformFeedbackTest);
ANGLE_INSTANTIATE_TEST_ES3(TransformFeedbackTest);

View File

@@ -119,3 +119,30 @@ remove_incorrect_width_height_adjustments.patch
set_dpi_correctly_during_main_window_creation.patch
ui_gtk_public_header.patch
introduce_ozoneplatform_electron_can_call_x11_property.patch
revert_motionmark_avoid_unnecessary_ipc_on_mac.patch
cherry-pick-a1dc371d6680.patch
cherry-pick-1665a1d16d46.patch
use-after-free_of_id_and_idref_attributes.patch
fix_--without-valid_build.patch
cherry-pick-4d26949260aa.patch
skia_renderer_use_rectf_intersect_in_applyscissor.patch
cherry-pick-1a31e2110440.patch
cherry-pick-5cb934a23ddf.patch
use_iserrordocument_to_prevent_bfcacheing_of_interstitials_and.patch
cherry-pick-5ff02e4d7368.patch
cherry-pick-5361d836aeb1.patch
cherry-pick-5be8e065f43e.patch
cherry-pick-12ba78f3fa7a.patch
reland_fix_noopener_case_for_user_activation_consumption.patch
fsa_pass_file_ownership_to_worker_for_async_fsarfd_file_operations.patch
merge_to_m100_don_t_use_getoriginalopener_to_get_opener_s_origin_on.patch
cherry-pick-ec0cce63f47d.patch
cherry-pick-99c3f3bfd507.patch
cherry-pick-f1504440487f.patch
cherry-pick-21139756239b.patch
cherry-pick-919b1ffe1fe7.patch
cherry-pick-2782c7bc5bbe.patch
cherry-pick-f1dd785e021e.patch
cherry-pick-f3d01ff794dc.patch
cherry-pick-b03797bdb1df.patch
posix_replace_doubleforkandexec_with_forkandspawn.patch

View File

@@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Mon, 25 Apr 2022 20:57:43 +0000
Subject: Sanitize DragData markup before inserting it into document
(cherry picked from commit 5164a0fe3391283663e1196cf4576ec233985e89)
Fixed: 1315040
Change-Id: I8a0ddfb983d12c185f7e943d3d5277788199b011
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3579670
Quick-Run: Xiaocheng Hu <xiaochengh@chromium.org>
Auto-Submit: Xiaocheng Hu <xiaochengh@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#991324}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3589799
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1602}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/core/page/drag_data.cc b/third_party/blink/renderer/core/page/drag_data.cc
index 2ce56b1fefe016ac34a1a3011a595fab342abfa5..4fb86bc645386ee806544ee3647b0a333cd8afc4 100644
--- a/third_party/blink/renderer/core/page/drag_data.cc
+++ b/third_party/blink/renderer/core/page/drag_data.cc
@@ -131,8 +131,8 @@ DocumentFragment* DragData::AsFragment(LocalFrame* frame) const {
platform_drag_data_->HtmlAndBaseURL(html, base_url);
DCHECK(frame->GetDocument());
if (DocumentFragment* fragment =
- CreateFragmentFromMarkup(*frame->GetDocument(), html, base_url,
- kDisallowScriptingAndPluginContent))
+ CreateSanitizedFragmentFromMarkupWithContext(
+ *frame->GetDocument(), html, 0, html.length(), base_url))
return fragment;
}
diff --git a/third_party/blink/web_tests/editing/pasteboard/drag-and-drop-svg-use-sanitize.html b/third_party/blink/web_tests/editing/pasteboard/drag-and-drop-svg-use-sanitize.html
new file mode 100644
index 0000000000000000000000000000000000000000..58551d28341d851dbd99322e2a5d3af68b3b0c72
--- /dev/null
+++ b/third_party/blink/web_tests/editing/pasteboard/drag-and-drop-svg-use-sanitize.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<div id="drag-from" draggable=true>Drag from</div>
+<div id="drag-to" contenteditable>Drag to</div>
+
+<script>
+function computePoint(element) {
+ return {
+ x: element.offsetLeft + element.offsetWidth / 2,
+ y: element.offsetTop + element.offsetHeight / 2
+ };
+}
+
+let dragged = false;
+let executed = false;
+const payload = `
+ <svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg'&gt;&lt;image href='fake' onerror='executed=true' /&gt;&lt;/svg&gt;#x" />
+`;
+
+const dragFrom = document.getElementById('drag-from');
+dragFrom.ondragstart = event => {
+ dragged = true;
+ event.dataTransfer.setData('text/html', payload);
+}
+
+const dragTo = document.getElementById('drag-to');
+
+promise_test(async test => {
+ assert_own_property(window, 'eventSender', 'This test requires eventSender to simulate drag and drop');
+
+ const fromPoint = computePoint(dragFrom);
+ eventSender.mouseMoveTo(fromPoint.x, fromPoint.y);
+ eventSender.mouseDown();
+
+ const toPoint = computePoint(dragTo);
+ eventSender.mouseMoveTo(toPoint.x, toPoint.y);
+ eventSender.mouseUp();
+
+ assert_true(dragged, 'Element should be dragged');
+
+ // The 'error' event is dispatched asynchronously.
+ await new Promise(resolve => test.step_timeout(resolve, 100));
+ assert_false(executed, 'Script should be blocked');
+}, 'Script in SVG use href should be sanitized');
+</script>

View File

@@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "msw@chromium.org" <msw@chromium.org>
Date: Tue, 1 Feb 2022 21:16:10 +0000
Subject: Reland "Make web cursor size limits match on browser and renderer"
This reverts commit 38a8343085e53889eba48fcff78a6c2295927333.
Reason for revert: Fix without regressing https://crbug.com/1292426
(Increased WebCursor limit 128->150px to support DevToolsEyeDropper)
Original change's description:
> Revert "Make web cursor size limits match on browser and renderer"
>
> This reverts commit 868b44dd8b4a1a3b9698f561ca17f75e4ec78dd2.
>
> Reason for revert: https://crbug.com/1292426
>
> Original change's description:
> > Make web cursor size limits match on browser and renderer
> >
> > Use NSCursor arrowCursor on Mac for ui::mojom::CursorType::kNull.
> > (i.e. when WebCursor is constructed with an overly large custom cursor)
> >
> > Bug: 1246188
> > Test: Automated unit tests and WPTs
> > Change-Id: I89627fa13cba96b755b8f80adbc91cfc865b6b1b
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3413912
> > Reviewed-by: Henrique Ferreiro <hferreiro@igalia.com>
> > Reviewed-by: Charlie Harrison <csharrison@chromium.org>
> > Commit-Queue: Mike Wasserman <msw@chromium.org>
> > Auto-Submit: Mike Wasserman <msw@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#964378}
>
> Bug: 1246188
> Change-Id: Id7b3b88e65c012993537ce96c2b5064b7b76646e
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3428347
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Commit-Queue: Mike Wasserman <msw@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#965475}
Fixed: 1246188
Bug: 1292426
Change-Id: I5a490603c3e21e17f3136a3d792a18429eb3f633
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3428624
Auto-Submit: Mike Wasserman <msw@chromium.org>
Reviewed-by: Charlie Harrison <csharrison@chromium.org>
Commit-Queue: Mike Wasserman <msw@chromium.org>
Reviewed-by: Henrique Ferreiro <hferreiro@igalia.com>
Cr-Commit-Position: refs/heads/main@{#965857}
diff --git a/content/common/cursors/webcursor.cc b/content/common/cursors/webcursor.cc
index c8b6b9d3f75d0cac98cc4ab8e71b68117837c1dc..4c80616e41e6ba5b171ae09d06d7f4110589f70a 100644
--- a/content/common/cursors/webcursor.cc
+++ b/content/common/cursors/webcursor.cc
@@ -22,16 +22,19 @@ WebCursor::WebCursor(const ui::Cursor& cursor) {
WebCursor::WebCursor(const WebCursor& other) = default;
bool WebCursor::SetCursor(const ui::Cursor& cursor) {
- static constexpr int kMaxSize = 1024;
+ // This value is just large enough to accommodate:
+ // - kMaximumCursorSize in Blink's EventHandler
+ // - kCursorSize in Chrome's DevToolsEyeDropper
+ static constexpr int kMaximumCursorSize = 150;
if (cursor.image_scale_factor() < 0.01f ||
cursor.image_scale_factor() > 100.f ||
(cursor.type() == ui::mojom::CursorType::kCustom &&
- (cursor.custom_bitmap().width() > kMaxSize ||
- cursor.custom_bitmap().height() > kMaxSize ||
+ (cursor.custom_bitmap().width() > kMaximumCursorSize ||
+ cursor.custom_bitmap().height() > kMaximumCursorSize ||
cursor.custom_bitmap().width() / cursor.image_scale_factor() >
- kMaxSize ||
+ kMaximumCursorSize ||
cursor.custom_bitmap().height() / cursor.image_scale_factor() >
- kMaxSize))) {
+ kMaximumCursorSize))) {
return false;
}
diff --git a/content/common/cursors/webcursor_mac.mm b/content/common/cursors/webcursor_mac.mm
index f85c421f8581abe191738eaee133004b729a817d..fdc70bdff2ddc517f3e341dd16263ae89d8b153f 100644
--- a/content/common/cursors/webcursor_mac.mm
+++ b/content/common/cursors/webcursor_mac.mm
@@ -265,6 +265,7 @@ - (CrCoreCursorType)_coreCursorType {
case ui::mojom::CursorType::kCustom:
return CreateCustomCursor(cursor_);
case ui::mojom::CursorType::kNull:
+ return [NSCursor arrowCursor];
case ui::mojom::CursorType::kDndNone:
case ui::mojom::CursorType::kDndMove:
case ui::mojom::CursorType::kDndCopy:
diff --git a/content/common/cursors/webcursor_unittest.cc b/content/common/cursors/webcursor_unittest.cc
index 8f53ffa052f1f60d4eedccca5a4bc32941966963..9b2d8dec85e73b73108f40bca90237b4465e5043 100644
--- a/content/common/cursors/webcursor_unittest.cc
+++ b/content/common/cursors/webcursor_unittest.cc
@@ -122,11 +122,11 @@ TEST(WebCursorTest, SetCursor) {
// SetCursor should return false when the image width is too large.
cursor.set_image_scale_factor(1.f);
- cursor.set_custom_bitmap(CreateTestBitmap(1025, 3));
+ cursor.set_custom_bitmap(CreateTestBitmap(151, 3));
EXPECT_FALSE(webcursor.SetCursor(cursor));
// SetCursor should return false when the image height is too large.
- cursor.set_custom_bitmap(CreateTestBitmap(3, 1025));
+ cursor.set_custom_bitmap(CreateTestBitmap(3, 151));
EXPECT_FALSE(webcursor.SetCursor(cursor));
// SetCursor should return false when the scaled image width is too large.
@@ -136,7 +136,7 @@ TEST(WebCursorTest, SetCursor) {
// SetCursor should return false when the scaled image height is too large.
cursor.set_image_scale_factor(0.1f);
- cursor.set_custom_bitmap(CreateTestBitmap(5, 200));
+ cursor.set_custom_bitmap(CreateTestBitmap(5, 20));
EXPECT_FALSE(webcursor.SetCursor(cursor));
}

View File

@@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anders Hartvoll Ruud <andruud@chromium.org>
Date: Tue, 5 Apr 2022 20:44:33 +0000
Subject: Disallow CSS-wide keywords for StylePropertyMap.set
We don't support this properly, and the spec does not handle CSS-keywords
either. Disallow it until we can add proper support for this.
(cherry picked from commit 02e4b18febb37de8baea718bc2f62cfb5fe56e23)
Fixed: 1292905
Bug: 1310761
Change-Id: Ieb3d20edfea72c2ccb0928536fdfd86d10aad1a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3551609
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#986411}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3572186
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
Auto-Submit: Srinivas Sista <srinivassista@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/branch-heads/4896@{#1041}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl
index 925272d4967a33043cc3a53bd7de448ab03ca805..75597baf3aae8e9a1981153353202fb3e35b7850 100644
--- a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl
@@ -20,8 +20,10 @@ bool CSSOMKeywords::ValidKeywordForProperty(CSSPropertyID id,
return false;
}
- if (css_parsing_utils::IsCSSWideKeyword(valueID))
- return true;
+ if (css_parsing_utils::IsCSSWideKeyword(valueID)) {
+ // TODO(crbug.com/1310761): Support CSS-wide keywords in custom props.
+ return id != CSSPropertyID::kVariable;
+ }
switch (id) {
{% for property in properties if property.keywordIDs and 'Keyword' in property.typedom_types %}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-css-wide-in-custom-property-crash.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-css-wide-in-custom-property-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..bc977c9889889bd8a35eccc48ac28e25871b1ec9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-css-wide-in-custom-property-crash.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Don't crash when setting a CSS-wide keyword on a custom property</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
+<link rel="help" href="https://crbug.com/1310761<">
+<div id="target">
+ Don't crash
+</div>
+<script>
+ for (let keyword of ['initial', 'inherit', 'unset', 'revert', 'revert-layer']) {
+ try {
+ target.attributeStyleMap.set('--x', new CSSKeywordValue(keyword));
+ } catch (e) {
+ }
+ }
+</script>

View File

@@ -0,0 +1,114 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ari Chivukula <arichiv@chromium.org>
Date: Tue, 17 May 2022 18:17:07 +0000
Subject: {M102 PICK} [IndexedDB] Use-After-Free Fix
We can't guarantee order in the task the constructor dispatches the same
way we could before due to all the async changes. Let's be sure all the
objects exist before using them now. Long term, we need to address
ownership of the idb context.
Bug: 1324864, 1218100
Change-Id: Id5753297a4c966432028a1e7e063c5f1bed6f619
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3646994
Reviewed-by: Ayu Ishii <ayui@chromium.org>
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
Cr-Commit-Position: refs/branch-heads/5005@{#812}
Cr-Branched-From: 5b4d9450fee01f821b6400e947b3839727643a71-refs/heads/main@{#992738}
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index 6a7d303385aaf9bd8e0581c580ab328096ef5950..3afb1edf4cdc0baef105b680ec82007c66b40940 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -167,38 +167,32 @@ IndexedDBContextImpl::IndexedDBContextImpl(
std::move(quota_client_remote),
storage::QuotaClientType::kIndexedDatabase,
{blink::mojom::StorageType::kTemporary});
+ IDBTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&IndexedDBContextImpl::BindPipesOnIDBSequence,
+ weak_factory_.GetWeakPtr(),
+ std::move(quota_client_receiver),
+ std::move(blob_storage_context),
+ std::move(file_system_access_context)));
+}
- // This is safe because the IndexedDBContextImpl must be destructed on the
- // IDBTaskRunner, and this task will always happen before that.
- idb_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](mojo::Remote<storage::mojom::BlobStorageContext>*
- blob_storage_context,
- mojo::Remote<storage::mojom::FileSystemAccessContext>*
- file_system_access_context,
- mojo::Receiver<storage::mojom::QuotaClient>* quota_client_receiver,
- mojo::PendingRemote<storage::mojom::BlobStorageContext>
- pending_blob_storage_context,
- mojo::PendingRemote<storage::mojom::FileSystemAccessContext>
- pending_file_system_access_context,
- mojo::PendingReceiver<storage::mojom::QuotaClient>
- quota_client_pending_receiver) {
- quota_client_receiver->Bind(
- std::move(quota_client_pending_receiver));
- if (pending_blob_storage_context) {
- blob_storage_context->Bind(
- std::move(pending_blob_storage_context));
- }
- if (pending_file_system_access_context) {
- file_system_access_context->Bind(
- std::move(pending_file_system_access_context));
- }
- },
- &blob_storage_context_, &file_system_access_context_,
- &quota_client_receiver_, std::move(blob_storage_context),
- std::move(file_system_access_context),
- std::move(quota_client_receiver)));
+void IndexedDBContextImpl::BindPipesOnIDBSequence(
+ mojo::PendingReceiver<storage::mojom::QuotaClient>
+ pending_quota_client_receiver,
+ mojo::PendingRemote<storage::mojom::BlobStorageContext>
+ pending_blob_storage_context,
+ mojo::PendingRemote<storage::mojom::FileSystemAccessContext>
+ pending_file_system_access_context) {
+ DCHECK(IDBTaskRunner()->RunsTasksInCurrentSequence());
+ if (pending_quota_client_receiver) {
+ quota_client_receiver_.Bind(std::move(pending_quota_client_receiver));
+ }
+ if (pending_blob_storage_context) {
+ blob_storage_context_.Bind(std::move(pending_blob_storage_context));
+ }
+ if (pending_file_system_access_context) {
+ file_system_access_context_.Bind(
+ std::move(pending_file_system_access_context));
+ }
}
void IndexedDBContextImpl::Bind(
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index 4b874b244778d831e0fa8ca3bbfd7e751897923e..ad2f984e130ece867c0f0dc7ca9ae52b8ec12ae9 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -224,6 +224,14 @@ class CONTENT_EXPORT IndexedDBContextImpl
~IndexedDBContextImpl() override;
+ void BindPipesOnIDBSequence(
+ mojo::PendingReceiver<storage::mojom::QuotaClient>
+ pending_quota_client_receiver,
+ mojo::PendingRemote<storage::mojom::BlobStorageContext>
+ pending_blob_storage_context,
+ mojo::PendingRemote<storage::mojom::FileSystemAccessContext>
+ pending_file_system_access_context);
+
// Binds receiver on bucket retrieval to ensure that a bucket always exists
// for a storage key.
void BindIndexedDBWithBucket(
@@ -282,6 +290,8 @@ class CONTENT_EXPORT IndexedDBContextImpl
mojo::Receiver<storage::mojom::QuotaClient> quota_client_receiver_;
const std::unique_ptr<storage::FilesystemProxy> filesystem_proxy_;
+ // weak_factory_->GetWeakPtr() may be used on any thread, but the resulting
+ // pointer must only be checked/used on idb_task_runner_.
base::WeakPtrFactory<IndexedDBContextImpl> weak_factory_{this};
};

View File

@@ -0,0 +1,139 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <mek@chromium.org>
Date: Wed, 27 Apr 2022 20:51:50 +0000
Subject: Reland "Close a MessagePort if it is created in a destroyed context."
This is a reland of commit 068f13cc5aa5f7a6e9faf28d8731275e64cb657b
This reland changes the timeout in the test from 3 to 2 seconds, because
two 3 second timeouts is too long for chrome's default overall test
timeout of 6 seconds on non-dcheck release builds.
Original change's description:
> Close a MessagePort if it is created in a destroyed context.
>
> MessagePort assumes it is only destroyed either after ContextDestroyed,
> or after the port has been closed explicitly. As it turns out ports that
> were created in an already detached iframe would violate this invariant,
> causing issues.
>
> Bug: 1228661
> Change-Id: Ib1abce15f1d1d15f044de19fe0534767db488af0
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3561845
> Reviewed-by: Jeremy Roman <jbroman@chromium.org>
> Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#988859}
Bug: 1228661
Change-Id: Ifc5ec866678667b0d81438e2a2c8e5ada6e19d8c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3609249
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Auto-Submit: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/main@{#996880}
diff --git a/third_party/blink/renderer/core/messaging/message_port.cc b/third_party/blink/renderer/core/messaging/message_port.cc
index 6f67b21803fcdc2498ef207878d1541e04822fca..7f3df8ea567f91cd063122aab63a5c5424ab7919 100644
--- a/third_party/blink/renderer/core/messaging/message_port.cc
+++ b/third_party/blink/renderer/core/messaging/message_port.cc
@@ -55,7 +55,11 @@
namespace blink {
MessagePort::MessagePort(ExecutionContext& execution_context)
- : ExecutionContextLifecycleObserver(&execution_context),
+ : ExecutionContextLifecycleObserver(execution_context.IsContextDestroyed()
+ ? nullptr
+ : &execution_context),
+ // Ports in a destroyed context start out in a closed state.
+ closed_(execution_context.IsContextDestroyed()),
task_runner_(execution_context.GetTaskRunner(TaskType::kPostedMessage)) {}
MessagePort::~MessagePort() {
@@ -168,10 +172,21 @@ void MessagePort::Entangle(MessagePortDescriptor port) {
DCHECK(port.IsValid());
DCHECK(!connector_);
+ // If the context was already destroyed, there is no reason to actually
+ // entangle the port and create a Connector. No messages will ever be able to
+ // be sent or received anyway, as StartReceiving will never be called.
+ if (!GetExecutionContext())
+ return;
+
port_ = std::move(port);
connector_ = std::make_unique<mojo::Connector>(
port_.TakeHandleToEntangle(GetExecutionContext()),
mojo::Connector::SINGLE_THREADED_SEND);
+ // The raw `this` is safe despite `this` being a garbage collected object
+ // because we make sure that:
+ // 1. This object will not be garbage collected while it is connected and
+ // the execution context is not destroyed, and
+ // 2. when the execution context is destroyed, the connector_ is reset.
connector_->set_incoming_receiver(this);
connector_->set_connection_error_handler(
WTF::Bind(&MessagePort::close, WrapWeakPersistent(this)));
diff --git a/third_party/blink/renderer/core/messaging/message_port.h b/third_party/blink/renderer/core/messaging/message_port.h
index 83d7901d99ad01ba039ea1ffa3dbee2595fc31ff..f9baba3c6d13992508da48a13c97bb10c8ec56e0 100644
--- a/third_party/blink/renderer/core/messaging/message_port.h
+++ b/third_party/blink/renderer/core/messaging/message_port.h
@@ -148,7 +148,7 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
std::unique_ptr<mojo::Connector> connector_;
bool started_ = false;
- bool closed_ = false;
+ bool closed_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/third_party/blink/web_tests/external/wpt/webmessaging/message-channels/detached-iframe.window.js b/third_party/blink/web_tests/external/wpt/webmessaging/message-channels/detached-iframe.window.js
new file mode 100644
index 0000000000000000000000000000000000000000..c1effaf141b7246320883e293b58dabbc3572123
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webmessaging/message-channels/detached-iframe.window.js
@@ -0,0 +1,47 @@
+// META: title=MessageChannel in a detached iframe test
+// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
+// Pull in the with_iframe helper function from the service worker tests
+
+
+const IframeAction = {
+ REMOVE_BEFORE_CREATION: 'remove-before-creation',
+ REMOVE_AFTER_CREATION: 'remove-after-creation',
+};
+
+async function detached_frame_test(t, action) {
+ const iframe = await with_iframe('about:blank');
+ const iframe_MessageChannel = iframe.contentWindow.MessageChannel;
+
+ if (action === IframeAction.REMOVE_BEFORE_CREATION) {
+ iframe.remove();
+ }
+
+ (() => {
+ const mc = new iframe_MessageChannel();
+ mc.port1.postMessage("boo");
+ mc.port2.onmessage = t.unreached_func("message event received");
+ mc.port2.onmessageerror = t.unreached_func("message event received");
+ })();
+
+ if (action === IframeAction.REMOVE_AFTER_CREATION) {
+ iframe.remove();
+ }
+
+ // TODO(https://github.com/web-platform-tests/wpt/issues/7899): Change to
+ // some sort of cross-browser GC trigger.
+ if (self.gc) self.gc();
+
+ // We are testing that neither of the above two events fire. We assume that a 2 second timeout
+ // is good enough. We can't use any other API for an end condition because each MessagePort has
+ // its own independent port message queue, which has no ordering guarantees relative to other
+ // APIs.
+ await new Promise(resolve => t.step_timeout(resolve, 2000));
+}
+
+promise_test(async (t) => {
+ return detached_frame_test(t, IframeAction.REMOVE_AFTER_CREATION);
+}, 'MessageChannel created from a detached iframe should not send messages (remove after create)');
+
+promise_test(async (t) => {
+ return detached_frame_test(t, IframeAction.REMOVE_BEFORE_CREATION);
+}, 'MessageChannel created from a detached iframe should not send messages (remove before create)');

View File

@@ -0,0 +1,154 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yutaka Hirano <yhirano@chromium.org>
Date: Fri, 4 Feb 2022 10:16:05 +0000
Subject: Don't interpret informational response body as HTTP/0.9 response
An informational (1xx) response with body can be interpreted as an
informational response followed by an HTTP/0.9 response. It is confusing
so let's stop doing that.
Bug: 1291482
Change-Id: Ic3823838614330d761f11360a783859e5baa260e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3428433
Reviewed-by: Matt Menke <mmenke@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/main@{#967169}
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index a5f7bb10a01abb00db5d4ae15104f305027145b2..aaa22ac7001420c4d9c44a76af5a58bfbdc7deda 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -1014,15 +1014,23 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) {
base::StringPiece(read_buf_->StartOfBuffer(), end_offset));
if (!headers)
return net::ERR_INVALID_HTTP_RESPONSE;
+ has_seen_status_line_ = true;
} else {
// Enough data was read -- there is no status line, so this is HTTP/0.9, or
// the server is broken / doesn't speak HTTP.
- // If the port is not the default for the scheme, assume it's not a real
- // HTTP/0.9 response, and fail the request.
+ if (has_seen_status_line_) {
+ // If we saw a status line previously, the server can speak HTTP/1.x so it
+ // is not reasonable to interpret the response as an HTTP/0.9 response.
+ return ERR_INVALID_HTTP_RESPONSE;
+ }
+
base::StringPiece scheme = request_->url.scheme_piece();
if (url::DefaultPortForScheme(scheme.data(), scheme.length()) !=
request_->url.EffectiveIntPort()) {
+ // If the port is not the default for the scheme, assume it's not a real
+ // HTTP/0.9 response, and fail the request.
+
// Allow Shoutcast responses over HTTP, as it's somewhat common and relies
// on HTTP/0.9 on weird ports to work.
// See
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h
index 508b5296d6ff93689facc16939be2c720f42bf48..0c0619bdcf49328d1b737e2c3485d5beff99d0d1 100644
--- a/net/http/http_stream_parser.h
+++ b/net/http/http_stream_parser.h
@@ -275,6 +275,11 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// True if reading a keep-alive response. False if not, or if don't yet know.
bool response_is_keep_alive_;
+ // True if we've seen a response that has an HTTP status line. This is
+ // persistent across multiple response parsing. If we see a status line
+ // for a response, this will remain true forever.
+ bool has_seen_status_line_ = false;
+
// Keep track of the number of response body bytes read so far.
int64_t response_body_read_;
diff --git a/net/http/http_stream_parser_unittest.cc b/net/http/http_stream_parser_unittest.cc
index 3a394e629874d8ffff6eec02609e6009571a6733..e25b78539dfec4b27e6ddf2052967cab91141770 100644
--- a/net/http/http_stream_parser_unittest.cc
+++ b/net/http/http_stream_parser_unittest.cc
@@ -1399,6 +1399,25 @@ TEST(HttpStreamParser, Http09PortTests) {
}
}
+TEST(HttpStreamParser, ContinueWithBody) {
+ const std::string kResponse =
+ "HTTP/1.1 100 Continue\r\n\r\nhello\r\nworld\r\n";
+
+ SimpleGetRunner get_runner;
+ get_runner.set_url(GURL("http://foo.com/"));
+ get_runner.AddRead(kResponse);
+ get_runner.SetupParserAndSendRequest();
+
+ get_runner.ReadHeadersExpectingError(OK);
+ ASSERT_TRUE(get_runner.response_info()->headers);
+ EXPECT_EQ("HTTP/1.1 100 Continue",
+ get_runner.response_info()->headers->GetStatusLine());
+
+ // We ignore informational responses and start reading the next response in
+ // the stream. This simulates the behavior.
+ get_runner.ReadHeadersExpectingError(ERR_INVALID_HTTP_RESPONSE);
+}
+
TEST(HttpStreamParser, NullFails) {
const char kTestHeaders[] =
"HTTP/1.1 200 OK\r\n"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ac068363a83816939013bbde88a7584aca4f307
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS Status(100) should be ignored.
+FAIL Status(101) should be accepted, with removing body. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Status(103) should be ignored.
+PASS Status(199) should be ignored.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js
new file mode 100644
index 0000000000000000000000000000000000000000..df4dafcd80b38af93b688dcb318cfaf1978a939f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js
@@ -0,0 +1,28 @@
+promise_test(async (t) => {
+ // The 100 response should be ignored, then the transaction ends, which
+ // should lead to an error.
+ await promise_rejects_js(
+ t, TypeError, fetch('/common/text-plain.txt?pipe=status(100)'));
+}, 'Status(100) should be ignored.');
+
+// This behavior is being discussed at https://github.com/whatwg/fetch/issues/1397.
+promise_test(async (t) => {
+ const res = await fetch('/common/text-plain.txt?pipe=status(101)');
+ assert_equals(res.status, 101);
+ const body = await res.text();
+ assert_equals(body, '');
+}, 'Status(101) should be accepted, with removing body.');
+
+promise_test(async (t) => {
+ // The 103 response should be ignored, then the transaction ends, which
+ // should lead to an error.
+ await promise_rejects_js(
+ t, TypeError, fetch('/common/text-plain.txt?pipe=status(103)'));
+}, 'Status(103) should be ignored.');
+
+promise_test(async (t) => {
+ // The 199 response should be ignored, then the transaction ends, which
+ // should lead to an error.
+ await promise_rejects_js(
+ t, TypeError, fetch('/common/text-plain.txt?pipe=status(199)'));
+}, 'Status(199) should be ignored.');
diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ac068363a83816939013bbde88a7584aca4f307
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS Status(100) should be ignored.
+FAIL Status(101) should be accepted, with removing body. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Status(103) should be ignored.
+PASS Status(199) should be ignored.
+Harness: the test ran to completion.
+

View File

@@ -0,0 +1,84 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Eng <enga@chromium.org>
Date: Mon, 25 Apr 2022 21:01:40 +0000
Subject: Add bounds check to WebGPUDecoderImpl::DoRequestDevice
(cherry picked from commit bee4701c99cbbbb25c0bd6c5c79a40f63f1b1e47)
Fixed: chromium:1314754
Change-Id: Id23af9cc3df08cca3ce7d627e3761c9a65a2c802
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3580555
Commit-Queue: Austin Eng <enga@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#991510}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3589810
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1603}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index 39f2652a69e3b0e7494c8de3dee5453c4d447941..6879bddb8354e3f57f1431f05f30801e267940f5 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -423,11 +423,12 @@ class WebGPUDecoderImpl final : public WebGPUDecoder {
int32_t GetPreferredAdapterIndex(PowerPreference power_preference) const;
- void DoRequestDevice(DawnRequestDeviceSerial request_device_serial,
- int32_t requested_adapter_index,
- uint32_t device_id,
- uint32_t device_generation,
- const WGPUDeviceProperties& requested_device_properties);
+ error::Error DoRequestDevice(
+ DawnRequestDeviceSerial request_device_serial,
+ int32_t requested_adapter_index,
+ uint32_t device_id,
+ uint32_t device_generation,
+ const WGPUDeviceProperties& requested_device_properties);
void OnRequestDeviceCallback(DawnRequestDeviceSerial request_device_serial,
size_t requested_adapter_index,
uint32_t device_id,
@@ -582,16 +583,16 @@ ContextResult WebGPUDecoderImpl::Initialize() {
return ContextResult::kSuccess;
}
-void WebGPUDecoderImpl::DoRequestDevice(
+error::Error WebGPUDecoderImpl::DoRequestDevice(
DawnRequestDeviceSerial request_device_serial,
int32_t requested_adapter_index,
uint32_t device_id,
uint32_t device_generation,
const WGPUDeviceProperties& request_device_properties) {
- DCHECK_LE(0, requested_adapter_index);
-
- DCHECK_LT(static_cast<size_t>(requested_adapter_index),
- dawn_adapters_.size());
+ if (requested_adapter_index < 0 ||
+ static_cast<uint32_t>(requested_adapter_index) >= dawn_adapters_.size()) {
+ return error::kOutOfBounds;
+ }
dawn_native::DawnDeviceDescriptor device_descriptor;
if (request_device_properties.textureCompressionBC) {
@@ -666,6 +667,8 @@ void WebGPUDecoderImpl::DoRequestDevice(
std::move(*callback).Run(status, wgpu_device, message);
},
new CallbackT(std::move(callback)));
+
+ return error::kNoError;
}
void WebGPUDecoderImpl::OnRequestDeviceCallback(
@@ -1083,9 +1086,8 @@ error::Error WebGPUDecoderImpl::HandleRequestDevice(
}
}
- DoRequestDevice(request_device_serial, adapter_service_id, device_id,
- device_generation, device_properties);
- return error::kNoError;
+ return DoRequestDevice(request_device_serial, adapter_service_id, device_id,
+ device_generation, device_properties);
}
error::Error WebGPUDecoderImpl::HandleDawnCommands(

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gregg Tavares <gman@chromium.org>
Date: Fri, 29 Apr 2022 15:23:33 +0000
Subject: Check for error when calling ComputeImageSizeInBytes
(cherry picked from commit f3244fe50ba6c64ab6a75f1370d8dd983927fae6)
Bug: chromium:1304987
Change-Id: I8311231156fca3200ce74d79db59d910a1a0e33a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3556686
Commit-Queue: Gregg Tavares <gman@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#986304}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3597078
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1609}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
index 76a005a168a0e40d1e53016e461e96353ca463c5..b63b7c15d42bcdafed0bcbaced8cc13894c67035 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
@@ -3996,8 +3996,10 @@ bool WebGLImageConversion::ExtractTextureData(
data.resize(width * height * bytes_per_pixel);
unsigned image_size_in_bytes, skip_size_in_bytes;
- ComputeImageSizeInBytes(format, type, width, height, 1, unpack_params,
- &image_size_in_bytes, nullptr, &skip_size_in_bytes);
+ if (ComputeImageSizeInBytes(format, type, width, height, 1, unpack_params,
+ &image_size_in_bytes, nullptr,
+ &skip_size_in_bytes) != GL_NO_ERROR)
+ return false;
const uint8_t* src_data = static_cast<const uint8_t*>(pixels);
if (skip_size_in_bytes) {
src_data += skip_size_in_bytes;

View File

@@ -0,0 +1,431 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <mek@chromium.org>
Date: Tue, 5 Apr 2022 20:09:23 +0000
Subject: M100: Change ownership of BlobBytesProvider.
Rather than immediately passing ownership to a cross-thread
SelfOwnedReceiver while retaining a raw pointer, instead maintain
ownership in a unique_ptr as long as it is needed, only transferring
ownership to a SelfOwnedReceiver when BlobData is done with the
BlobBytesProvider.
Also clean-up/tighten down sequence checks for BlobBytesProvider a bit.
(cherry picked from commit 7222e9825fc02acc962e005c59885ee2f26df185)
Bug: 1285234
Change-Id: I7273e886a0bab2ae489b680d786991c9e4ff1dbb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3553304
Reviewed-by: Austin Sullivan <asully@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#986111}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3568972
Auto-Submit: Marijn Kruisselbrink <mek@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4896@{#1040}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc b/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
index fd27f1280e1745103879ffa4df563c21f4c46afd..125acccdd268c134a0608b739b5036ce2c455f26 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
@@ -32,13 +32,10 @@ class BlobBytesStreamer {
public:
BlobBytesStreamer(Vector<scoped_refptr<RawData>> data,
- mojo::ScopedDataPipeProducerHandle pipe,
- scoped_refptr<base::SequencedTaskRunner> task_runner)
+ mojo::ScopedDataPipeProducerHandle pipe)
: data_(std::move(data)),
pipe_(std::move(pipe)),
- watcher_(FROM_HERE,
- mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC,
- std::move(task_runner)) {
+ watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {
watcher_.Watch(pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
MOJO_WATCH_CONDITION_SATISFIED,
WTF::BindRepeating(&BlobBytesStreamer::OnWritable,
@@ -46,6 +43,8 @@ class BlobBytesStreamer {
}
void OnWritable(MojoResult result, const mojo::HandleSignalsState& state) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
if (result == MOJO_RESULT_CANCELLED ||
result == MOJO_RESULT_FAILED_PRECONDITION) {
delete this;
@@ -85,15 +84,18 @@ class BlobBytesStreamer {
private:
// The index of the item currently being written.
- wtf_size_t current_item_ = 0;
+ wtf_size_t current_item_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
// The offset into the current item of the first byte not yet written to the
// data pipe.
- size_t current_item_offset_ = 0;
+ size_t current_item_offset_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
// The data being written.
- Vector<scoped_refptr<RawData>> data_;
+ Vector<scoped_refptr<RawData>> data_ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ mojo::ScopedDataPipeProducerHandle pipe_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+ mojo::SimpleWatcher watcher_ GUARDED_BY_CONTEXT(sequence_checker_);
- mojo::ScopedDataPipeProducerHandle pipe_;
- mojo::SimpleWatcher watcher_;
+ SEQUENCE_CHECKER(sequence_checker_);
};
// This keeps the process alive while blobs are being transferred.
@@ -119,31 +121,8 @@ void DecreaseChildProcessRefCount() {
constexpr size_t BlobBytesProvider::kMaxConsolidatedItemSizeInBytes;
-// static
-BlobBytesProvider* BlobBytesProvider::CreateAndBind(
- mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
- auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
- {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
- auto provider = base::WrapUnique(new BlobBytesProvider(task_runner));
- auto* result = provider.get();
- // TODO(mek): Consider binding BytesProvider on the IPC thread instead, only
- // using the MayBlock taskrunner for actual file operations.
- PostCrossThreadTask(
- *task_runner, FROM_HERE,
- CrossThreadBindOnce(
- [](std::unique_ptr<BlobBytesProvider> provider,
- mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
- mojo::MakeSelfOwnedReceiver(std::move(provider),
- std::move(receiver));
- },
- std::move(provider), std::move(receiver)));
- return result;
-}
-
-// static
-std::unique_ptr<BlobBytesProvider> BlobBytesProvider::CreateForTesting(
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
- return base::WrapUnique(new BlobBytesProvider(std::move(task_runner)));
+BlobBytesProvider::BlobBytesProvider() {
+ IncreaseChildProcessRefCount();
}
BlobBytesProvider::~BlobBytesProvider() {
@@ -151,6 +130,8 @@ BlobBytesProvider::~BlobBytesProvider() {
}
void BlobBytesProvider::AppendData(scoped_refptr<RawData> data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
if (!data_.IsEmpty()) {
uint64_t last_offset = offsets_.IsEmpty() ? 0 : offsets_.back();
offsets_.push_back(last_offset + data_.back()->length());
@@ -159,6 +140,8 @@ void BlobBytesProvider::AppendData(scoped_refptr<RawData> data) {
}
void BlobBytesProvider::AppendData(base::span<const char> data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
if (data_.IsEmpty() ||
data_.back()->length() + data.size() > kMaxConsolidatedItemSizeInBytes) {
AppendData(RawData::Create());
@@ -167,8 +150,32 @@ void BlobBytesProvider::AppendData(base::span<const char> data) {
data.data(), base::checked_cast<wtf_size_t>(data.size()));
}
+// static
+void BlobBytesProvider::Bind(
+ std::unique_ptr<BlobBytesProvider> provider,
+ mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(provider->sequence_checker_);
+ DETACH_FROM_SEQUENCE(provider->sequence_checker_);
+
+ auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+ // TODO(mek): Consider binding BytesProvider on the IPC thread instead, only
+ // using the MayBlock taskrunner for actual file operations.
+ PostCrossThreadTask(
+ *task_runner, FROM_HERE,
+ CrossThreadBindOnce(
+ [](std::unique_ptr<BlobBytesProvider> provider,
+ mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(provider->sequence_checker_);
+ mojo::MakeSelfOwnedReceiver(std::move(provider),
+ std::move(receiver));
+ },
+ std::move(provider), std::move(receiver)));
+}
+
void BlobBytesProvider::RequestAsReply(RequestAsReplyCallback callback) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
// TODO(mek): Once better metrics are created we could experiment with ways
// to reduce the number of copies of data that are made here.
Vector<uint8_t> result;
@@ -179,9 +186,10 @@ void BlobBytesProvider::RequestAsReply(RequestAsReplyCallback callback) {
void BlobBytesProvider::RequestAsStream(
mojo::ScopedDataPipeProducerHandle pipe) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
// BlobBytesStreamer will self delete when done.
- new BlobBytesStreamer(std::move(data_), std::move(pipe), task_runner_);
+ new BlobBytesStreamer(std::move(data_), std::move(pipe));
}
void BlobBytesProvider::RequestAsFile(uint64_t source_offset,
@@ -189,7 +197,7 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset,
base::File file,
uint64_t file_offset,
RequestAsFileCallback callback) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!file.IsValid()) {
std::move(callback).Run(absl::nullopt);
@@ -257,10 +265,4 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset,
std::move(callback).Run(info.last_modified);
}
-BlobBytesProvider::BlobBytesProvider(
- scoped_refptr<base::SequencedTaskRunner> task_runner)
- : task_runner_(std::move(task_runner)) {
- IncreaseChildProcessRefCount();
-}
-
} // namespace blink
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider.h b/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
index 94e0172b7d411c8442b3949e8c82590f0b331fea..662cc02ecec7346ef32c44452cab38878c323edb 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_BYTES_PROVIDER_H_
#include "base/gtest_prod_util.h"
+#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/blob/data_element.mojom-blink.h"
@@ -17,8 +18,8 @@ namespace blink {
// making up a blob to the browser process, at the request of the blob service.
//
// Typical usage of this class creates and calls AppendData on one thread, and
-// then transfers ownership of the class to a different thread where it will be
-// bound to a mojo pipe, such that the various Request* methods are called on a
+// then transfers ownership of the class to a different thread using the `Bind`
+// method. This ensures that the various Request* methods are called on a
// thread that is allowed to do File IO.
class PLATFORM_EXPORT BlobBytesProvider : public mojom::blink::BytesProvider {
public:
@@ -26,19 +27,17 @@ class PLATFORM_EXPORT BlobBytesProvider : public mojom::blink::BytesProvider {
// data appended to the same item.
static constexpr size_t kMaxConsolidatedItemSizeInBytes = 15 * 1024;
- // Creates a new instance, and binds it on a new SequencedTaskRunner. The
- // returned instance should only be considered valid as long as the request
- // passed in to this method is still known to be valid.
- static BlobBytesProvider* CreateAndBind(
- mojo::PendingReceiver<mojom::blink::BytesProvider>);
- static std::unique_ptr<BlobBytesProvider> CreateForTesting(
- scoped_refptr<base::SequencedTaskRunner>);
-
+ BlobBytesProvider();
~BlobBytesProvider() override;
void AppendData(scoped_refptr<RawData>);
void AppendData(base::span<const char>);
+ // Binds `provider` to `receiver` on a threadpool task runner, transferring
+ // ownership.
+ static void Bind(std::unique_ptr<BlobBytesProvider> provider,
+ mojo::PendingReceiver<mojom::blink::BytesProvider> receiver);
+
// BytesProvider implementation:
void RequestAsReply(RequestAsReplyCallback) override;
void RequestAsStream(mojo::ScopedDataPipeProducerHandle) override;
@@ -51,17 +50,13 @@ class PLATFORM_EXPORT BlobBytesProvider : public mojom::blink::BytesProvider {
private:
FRIEND_TEST_ALL_PREFIXES(BlobBytesProviderTest, Consolidation);
- BlobBytesProvider(scoped_refptr<base::SequencedTaskRunner>);
-
- // The task runner this class is bound on, as well as what is used by the
- // RequestAsStream method to monitor the data pipe.
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
- Vector<scoped_refptr<RawData>> data_;
+ Vector<scoped_refptr<RawData>> data_ GUARDED_BY_CONTEXT(sequence_checker_);
// |offsets_| always contains exactly one fewer item than |data_| (except when
// |data_| itself is empty).
// offsets_[x] is equal to the sum of data_[i].length for all i <= x.
- Vector<uint64_t> offsets_;
+ Vector<uint64_t> offsets_ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace blink
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc b/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
index 227955f6c0762ab7015597fc3c6a6dada823b507..27bdebcbd7a96b579efdb9372d1de4e543b55f4d 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
@@ -52,8 +52,7 @@ class BlobBytesProviderTest : public testing::Test {
std::unique_ptr<BlobBytesProvider> CreateProvider(
scoped_refptr<RawData> data = nullptr) {
- auto result = BlobBytesProvider::CreateForTesting(
- blink::scheduler::GetSequencedTaskRunnerForTesting());
+ auto result = std::make_unique<BlobBytesProvider>();
if (data)
result->AppendData(std::move(data));
return result;
@@ -73,6 +72,8 @@ class BlobBytesProviderTest : public testing::Test {
TEST_F(BlobBytesProviderTest, Consolidation) {
auto data = CreateProvider();
+ DCHECK_CALLED_ON_VALID_SEQUENCE(data->sequence_checker_);
+
data->AppendData(base::make_span("abc", 3));
data->AppendData(base::make_span("def", 3));
data->AppendData(base::make_span("ps1", 3));
diff --git a/third_party/blink/renderer/platform/blob/blob_data.cc b/third_party/blink/renderer/platform/blob/blob_data.cc
index 6e3b98983f45b8583d8a7bb0fa51ad0fa73ecfa6..065820bf854e24ee4f1ef69fe1aff75755a27111 100644
--- a/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -107,6 +107,12 @@ BlobData::BlobData(FileCompositionStatus composition)
BlobData::~BlobData() = default;
Vector<mojom::blink::DataElementPtr> BlobData::ReleaseElements() {
+ if (last_bytes_provider_) {
+ DCHECK(last_bytes_provider_receiver_);
+ BlobBytesProvider::Bind(std::move(last_bytes_provider_),
+ std::move(last_bytes_provider_receiver_));
+ }
+
return std::move(elements_);
}
@@ -141,16 +147,6 @@ std::unique_ptr<BlobData> BlobData::CreateForFileSystemURLWithUnknownSize(
return data;
}
-void BlobData::DetachFromCurrentThread() {
- content_type_ = content_type_.IsolatedCopy();
- for (auto& element : elements_) {
- if (element->is_file_filesystem()) {
- auto& file_element = element->get_file_filesystem();
- file_element->url = file_element->url.Copy();
- }
- }
-}
-
void BlobData::SetContentType(const String& content_type) {
if (IsValidBlobType(content_type))
content_type_ = content_type;
@@ -274,6 +270,7 @@ void BlobData::AppendDataInternal(base::span<const char> data,
if (!elements_.IsEmpty() && elements_.back()->is_bytes()) {
// Append bytes to previous element.
DCHECK(last_bytes_provider_);
+ DCHECK(last_bytes_provider_receiver_);
const auto& bytes_element = elements_.back()->get_bytes();
bytes_element->length += data.size();
if (should_embed_bytes && bytes_element->embedded_data) {
@@ -285,9 +282,18 @@ void BlobData::AppendDataInternal(base::span<const char> data,
bytes_element->embedded_data = absl::nullopt;
}
} else {
+ if (last_bytes_provider_) {
+ // If `last_bytes_provider_` is set, but the previous element is not a
+ // bytes element, a new BytesProvider will be created and we need to
+ // make sure to bind the previous one first.
+ DCHECK(last_bytes_provider_receiver_);
+ BlobBytesProvider::Bind(std::move(last_bytes_provider_),
+ std::move(last_bytes_provider_receiver_));
+ }
mojo::PendingRemote<BytesProvider> bytes_provider_remote;
- last_bytes_provider_ = BlobBytesProvider::CreateAndBind(
- bytes_provider_remote.InitWithNewPipeAndPassReceiver());
+ last_bytes_provider_ = std::make_unique<BlobBytesProvider>();
+ last_bytes_provider_receiver_ =
+ bytes_provider_remote.InitWithNewPipeAndPassReceiver();
auto bytes_element = DataElementBytes::New(
data.size(), absl::nullopt, std::move(bytes_provider_remote));
diff --git a/third_party/blink/renderer/platform/blob/blob_data.h b/third_party/blink/renderer/platform/blob/blob_data.h
index 17cf9a704f1f0238e5f7f2ed754b1b9f37acdc6a..bfb88005916987eb61d533f53f5090dddc543cd5 100644
--- a/third_party/blink/renderer/platform/blob/blob_data.h
+++ b/third_party/blink/renderer/platform/blob/blob_data.h
@@ -44,6 +44,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/mojom/blob/data_element.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -120,13 +121,10 @@ class PLATFORM_EXPORT BlobData {
const KURL& file_system_url,
const absl::optional<base::Time>& expected_modification_time);
- // Detaches from current thread so that it can be passed to another thread.
- void DetachFromCurrentThread();
-
const String& ContentType() const { return content_type_; }
void SetContentType(const String&);
- const Vector<mojom::blink::DataElementPtr>& Elements() const {
+ const Vector<mojom::blink::DataElementPtr>& ElementsForTesting() const {
return elements_;
}
Vector<mojom::blink::DataElementPtr> ReleaseElements();
@@ -168,7 +166,15 @@ class PLATFORM_EXPORT BlobData {
Vector<mojom::blink::DataElementPtr> elements_;
size_t current_memory_population_ = 0;
- BlobBytesProvider* last_bytes_provider_ = nullptr;
+
+ // These two members are used to combine multiple consecutive 'bytes' elements
+ // (as created by `AppendBytes`, `AppendData` or `AppendText`) into a single
+ // element. When one has a value the other also has a value. Before using
+ // `elements_` to actually create a blob, `last_bytes_provider_` should be
+ // bound to `last_bytes_provider_receiver_`.
+ std::unique_ptr<BlobBytesProvider> last_bytes_provider_;
+ mojo::PendingReceiver<mojom::blink::BytesProvider>
+ last_bytes_provider_receiver_;
};
class PLATFORM_EXPORT BlobDataHandle
diff --git a/third_party/blink/renderer/platform/blob/blob_data_test.cc b/third_party/blink/renderer/platform/blob/blob_data_test.cc
index 60a811d1736c035a846fb9a8e0945c3203b2b6b4..1bad0fcf3a29e5420dff6a51c5e57714b063eb03 100644
--- a/third_party/blink/renderer/platform/blob/blob_data_test.cc
+++ b/third_party/blink/renderer/platform/blob/blob_data_test.cc
@@ -315,7 +315,7 @@ TEST_F(BlobDataHandleTest, CreateFromMergedBytes) {
auto data = std::make_unique<BlobData>();
data->AppendBytes(medium_test_data_.data(), medium_test_data_.size());
data->AppendBytes(small_test_data_.data(), small_test_data_.size());
- EXPECT_EQ(1u, data->Elements().size());
+ EXPECT_EQ(1u, data->ElementsForTesting().size());
Vector<uint8_t> expected_data = medium_test_data_;
expected_data.AppendVector(small_test_data_);
@@ -331,7 +331,7 @@ TEST_F(BlobDataHandleTest, CreateFromMergedLargeAndSmallBytes) {
auto data = std::make_unique<BlobData>();
data->AppendBytes(large_test_data_.data(), large_test_data_.size());
data->AppendBytes(small_test_data_.data(), small_test_data_.size());
- EXPECT_EQ(1u, data->Elements().size());
+ EXPECT_EQ(1u, data->ElementsForTesting().size());
Vector<uint8_t> expected_data = large_test_data_;
expected_data.AppendVector(small_test_data_);
@@ -347,7 +347,7 @@ TEST_F(BlobDataHandleTest, CreateFromMergedSmallAndLargeBytes) {
auto data = std::make_unique<BlobData>();
data->AppendBytes(small_test_data_.data(), small_test_data_.size());
data->AppendBytes(large_test_data_.data(), large_test_data_.size());
- EXPECT_EQ(1u, data->Elements().size());
+ EXPECT_EQ(1u, data->ElementsForTesting().size());
Vector<uint8_t> expected_data = small_test_data_;
expected_data.AppendVector(large_test_data_);

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: UwU UwU <uwu7586@gmail.com>
Date: Tue, 19 Apr 2022 15:10:38 +0000
Subject: NavigatorManagedData: Prevent iterator invalidation during Promise
resolution
(cherry picked from commit 6083135252280d9b43e26169eb35154a9ac861ea)
Bug: 1307223
Change-Id: Iead6cf8c6236a95dbdfe7877c912f6ba86b370ac
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3532439
Commit-Queue: Anqing Zhao <anqing@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#984230}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3577263
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Owners-Override: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1591}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc
index 2df64ff2c51dfe080cd50b46199e9c1d77ea26db..32b48ca0157a52d322aa4e00d18d4e662d3b1c4a 100644
--- a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc
+++ b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc
@@ -108,8 +108,14 @@ void NavigatorManagedData::OnServiceConnectionError() {
!managed_configuration_service_.is_connected()) {
managed_configuration_service_.reset();
}
+
+ // Move the set to a local variable to prevent script execution in Reject()
+ // from invalidating the iterator used by the loop.
+ HeapHashSet<Member<ScriptPromiseResolver>> pending_promises;
+ pending_promises_.swap(pending_promises);
+
// Resolve all pending promises with a failure.
- for (ScriptPromiseResolver* resolver : pending_promises_) {
+ for (ScriptPromiseResolver* resolver : pending_promises) {
resolver->Reject(
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotAllowedError,
kNotHighTrustedAppExceptionMessage));

View File

@@ -0,0 +1,393 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Rudenko <alexrudenko@chromium.org>
Date: Tue, 26 Apr 2022 05:53:56 +0000
Subject: DevTools: store weak references to nodes in inspect_tools
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This CL changes how the configuration for persistent overlays is stored.
Instead of trying to save a strong reference to a DOM node, we can
store weak references instead. This requires using a HeapHashMap as
vectors don't support weak reference elements.
(cherry picked from commit 2e0a0b83e1340e948a27cdc319bea8f32849d414)
Fixed: 1314310
Change-Id: I27ce12730d7598bc84d01adf421923af9a53dc67
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3593092
Reviewed-by: Danil Somsikov <dsv@chromium.org>
Reviewed-by: Changhao Han <changhaohan@chromium.org>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Commit-Queue: Alex Rudenko <alexrudenko@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#994866}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3604262
Auto-Submit: Alex Rudenko <alexrudenko@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Commit-Queue: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/branch-heads/5005@{#163}
Cr-Branched-From: 5b4d9450fee01f821b6400e947b3839727643a71-refs/heads/main@{#992738}
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc
index 7a417795a2fae0936cf1f168fc2b046fb2a0b0fd..2f8335981ac7679a9e8c3d0059dfff4b8a025ac4 100644
--- a/third_party/blink/renderer/core/inspector/inspect_tools.cc
+++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -477,14 +477,14 @@ bool PersistentTool::HideOnMouseMove() {
void PersistentTool::Draw(float scale) {
for (auto& entry : grid_node_highlights_) {
std::unique_ptr<protocol::Value> highlight =
- InspectorGridHighlight(entry.first.Get(), *(entry.second));
+ InspectorGridHighlight(entry.key, *(entry.value));
if (!highlight)
continue;
overlay_->EvaluateInOverlay("drawGridHighlight", std::move(highlight));
}
for (auto& entry : flex_container_configs_) {
std::unique_ptr<protocol::Value> highlight =
- InspectorFlexContainerHighlight(entry.first.Get(), *(entry.second));
+ InspectorFlexContainerHighlight(entry.key, *(entry.value));
if (!highlight)
continue;
overlay_->EvaluateInOverlay("drawFlexContainerHighlight",
@@ -492,7 +492,7 @@ void PersistentTool::Draw(float scale) {
}
for (auto& entry : scroll_snap_configs_) {
std::unique_ptr<protocol::Value> highlight =
- InspectorScrollSnapHighlight(entry.first.Get(), *(entry.second));
+ InspectorScrollSnapHighlight(entry.key, *(entry.value));
if (!highlight)
continue;
overlay_->EvaluateInOverlay("drawScrollSnapHighlight",
@@ -500,17 +500,15 @@ void PersistentTool::Draw(float scale) {
}
for (auto& entry : container_query_configs_) {
std::unique_ptr<protocol::Value> highlight =
- InspectorContainerQueryHighlight(entry.first.Get(), *(entry.second));
+ InspectorContainerQueryHighlight(entry.key, *(entry.value));
if (!highlight)
continue;
overlay_->EvaluateInOverlay("drawContainerQueryHighlight",
std::move(highlight));
}
- for (wtf_size_t i = 0; i < isolated_element_configs_.size(); ++i) {
- auto& entry = isolated_element_configs_.at(i);
+ for (auto& entry : isolated_element_configs_) {
std::unique_ptr<protocol::Value> highlight =
- InspectorIsolatedElementHighlight(entry.first.Get(), *(entry.second),
- i);
+ InspectorIsolatedElementHighlight(entry.key, *(entry.value));
if (!highlight)
continue;
overlay_->EvaluateInOverlay("drawIsolatedElementHighlight",
@@ -548,9 +546,11 @@ void PersistentTool::Dispatch(const ScriptValue& message,
Element* element = nullptr;
if (highlight_type == "isolatedElement") {
- if (index < static_cast<int>(isolated_element_configs_.size()) &&
- index >= 0) {
- element = isolated_element_configs_.at(index).first.Get();
+ for (auto& entry : isolated_element_configs_) {
+ if (entry.value->highlight_index == index) {
+ element = entry.key;
+ break;
+ }
}
}
@@ -571,7 +571,7 @@ PersistentTool::GetGridInspectorHighlightsAsJson() const {
protocol::ListValue::create();
for (auto& entry : grid_node_highlights_) {
std::unique_ptr<protocol::Value> highlight =
- InspectorGridHighlight(entry.first.Get(), *(entry.second));
+ InspectorGridHighlight(entry.key, *(entry.value));
if (!highlight)
continue;
highlights->pushValue(std::move(highlight));
@@ -584,6 +584,15 @@ PersistentTool::GetGridInspectorHighlightsAsJson() const {
return result;
}
+void PersistentTool::Trace(Visitor* visitor) const {
+ InspectTool::Trace(visitor);
+ visitor->Trace(grid_node_highlights_);
+ visitor->Trace(flex_container_configs_);
+ visitor->Trace(scroll_snap_configs_);
+ visitor->Trace(container_query_configs_);
+ visitor->Trace(isolated_element_configs_);
+}
+
// SourceOrderTool -----------------------------------------------------------
SourceOrderTool::SourceOrderTool(
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.h b/third_party/blink/renderer/core/inspector/inspect_tools.h
index 1f558bec19b510fc80b884a6fe00144123c8aee3..2c45dc42dac388df5dbfe95949c41721944e14c4 100644
--- a/third_party/blink/renderer/core/inspector/inspect_tools.h
+++ b/third_party/blink/renderer/core/inspector/inspect_tools.h
@@ -145,23 +145,20 @@ class SourceOrderTool : public InspectTool {
};
// -----------------------------------------------------------------------------
-
-using GridConfigs = Vector<
- std::pair<Member<Node>, std::unique_ptr<InspectorGridHighlightConfig>>>;
+using GridConfigs = HeapHashMap<WeakMember<Node>,
+ std::unique_ptr<InspectorGridHighlightConfig>>;
using FlexContainerConfigs =
- Vector<std::pair<Member<Node>,
- std::unique_ptr<InspectorFlexContainerHighlightConfig>>>;
-using ScrollSnapConfigs = Vector<
- std::pair<Member<Node>,
- std::unique_ptr<InspectorScrollSnapContainerHighlightConfig>>>;
-
-using ContainerQueryConfigs = Vector<std::pair<
- Member<Node>,
- std::unique_ptr<InspectorContainerQueryContainerHighlightConfig>>>;
-
+ HeapHashMap<WeakMember<Node>,
+ std::unique_ptr<InspectorFlexContainerHighlightConfig>>;
+using ScrollSnapConfigs =
+ HeapHashMap<WeakMember<Node>,
+ std::unique_ptr<InspectorScrollSnapContainerHighlightConfig>>;
+using ContainerQueryConfigs = HeapHashMap<
+ WeakMember<Node>,
+ std::unique_ptr<InspectorContainerQueryContainerHighlightConfig>>;
using IsolatedElementConfigs =
- Vector<std::pair<Member<Element>,
- std::unique_ptr<InspectorIsolationModeHighlightConfig>>>;
+ HeapHashMap<WeakMember<Element>,
+ std::unique_ptr<InspectorIsolationModeHighlightConfig>>;
class PersistentTool : public InspectTool {
using InspectTool::InspectTool;
@@ -181,6 +178,8 @@ class PersistentTool : public InspectTool {
std::unique_ptr<protocol::DictionaryValue> GetGridInspectorHighlightsAsJson()
const;
+ void Trace(Visitor* visitor) const override;
+
private:
bool ForwardEventsToOverlay() override;
bool HideOnMouseMove() override;
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index 74edb4b3c0b557988e7ac297a2e502497c792eec..357aea702b828bbb7797377677bdbddbaa50e3b9 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -2428,8 +2428,7 @@ std::unique_ptr<protocol::DictionaryValue> InspectorContainerQueryHighlight(
std::unique_ptr<protocol::DictionaryValue> InspectorIsolatedElementHighlight(
Element* element,
- const InspectorIsolationModeHighlightConfig& config,
- int highlight_index) {
+ const InspectorIsolationModeHighlightConfig& config) {
LocalFrameView* frame_view = element->GetDocument().View();
if (!frame_view)
return nullptr;
@@ -2441,7 +2440,7 @@ std::unique_ptr<protocol::DictionaryValue> InspectorIsolatedElementHighlight(
if (!isolated_element_info)
return nullptr;
- isolated_element_info->setInteger("highlightIndex", highlight_index);
+ isolated_element_info->setInteger("highlightIndex", config.highlight_index);
return isolated_element_info;
}
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.h b/third_party/blink/renderer/core/inspector/inspector_highlight.h
index 53884fd75b8a861df3b33cc730304d344f5cda2a..897445629fdc6bbfe36c750027acce992a965d46 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.h
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -145,6 +145,7 @@ struct CORE_EXPORT InspectorIsolationModeHighlightConfig {
Color resizer_color;
Color resizer_handle_color;
Color mask_color;
+ int highlight_index = 0;
};
struct CORE_EXPORT InspectorHighlightConfig {
@@ -300,8 +301,7 @@ std::unique_ptr<protocol::DictionaryValue> InspectorContainerQueryHighlight(
std::unique_ptr<protocol::DictionaryValue> InspectorIsolatedElementHighlight(
Element* element,
- const InspectorIsolationModeHighlightConfig& config,
- int highlight_index);
+ const InspectorIsolationModeHighlightConfig& config);
// CORE_EXPORT is required to make these functions available for unit tests.
std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
index f061849584a4a228b86cffb20ce3ab74c0a25409..d8c9a48da6ed4b08681268d495a2e60efb8308b6 100644
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -711,7 +711,7 @@ Response InspectorOverlayAgent::setShowGridOverlays(
MakeGarbageCollected<PersistentTool>(this, GetFrontend());
}
- Vector<std::pair<Member<Node>, std::unique_ptr<InspectorGridHighlightConfig>>>
+ HeapHashMap<WeakMember<Node>, std::unique_ptr<InspectorGridHighlightConfig>>
configs;
for (std::unique_ptr<protocol::Overlay::GridNodeHighlightConfig>& config :
*grid_node_highlight_configs) {
@@ -719,9 +719,8 @@ Response InspectorOverlayAgent::setShowGridOverlays(
Response response = dom_agent_->AssertNode(config->getNodeId(), node);
if (!response.IsSuccess())
return response;
- configs.push_back(
- std::make_pair(node, InspectorOverlayAgent::ToGridHighlightConfig(
- config->getGridHighlightConfig())));
+ configs.insert(node, InspectorOverlayAgent::ToGridHighlightConfig(
+ config->getGridHighlightConfig()));
}
persistent_tool_->SetGridConfigs(std::move(configs));
@@ -739,8 +738,8 @@ Response InspectorOverlayAgent::setShowFlexOverlays(
MakeGarbageCollected<PersistentTool>(this, GetFrontend());
}
- Vector<std::pair<Member<Node>,
- std::unique_ptr<InspectorFlexContainerHighlightConfig>>>
+ HeapHashMap<WeakMember<Node>,
+ std::unique_ptr<InspectorFlexContainerHighlightConfig>>
configs;
for (std::unique_ptr<protocol::Overlay::FlexNodeHighlightConfig>& config :
@@ -749,9 +748,8 @@ Response InspectorOverlayAgent::setShowFlexOverlays(
Response response = dom_agent_->AssertNode(config->getNodeId(), node);
if (!response.IsSuccess())
return response;
- configs.push_back(std::make_pair(
- node, InspectorOverlayAgent::ToFlexContainerHighlightConfig(
- config->getFlexContainerHighlightConfig())));
+ configs.insert(node, InspectorOverlayAgent::ToFlexContainerHighlightConfig(
+ config->getFlexContainerHighlightConfig()));
}
persistent_tool_->SetFlexContainerConfigs(std::move(configs));
@@ -770,9 +768,8 @@ Response InspectorOverlayAgent::setShowScrollSnapOverlays(
MakeGarbageCollected<PersistentTool>(this, GetFrontend());
}
- Vector<
- std::pair<Member<Node>,
- std::unique_ptr<InspectorScrollSnapContainerHighlightConfig>>>
+ HeapHashMap<WeakMember<Node>,
+ std::unique_ptr<InspectorScrollSnapContainerHighlightConfig>>
configs;
for (std::unique_ptr<protocol::Overlay::ScrollSnapHighlightConfig>& config :
@@ -781,9 +778,9 @@ Response InspectorOverlayAgent::setShowScrollSnapOverlays(
Response response = dom_agent_->AssertNode(config->getNodeId(), node);
if (!response.IsSuccess())
return response;
- configs.push_back(std::make_pair(
- node, InspectorOverlayAgent::ToScrollSnapContainerHighlightConfig(
- config->getScrollSnapContainerHighlightConfig())));
+ configs.insert(node,
+ InspectorOverlayAgent::ToScrollSnapContainerHighlightConfig(
+ config->getScrollSnapContainerHighlightConfig()));
}
persistent_tool_->SetScrollSnapConfigs(std::move(configs));
@@ -802,9 +799,8 @@ Response InspectorOverlayAgent::setShowContainerQueryOverlays(
MakeGarbageCollected<PersistentTool>(this, GetFrontend());
}
- Vector<std::pair<
- Member<Node>,
- std::unique_ptr<InspectorContainerQueryContainerHighlightConfig>>>
+ HeapHashMap<WeakMember<Node>,
+ std::unique_ptr<InspectorContainerQueryContainerHighlightConfig>>
configs;
for (std::unique_ptr<protocol::Overlay::ContainerQueryHighlightConfig>&
@@ -813,9 +809,9 @@ Response InspectorOverlayAgent::setShowContainerQueryOverlays(
Response response = dom_agent_->AssertNode(config->getNodeId(), node);
if (!response.IsSuccess())
return response;
- configs.push_back(std::make_pair(
+ configs.insert(
node, InspectorOverlayAgent::ToContainerQueryContainerHighlightConfig(
- config->getContainerQueryContainerHighlightConfig())));
+ config->getContainerQueryContainerHighlightConfig()));
}
persistent_tool_->SetContainerQueryConfigs(std::move(configs));
@@ -834,10 +830,11 @@ Response InspectorOverlayAgent::setShowIsolatedElements(
MakeGarbageCollected<PersistentTool>(this, GetFrontend());
}
- Vector<std::pair<Member<Element>,
- std::unique_ptr<InspectorIsolationModeHighlightConfig>>>
+ HeapHashMap<WeakMember<Element>,
+ std::unique_ptr<InspectorIsolationModeHighlightConfig>>
configs;
+ int idx = 0;
for (std::unique_ptr<protocol::Overlay::IsolatedElementHighlightConfig>&
config : *isolated_element_highlight_configs) {
Element* element = nullptr;
@@ -845,9 +842,10 @@ Response InspectorOverlayAgent::setShowIsolatedElements(
Response response = dom_agent_->AssertElement(config->getNodeId(), element);
if (!response.IsSuccess())
return response;
- configs.push_back(std::make_pair(
- element, InspectorOverlayAgent::ToIsolationModeHighlightConfig(
- config->getIsolationModeHighlightConfig())));
+ configs.insert(element,
+ InspectorOverlayAgent::ToIsolationModeHighlightConfig(
+ config->getIsolationModeHighlightConfig(), idx));
+ idx++;
}
persistent_tool_->SetIsolatedElementConfigs(std::move(configs));
@@ -951,16 +949,16 @@ Response InspectorOverlayAgent::getGridHighlightObjectsForTest(
std::unique_ptr<protocol::Array<int>> node_ids,
std::unique_ptr<protocol::DictionaryValue>* highlights) {
PersistentTool persistent_tool(this, GetFrontend());
- Vector<std::pair<Member<Node>, std::unique_ptr<InspectorGridHighlightConfig>>>
+
+ HeapHashMap<WeakMember<Node>, std::unique_ptr<InspectorGridHighlightConfig>>
configs;
for (const int node_id : *node_ids) {
Node* node = nullptr;
Response response = dom_agent_->AssertNode(node_id, node);
if (!response.IsSuccess())
return response;
- configs.push_back(
- std::make_pair(node, std::make_unique<InspectorGridHighlightConfig>(
- InspectorHighlight::DefaultGridConfig())));
+ configs.insert(node, std::make_unique<InspectorGridHighlightConfig>(
+ InspectorHighlight::DefaultGridConfig()));
}
persistent_tool.SetGridConfigs(std::move(configs));
*highlights = persistent_tool.GetGridInspectorHighlightsAsJson();
@@ -1728,7 +1726,8 @@ InspectorOverlayAgent::ToFlexItemHighlightConfig(
// static
std::unique_ptr<InspectorIsolationModeHighlightConfig>
InspectorOverlayAgent::ToIsolationModeHighlightConfig(
- protocol::Overlay::IsolationModeHighlightConfig* config) {
+ protocol::Overlay::IsolationModeHighlightConfig* config,
+ int idx) {
if (!config) {
return nullptr;
}
@@ -1740,6 +1739,7 @@ InspectorOverlayAgent::ToIsolationModeHighlightConfig(
InspectorDOMAgent::ParseColor(config->getResizerHandleColor(nullptr));
highlight_config->mask_color =
InspectorDOMAgent::ParseColor(config->getMaskColor(nullptr));
+ highlight_config->highlight_index = idx;
return highlight_config;
}
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
index ee9963de2b918cba7fd786c85f6c1ad1884ae5f8..d70123303569c7626a4c3117d542d66e0c375ac1 100644
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -161,7 +161,8 @@ class CORE_EXPORT InspectorOverlayAgent final
ToFlexItemHighlightConfig(protocol::Overlay::FlexItemHighlightConfig*);
static std::unique_ptr<InspectorIsolationModeHighlightConfig>
ToIsolationModeHighlightConfig(
- protocol::Overlay::IsolationModeHighlightConfig*);
+ protocol::Overlay::IsolationModeHighlightConfig*,
+ int highlight_index);
static absl::optional<LineStyle> ToLineStyle(protocol::Overlay::LineStyle*);
static absl::optional<BoxStyle> ToBoxStyle(protocol::Overlay::BoxStyle*);
static std::unique_ptr<InspectorHighlightConfig> ToHighlightConfig(

View File

@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Fri, 8 Apr 2022 23:28:35 +0000
Subject: Only destroy successfully created compression session in VT encoder
This is a defensive change, since we don't have a repro on hand.
My guess is that VTCompressionSessionCreate() might fail to create a
compression session, but still write a value to compressionSessionOut.
It makes VTCompressionSessionInvalidate() access uninitialized memory.
That's why this CL makes sure that we only destroy a compression session
if VTCompressionSessionCreate() reports success.
Bug: 1312563
Change-Id: I468ce0e10bad251ca0b62b568607dbc5c32ba8bc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3575680
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Cr-Commit-Position: refs/heads/main@{#990654}
diff --git a/media/gpu/mac/vt_video_encode_accelerator_mac.cc b/media/gpu/mac/vt_video_encode_accelerator_mac.cc
index 06333aaeca6b8bfd10d6809bcace4177ac7fd368..c265ff94617dfedca60ad9b3f1ce3de3364cfe56 100644
--- a/media/gpu/mac/vt_video_encode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_encode_accelerator_mac.cc
@@ -129,13 +129,13 @@ VTVideoEncodeAccelerator::GetSupportedProfiles() {
SupportedProfiles profiles;
const bool rv = CreateCompressionSession(
gfx::Size(kDefaultResolutionWidth, kDefaultResolutionHeight));
- DestroyCompressionSession();
if (!rv) {
VLOG(1)
<< "Hardware encode acceleration is not available on this platform.";
return profiles;
}
+ DestroyCompressionSession();
SupportedProfile profile;
profile.max_framerate_numerator = kMaxFrameRateNumerator;
profile.max_framerate_denominator = kMaxFrameRateDenominator;
@@ -533,10 +533,8 @@ bool VTVideoEncodeAccelerator::ResetCompressionSession() {
DestroyCompressionSession();
bool session_rv = CreateCompressionSession(input_visible_size_);
- if (!session_rv) {
- DestroyCompressionSession();
+ if (!session_rv)
return false;
- }
const bool configure_rv = ConfigureCompressionSession();
if (configure_rv)
@@ -572,6 +570,12 @@ bool VTVideoEncodeAccelerator::CreateCompressionSession(
&VTVideoEncodeAccelerator::CompressionCallback,
reinterpret_cast<void*>(this), compression_session_.InitializeInto());
if (status != noErr) {
+ // IMPORTANT: ScopedCFTypeRef::release() doesn't call CFRelease().
+ // In case of an error VTCompressionSessionCreate() is not supposed to
+ // write a non-null value into compression_session_, but just in case,
+ // we'll clear it without calling CFRelease() because it can be unsafe
+ // to call on a not fully created session.
+ (void)compression_session_.release();
DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status;
return false;
}

View File

@@ -0,0 +1,413 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jack Hsieh <chengweih@chromium.org>
Date: Fri, 21 Jan 2022 00:01:43 +0000
Subject: usb: Fix OOB access with non-sequential interfaces
When accessing a usb device with non-sequential interface number or
alternative setting value, it might end up using index out of the
internal array allocated size. It is caused by using incorrect
parameters (i.e interface_number and alternate_setting) into the
callback which expects taking interface_index and alternate_index. Fix
it by passing the correct parameters which are already available in the
function to the callback.
Bug: 1286816
Change-Id: I6b3533f944f94e94e63959b99718858e089449da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3384715
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Jack Hsieh <chengweih@chromium.org>
Cr-Commit-Position: refs/heads/main@{#961679}
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
index aef73449348e4636be9f8fc90bfc07ac65b03326..82da58974c51c3a593d5c2a272d0a0f05361dfdb 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -132,9 +132,9 @@ bool USBDevice::IsInterfaceClaimed(wtf_size_t configuration_index,
claimed_interfaces_[interface_index];
}
-wtf_size_t USBDevice::SelectedAlternateInterface(
+wtf_size_t USBDevice::SelectedAlternateInterfaceIndex(
wtf_size_t interface_index) const {
- return selected_alternates_[interface_index];
+ return selected_alternate_indices_[interface_index];
}
USBConfiguration* USBDevice::configuration() const {
@@ -302,7 +302,7 @@ ScriptPromise USBDevice::selectAlternateInterface(ScriptState* script_state,
device_->SetInterfaceAlternateSetting(
interface_number, alternate_setting,
WTF::Bind(&USBDevice::AsyncSelectAlternateInterface,
- WrapPersistent(this), interface_number, alternate_setting,
+ WrapPersistent(this), interface_index, alternate_index,
WrapPersistent(resolver)));
}
}
@@ -744,7 +744,7 @@ void USBDevice::SetEndpointsForInterface(wtf_size_t interface_index, bool set) {
const auto& configuration = *Info().configurations[configuration_index_];
const auto& interface = *configuration.interfaces[interface_index];
const auto& alternate =
- *interface.alternates[selected_alternates_[interface_index]];
+ *interface.alternates[selected_alternate_indices_[interface_index]];
for (const auto& endpoint : alternate.endpoints) {
uint8_t endpoint_number = endpoint->endpoint_number;
if (endpoint_number == 0 || endpoint_number >= kEndpointsBitsNumber)
@@ -792,7 +792,7 @@ void USBDevice::OnDeviceOpenedOrClosed(bool opened) {
opened_ = opened;
if (!opened_) {
claimed_interfaces_.Fill(false);
- selected_alternates_.Fill(0);
+ selected_alternate_indices_.Fill(0);
in_endpoints_.reset();
out_endpoints_.reset();
}
@@ -825,8 +825,8 @@ void USBDevice::OnConfigurationSelected(bool success,
claimed_interfaces_.Fill(false);
interface_state_change_in_progress_.resize(num_interfaces);
interface_state_change_in_progress_.Fill(false);
- selected_alternates_.resize(num_interfaces);
- selected_alternates_.Fill(0);
+ selected_alternate_indices_.resize(num_interfaces);
+ selected_alternate_indices_.Fill(0);
in_endpoints_.reset();
out_endpoints_.reset();
}
@@ -887,7 +887,7 @@ void USBDevice::OnInterfaceClaimedOrUnclaimed(bool claimed,
claimed_interfaces_[interface_index] = true;
} else {
claimed_interfaces_[interface_index] = false;
- selected_alternates_[interface_index] = 0;
+ selected_alternate_indices_[interface_index] = 0;
}
SetEndpointsForInterface(interface_index, claimed);
interface_state_change_in_progress_[interface_index] = false;
@@ -901,7 +901,7 @@ void USBDevice::AsyncSelectAlternateInterface(wtf_size_t interface_index,
return;
if (success)
- selected_alternates_[interface_index] = alternate_index;
+ selected_alternate_indices_[interface_index] = alternate_index;
SetEndpointsForInterface(interface_index, success);
interface_state_change_in_progress_[interface_index] = false;
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.h b/third_party/blink/renderer/modules/webusb/usb_device.h
index 21231db5f4d6f949b4d371143c631a6f33dcb1e4..cb199d2f2ac4c27f2db7f153d51408e604b5f6f0 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.h
+++ b/third_party/blink/renderer/modules/webusb/usb_device.h
@@ -40,7 +40,7 @@ class USBDevice : public ScriptWrappable,
}
bool IsInterfaceClaimed(wtf_size_t configuration_index,
wtf_size_t interface_index) const;
- wtf_size_t SelectedAlternateInterface(wtf_size_t interface_index) const;
+ wtf_size_t SelectedAlternateInterfaceIndex(wtf_size_t interface_index) const;
// USBDevice.idl
uint8_t usbVersionMajor() const { return Info().usb_version_major; }
@@ -179,7 +179,7 @@ class USBDevice : public ScriptWrappable,
// configured. Use the index returned by FindInterfaceIndex().
WTF::Vector<bool> claimed_interfaces_;
WTF::Vector<bool> interface_state_change_in_progress_;
- WTF::Vector<wtf_size_t> selected_alternates_;
+ WTF::Vector<wtf_size_t> selected_alternate_indices_;
// These bit sets have one entry for each endpoint. Index using the endpoint
// number (lower 4 bits of the endpoint address).
diff --git a/third_party/blink/renderer/modules/webusb/usb_interface.cc b/third_party/blink/renderer/modules/webusb/usb_interface.cc
index bba6f5eb58d56e9372f9cef8e38e2f1493a94678..2ecc28054831e076f85832d97bd95a738d6657b2 100644
--- a/third_party/blink/renderer/modules/webusb/usb_interface.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_interface.cc
@@ -53,7 +53,7 @@ const device::mojom::blink::UsbInterfaceInfo& USBInterface::Info() const {
USBAlternateInterface* USBInterface::alternate() const {
if (device_->IsInterfaceClaimed(configuration_index_, interface_index_)) {
return USBAlternateInterface::Create(
- this, device_->SelectedAlternateInterface(interface_index_));
+ this, device_->SelectedAlternateInterfaceIndex(interface_index_));
}
return USBAlternateInterface::Create(this, 0);
}
diff --git a/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js b/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js
index 975d2242c949740217c050beea72db908ef46fc7..c5c5cadaa6af48f676565775d1dc8e27efffc3a2 100644
--- a/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js
+++ b/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js
@@ -16,75 +16,160 @@ let fakeDeviceInit = {
productName: 'The amazing imaginary printer',
serialNumber: '4',
activeConfigurationValue: 0,
- configurations: [{
- configurationValue: 1,
- configurationName: 'Printer Mode',
- interfaces: [{
- interfaceNumber: 0,
- alternates: [{
- alternateSetting: 0,
- interfaceClass: 0xff,
- interfaceSubclass: 0x01,
- interfaceProtocol: 0x01,
- interfaceName: 'Control',
- endpoints: [{
- endpointNumber: 1,
- direction: 'in',
- type: 'interrupt',
- packetSize: 8
- }]
+ configurations: [
+ {
+ configurationValue: 1,
+ configurationName: 'Printer Mode',
+ interfaces: [
+ {
+ interfaceNumber: 0,
+ alternates: [{
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x01,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Control',
+ endpoints: [{
+ endpointNumber: 1,
+ direction: 'in',
+ type: 'interrupt',
+ packetSize: 8
+ }]
+ }]
+ },
+ {
+ interfaceNumber: 1,
+ alternates: [{
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x02,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Data',
+ endpoints: [
+ {
+ endpointNumber: 2,
+ direction: 'in',
+ type: 'bulk',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 2,
+ direction: 'out',
+ type: 'bulk',
+ packetSize: 1024
+ }
+ ]
+ }]
+ }
+ ]
+ },
+ {
+ configurationValue: 2,
+ configurationName: 'Fighting Robot Mode',
+ interfaces: [{
+ interfaceNumber: 0,
+ alternates: [
+ {
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x42,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Disabled',
+ endpoints: []
+ },
+ {
+ alternateSetting: 1,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x42,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Activate!',
+ endpoints: [
+ {
+ endpointNumber: 1,
+ direction: 'in',
+ type: 'isochronous',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 1,
+ direction: 'out',
+ type: 'isochronous',
+ packetSize: 1024
+ }
+ ]
+ }
+ ]
}]
- }, {
- interfaceNumber: 1,
- alternates: [{
- alternateSetting: 0,
- interfaceClass: 0xff,
- interfaceSubclass: 0x02,
- interfaceProtocol: 0x01,
- interfaceName: 'Data',
- endpoints: [{
- endpointNumber: 2,
- direction: 'in',
- type: 'bulk',
- packetSize: 1024
- }, {
- endpointNumber: 2,
- direction: 'out',
- type: 'bulk',
- packetSize: 1024
- }]
- }]
- }]
- }, {
- configurationValue: 2,
- configurationName: 'Fighting Robot Mode',
- interfaces: [{
- interfaceNumber: 0,
- alternates: [{
- alternateSetting: 0,
- interfaceClass: 0xff,
- interfaceSubclass: 0x42,
- interfaceProtocol: 0x01,
- interfaceName: 'Disabled',
- endpoints: []
- }, {
- alternateSetting: 1,
- interfaceClass: 0xff,
- interfaceSubclass: 0x42,
- interfaceProtocol: 0x01,
- interfaceName: 'Activate!',
- endpoints: [{
- endpointNumber: 1,
- direction: 'in',
- type: 'isochronous',
- packetSize: 1024
- }, {
- endpointNumber: 1,
- direction: 'out',
- type: 'isochronous',
- packetSize: 1024
- }]
- }]
- }]
- }]
+ },
+ {
+ configurationValue: 3,
+ configurationName: 'Non-sequential interface number and alternate ' +
+ 'setting Mode',
+ interfaces: [
+ {
+ interfaceNumber: 0,
+ alternates: [
+ {
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x01,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Control',
+ endpoints: [{
+ endpointNumber: 1,
+ direction: 'in',
+ type: 'interrupt',
+ packetSize: 8
+ }]
+ },
+ {
+ alternateSetting: 2,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x02,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Data',
+ endpoints: [
+ {
+ endpointNumber: 2,
+ direction: 'in',
+ type: 'bulk',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 2,
+ direction: 'out',
+ type: 'bulk',
+ packetSize: 1024
+ }
+ ]
+ }
+ ]
+ },
+ {
+ interfaceNumber: 2,
+ alternates: [{
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x02,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Data',
+ endpoints: [
+ {
+ endpointNumber: 2,
+ direction: 'in',
+ type: 'bulk',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 2,
+ direction: 'out',
+ type: 'bulk',
+ packetSize: 1024
+ }
+ ]
+ }]
+ }
+ ]
+ }
+ ]
};
diff --git a/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js b/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js
index 5bfd841d5248e91a5cabf10d00d78db23d11f0e5..527d238d69b703b1fcf5d8a001d02e9f87b5689a 100644
--- a/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js
@@ -236,10 +236,11 @@ usb_test(() => {
return getFakeDevice().then(({ device }) => {
assert_equals(device.configuration, null);
return device.open()
- .then(() => assertRejectsWithError(
- device.selectConfiguration(3), 'NotFoundError',
- 'The configuration value provided is not supported by the device.'))
- .then(() => device.close());
+ .then(
+ () => assertRejectsWithError(
+ device.selectConfiguration(10), 'NotFoundError',
+ 'The configuration value provided is not supported by the device.'))
+ .then(() => device.close());
});
}, 'selectConfiguration rejects on invalid configurations');
@@ -431,6 +432,30 @@ usb_test(() => {
});
}, 'can select an alternate interface');
+usb_test(
+ async () => {
+ const {device} = await getFakeDevice();
+ await device.open();
+ await device.selectConfiguration(3);
+ await device.claimInterface(2);
+ await device.selectAlternateInterface(2, 0);
+ await device.close();
+ },
+ 'can select an alternate interface on a setting with non-sequential ' +
+ 'interface number');
+
+usb_test(
+ async () => {
+ const {device} = await getFakeDevice();
+ await device.open();
+ await device.selectConfiguration(3);
+ await device.claimInterface(0);
+ await device.selectAlternateInterface(0, 2);
+ await device.close();
+ },
+ 'can select an alternate interface on a setting with non-sequential ' +
+ 'alternative setting value');
+
usb_test(() => {
return getFakeDevice().then(({ device }) => {
return device.open()

View File

@@ -0,0 +1,195 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Mon, 2 May 2022 23:43:40 +0000
Subject: Markup sanitization should iterate until markup is stable
There are cases where parsing a markup and then serializing it does not
round trip, which can be used to inject XSS. Current sanitization code
only does one round of parsing and serializing, which does not remove
XSS injections that hide deeper.
Hence this patch makes sanitization algorithm iterate until the markup
is stable, or declares failure if it doesn't stabilize after many tries.
(cherry picked from commit 19280353fb92d0ff7d048d7cec28d6a23befbce0)
Fixed: 1315563
Change-Id: I4a3ebe1fda6df0e04a24d863b2b48df2110af209
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3611826
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#997032}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3621618
Auto-Submit: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/branch-heads/5005@{#363}
Cr-Branched-From: 5b4d9450fee01f821b6400e947b3839727643a71-refs/heads/main@{#992738}
diff --git a/third_party/blink/renderer/core/editing/serializers/serialization.cc b/third_party/blink/renderer/core/editing/serializers/serialization.cc
index 4ee332fa16a1bda54e6ba99c8063876fb046adaa..463fd9a37671b92c9af68ff5f3c0e8ddd5f1c62c 100644
--- a/third_party/blink/renderer/core/editing/serializers/serialization.cc
+++ b/third_party/blink/renderer/core/editing/serializers/serialization.cc
@@ -835,6 +835,12 @@ static bool StripSVGUseDataURLs(Node& node) {
return stripped;
}
+namespace {
+
+constexpr unsigned kMaxSanitizationIterations = 16;
+
+} // namespace
+
DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext(
Document& document,
const String& raw_markup,
@@ -844,42 +850,56 @@ DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext(
if (raw_markup.IsEmpty())
return nullptr;
- Document* staging_document = CreateStagingDocumentForMarkupSanitization(
- *document.GetFrame()->GetFrameScheduler()->GetAgentGroupScheduler());
- Element* body = staging_document->body();
-
- DocumentFragment* fragment = CreateFragmentFromMarkupWithContext(
- *staging_document, raw_markup, fragment_start, fragment_end, KURL(),
- kDisallowScriptingAndPluginContent);
- if (!fragment) {
- staging_document->GetPage()->WillBeDestroyed();
- return nullptr;
- }
+ // Iterate on parsing, sanitization and serialization until the markup is
+ // stable, or if we have exceeded the maximum allowed number of iterations.
+ String last_markup;
+ String markup = raw_markup;
+ for (unsigned iteration = 0;
+ iteration < kMaxSanitizationIterations && last_markup != markup;
+ ++iteration) {
+ last_markup = markup;
+
+ Document* staging_document = CreateStagingDocumentForMarkupSanitization(
+ *document.GetFrame()->GetFrameScheduler()->GetAgentGroupScheduler());
+ Element* body = staging_document->body();
+
+ DocumentFragment* fragment = CreateFragmentFromMarkupWithContext(
+ *staging_document, last_markup, fragment_start, fragment_end, KURL(),
+ kDisallowScriptingAndPluginContent);
+ if (!fragment) {
+ staging_document->GetPage()->WillBeDestroyed();
+ return nullptr;
+ }
- bool needs_sanitization = false;
- if (ContainsStyleElements(*fragment))
- needs_sanitization = true;
- if (StripSVGUseDataURLs(*fragment))
- needs_sanitization = true;
+ bool needs_sanitization = false;
+ if (ContainsStyleElements(*fragment))
+ needs_sanitization = true;
+ if (StripSVGUseDataURLs(*fragment))
+ needs_sanitization = true;
- if (!needs_sanitization) {
+ if (!needs_sanitization) {
+ markup = CreateMarkup(fragment);
+ } else {
+ body->appendChild(fragment);
+ staging_document->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
+
+ // This sanitizes stylesheets in the markup into element inline styles
+ markup = CreateMarkup(Position::FirstPositionInNode(*body),
+ Position::LastPositionInNode(*body),
+ CreateMarkupOptions::Builder()
+ .SetShouldAnnotateForInterchange(true)
+ .SetIsForMarkupSanitization(true)
+ .Build());
+ }
staging_document->GetPage()->WillBeDestroyed();
- return CreateFragmentFromMarkupWithContext(
- document, raw_markup, fragment_start, fragment_end, base_url,
- kDisallowScriptingAndPluginContent);
+
+ fragment_start = 0;
+ fragment_end = markup.length();
}
- body->appendChild(fragment);
- staging_document->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
-
- // This sanitizes stylesheets in the markup into element inline styles
- String markup = CreateMarkup(Position::FirstPositionInNode(*body),
- Position::LastPositionInNode(*body),
- CreateMarkupOptions::Builder()
- .SetShouldAnnotateForInterchange(true)
- .SetIsForMarkupSanitization(true)
- .Build());
- staging_document->GetPage()->WillBeDestroyed();
+ // Sanitization failed because markup can't stabilize.
+ if (last_markup != markup)
+ return nullptr;
return CreateFragmentFromMarkup(document, markup, base_url,
kDisallowScriptingAndPluginContent);
diff --git a/third_party/blink/web_tests/editing/pasteboard/paste-svg-use.html b/third_party/blink/web_tests/editing/pasteboard/paste-svg-use.html
index c03ca90d492a5e2af883f68811baa7660ef1cdc2..1af77f8faa4501f577e28297f013e170775bc86a 100644
--- a/third_party/blink/web_tests/editing/pasteboard/paste-svg-use.html
+++ b/third_party/blink/web_tests/editing/pasteboard/paste-svg-use.html
@@ -32,6 +32,6 @@ selection_test(
<use href=data:application/xml;base64,PHN2ZyBpZD0neCcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJz4KPGEgaHJlZj0namF2YXNjcmlwdDphbGVydCgxMjMpJz4KICAgIDxyZWN0IHdpZHRoPScxMDAlJyBoZWlnaHQ9JzEwMCUnIGZpbGw9J2xpZ2h0Ymx1ZScgLz4KICAgICA8dGV4dCB4PScwJyB5PScwJyBmaWxsPSdibGFjayc+CiAgICAgICA8dHNwYW4geD0nMCcgZHk9JzEuMmVtJz5Pb3BzLCB0aGVyZSdzIHNvbWV0aGluZyB3cm9uZyB3aXRoIHRoZSBwYWdlITwvdHNwYW4+CiAgICAgPHRzcGFuIHg9JzAnIGR5PScxLjJlbSc+UGxlYXNlIGNsaWNrIGhlcmUgdG8gcmVsb2FkLjwvdHNwYW4+Cjwvc3ZnPg==#x>"></noscript>asdasd`);
selection.document.execCommand('paste');
},
- '<div contenteditable>|<noscript>&lt;u title="</noscript><div contenteditable="false"><svg></svg></div></div>',
+ '<div contenteditable><div><br></div><div>      <u title="</div><div>      </div><div>      ">asdasd|</div></div>',
'Paste blocks data URI in SVG use element injection via <noscript>');
</script>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html
new file mode 100644
index 0000000000000000000000000000000000000000..9e0ab2ee740f85ea4e9de9d3f1d2ac43bee5a985
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Async Clipboard.read() should sanitize text/html</title>
+<link rel="help" href="https://w3c.github.io/clipboard-apis/#dom-clipboard-read">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1315563">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<p><button id="button">Put payload in the clipboard</button></p>
+<div id="output"></div>
+
+<script>
+let testFailed = false;
+function fail() {
+ testFailed = true;
+}
+
+button.onclick = () => document.execCommand('copy');
+document.oncopy = ev => {
+ ev.preventDefault();
+ ev.clipboardData.setData(
+ 'text/html',
+ `<form><math><mtext></form><form><mglyph><xmp></math><img src=invalid onerror=fail()></xmp>`);
+};
+
+promise_test(async test => {
+ await test_driver.set_permission({name: 'clipboard-read'}, 'granted');
+ await test_driver.click(button);
+
+ const items = await navigator.clipboard.read();
+ const htmlBlob = await items[0].getType("text/html");
+ const html = await htmlBlob.text();
+
+ // This inserts an image with `onerror` handler if `html` is not properly sanitized
+ output.innerHTML = html;
+
+ // Allow the 'error' event to be dispatched asynchronously
+ await new Promise(resolve => test.step_timeout(resolve, 100));
+
+ assert_false(testFailed);
+});
+</script>

View File

@@ -0,0 +1,160 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Corentin Pescheloche <cpescheloche@fb.com>
Date: Tue, 10 May 2022 14:05:53 +0000
Subject: Cleanup profiler group detached profilers
ProfilerGroup keeps track of detached profilers to be able to gracefully
stop leaked profilers when the corresponding ExecutionContext is
destroyed.
(cherry picked from commit 9f9d5fd2f3085414fc8776bf556fb5c4fa2dac2c)
Change-Id: I4fdbbc3a5208819397d742c9ecbff117f839691c
Bug: chromium:1297283
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3594570
Commit-Queue: Corentin Pescheloche <cpescheloche@fb.com>
Cr-Original-Commit-Position: refs/heads/main@{#994316}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3620956
Reviewed-by: Oleh Lamzin <lamzin@google.com>
Owners-Override: Oleh Lamzin <lamzin@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Auto-Submit: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1629}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/core/timing/profiler_group.cc b/third_party/blink/renderer/core/timing/profiler_group.cc
index 6638ee38519674036c6c45cf6cd1a4eff023289b..f498a122f5a491226720a36dc729364028148eaa 100644
--- a/third_party/blink/renderer/core/timing/profiler_group.cc
+++ b/third_party/blink/renderer/core/timing/profiler_group.cc
@@ -110,8 +110,7 @@ ProfilerGroup::ProfilerGroup(v8::Isolate* isolate)
: isolate_(isolate),
cpu_profiler_(nullptr),
next_profiler_id_(0),
- num_active_profilers_(0) {
-}
+ num_active_profilers_(0) {}
void DiscardedSamplesDelegate::Notify() {
if (profiler_group_) {
@@ -234,6 +233,8 @@ void ProfilerGroup::WillBeDestroyed() {
DCHECK(!profilers_.Contains(profiler));
}
+ StopDetachedProfilers();
+
if (cpu_profiler_)
TeardownV8Profiler();
}
@@ -304,18 +305,49 @@ void ProfilerGroup::CancelProfiler(Profiler* profiler) {
void ProfilerGroup::CancelProfilerAsync(ScriptState* script_state,
Profiler* profiler) {
+ DCHECK(IsMainThread());
DCHECK(cpu_profiler_);
DCHECK(!profiler->stopped());
profilers_.erase(profiler);
+ // register the profiler to be cleaned up in case its associated context
+ // gets destroyed before the cleanup task is executed.
+ detached_profiler_ids_.push_back(profiler->ProfilerId());
+
// Since it's possible for the profiler to get destructed along with its
// associated context, dispatch a task to cleanup context-independent isolate
// resources (rather than use the context's task runner).
ThreadScheduler::Current()->V8TaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&ProfilerGroup::CancelProfilerImpl,
+ FROM_HERE, WTF::Bind(&ProfilerGroup::StopDetachedProfiler,
WrapPersistent(this), profiler->ProfilerId()));
}
+void ProfilerGroup::StopDetachedProfiler(String profiler_id) {
+ DCHECK(IsMainThread());
+
+ // we use a vector instead of a map because the expected number of profiler
+ // is expected to be very small
+ auto* it = std::find(detached_profiler_ids_.begin(),
+ detached_profiler_ids_.end(), profiler_id);
+
+ if (it == detached_profiler_ids_.end()) {
+ // Profiler already stopped
+ return;
+ }
+
+ CancelProfilerImpl(profiler_id);
+ detached_profiler_ids_.erase(it);
+}
+
+void ProfilerGroup::StopDetachedProfilers() {
+ DCHECK(IsMainThread());
+
+ for (auto& detached_profiler_id : detached_profiler_ids_) {
+ CancelProfilerImpl(detached_profiler_id);
+ }
+ detached_profiler_ids_.clear();
+}
+
void ProfilerGroup::CancelProfilerImpl(String profiler_id) {
if (!cpu_profiler_)
return;
diff --git a/third_party/blink/renderer/core/timing/profiler_group.h b/third_party/blink/renderer/core/timing/profiler_group.h
index 2cdbd795f4265086073b8c378ede4f7c6c60e3e3..ede25fa5656f32d1982077eda43585b70743fd63 100644
--- a/third_party/blink/renderer/core/timing/profiler_group.h
+++ b/third_party/blink/renderer/core/timing/profiler_group.h
@@ -81,6 +81,10 @@ class CORE_EXPORT ProfilerGroup
// Internal implementation of cancel.
void CancelProfilerImpl(String profiler_id);
+ // Clean context independent resources for leaked profilers
+ void StopDetachedProfiler(String profiler_id);
+ void StopDetachedProfilers();
+
// Generates an unused string identifier to use for a new profiling session.
String NextProfilerId();
@@ -88,9 +92,11 @@ class CORE_EXPORT ProfilerGroup
v8::CpuProfiler* cpu_profiler_;
int next_profiler_id_;
int num_active_profilers_;
-
HeapHashSet<WeakMember<Profiler>> profilers_;
+ // Store the ids of leaked collected profilers that needs to be stopped
+ Vector<String> detached_profiler_ids_;
+
// A set of observers, one for each ExecutionContext that has profiling
// enabled.
HeapHashSet<Member<ProfilingContextObserver>> context_observers_;
diff --git a/third_party/blink/renderer/core/timing/profiler_group_test.cc b/third_party/blink/renderer/core/timing/profiler_group_test.cc
index adedff31f007ca2deff401ec93b39641f4ea516e..1c6dd092c36a27710085a03c74fa12e212adccb4 100644
--- a/third_party/blink/renderer/core/timing/profiler_group_test.cc
+++ b/third_party/blink/renderer/core/timing/profiler_group_test.cc
@@ -262,4 +262,29 @@ TEST(ProfilerGroupTest, LeakProfilerWithContext) {
test::RunPendingTasks();
}
+// Tests that a ProfilerGroup doesn't crash if the ProfilerGroup is destroyed
+// before a Profiler::Dispose is ran.
+TEST(ProfilerGroupTest, Bug1297283) {
+ {
+ V8TestingScope scope;
+ ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate());
+ profiler_group->OnProfilingContextAdded(scope.GetExecutionContext());
+
+ ProfilerInitOptions* init_options = ProfilerInitOptions::Create();
+ init_options->setSampleInterval(0);
+ init_options->setMaxBufferSize(0);
+ Profiler* profiler = profiler_group->CreateProfiler(
+ scope.GetScriptState(), *init_options, base::TimeTicks(),
+ scope.GetExceptionState());
+ EXPECT_FALSE(profiler->stopped());
+
+ // Force a collection of the underlying Profiler
+ profiler = nullptr;
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ // Exit Scope deallocating Context triggering ProfilerGroup::WillBeDestroyed
+ // Ensure doesn't crash.
+ }
+ test::RunPendingTasks();
+}
+
} // namespace blink

View File

@@ -0,0 +1,68 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Justin Novosad <junov@chromium.org>
Date: Thu, 2 Jun 2022 19:35:57 +0000
Subject: PaintOpReader: Harden PaintImage deserialization
This fix prevents the deserialization of PaintImage pixel data from
reading data out of bounds when the block of serialized pixel data isn't
large enough to cover the expected amount of data, given the size and
format of the image.
(cherry picked from commit e89ea1489429a9a9e49e70d5d4e8d018fbafb6ac)
Bug: 1325298
Change-Id: Icbeb405d2031d7d8ce4537836d7996ce7885f6d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3669596
Commit-Queue: Justin Novosad <junov@chromium.org>
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1007804}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3687975
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Justin Novosad <junov@chromium.org>
Auto-Submit: Srinivas Sista <srinivassista@chromium.org>
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
Cr-Commit-Position: refs/branch-heads/5005@{#1093}
Cr-Branched-From: 5b4d9450fee01f821b6400e947b3839727643a71-refs/heads/main@{#992738}
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc
index d71230cfc47944ca538ec8e007f652640e752b63..e34a5fb540dfa2626ab4d0a655e4ba85aa2b8921 100644
--- a/cc/paint/paint_op_reader.cc
+++ b/cc/paint/paint_op_reader.cc
@@ -329,6 +329,10 @@ void PaintOpReader::Read(PaintImage* image) {
SkImageInfo image_info =
SkImageInfo::Make(width, height, color_type, kPremul_SkAlphaType);
+ if (pixel_size < image_info.computeMinByteSize()) {
+ SetInvalid(DeserializationError::kInsufficientPixelData);
+ return;
+ }
const volatile void* pixel_data = ExtractReadableMemory(pixel_size);
if (!valid_)
return;
diff --git a/cc/paint/paint_op_reader.h b/cc/paint/paint_op_reader.h
index 201cdfde5eea3a07e31a3d6a50a5119485d5c1fc..af784145a9365ea2f776a1020145c0b83c63f16d 100644
--- a/cc/paint/paint_op_reader.h
+++ b/cc/paint/paint_op_reader.h
@@ -180,8 +180,9 @@ class CC_PAINT_EXPORT PaintOpReader {
kSharedImageProviderNoAccess = 50,
kSharedImageProviderSkImageCreationFailed = 51,
kZeroSkColorFilterBytes = 52,
+ kInsufficientPixelData = 53,
- kMaxValue = kZeroSkColorFilterBytes,
+ kMaxValue = kInsufficientPixelData
};
template <typename T>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 5faaf3cfd3c0231ad34f651023aeec5d74d9c19b..e15f292c099cfc8bf9cb8613f73517f2f241d91f 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -66406,6 +66406,7 @@ Called by update_net_trust_anchors.py.-->
<int value="50" label="SharedImageProvider no access"/>
<int value="51" label="SharedImageProvider SkImage creation failed"/>
<int value="52" label="Zero SkColorFilter bytes"/>
+ <int value="53" label="Insufficient Pixel Data"/>
</enum>
<enum name="PaletteModeCancelType">

View File

@@ -0,0 +1,229 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Sullivan <asully@chromium.org>
Date: Mon, 16 May 2022 18:20:27 +0000
Subject: M102: FSA: Sanitize .scf files
.scf files can be used to execute code without opening the file.
Sanitize these files the same way we sanitize .lnk files.
Also updates filename sanitization logic to be consistent in blocking
.lnk and .local extensions on all OSes.
(cherry picked from commit 988164c6c4a563c3d4c0dedba295d09472dfc15f)
Bug: 1227995
Change-Id: I4b018f1ba524c783547e18630db9addc9fb126e6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3089422
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1002147}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3648322
Auto-Submit: Austin Sullivan <asully@chromium.org>
Commit-Queue: Austin Sullivan <asully@chromium.org>
Cr-Commit-Position: refs/branch-heads/5005@{#759}
Cr-Branched-From: 5b4d9450fee01f821b6400e947b3839727643a71-refs/heads/main@{#992738}
diff --git a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
index 22e0fa6d237bda2819916d630a4de5583e56fe10..b6e3c97f044e1babbf8489b95e6db311ae8385b6 100644
--- a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
+++ b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
@@ -438,10 +438,13 @@ namespace {
bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
base::FilePath::StringType extension_lower = base::ToLowerASCII(extension);
- // .lnk files may be used to execute arbitrary code (see
- // https://nvd.nist.gov/vuln/detail/CVE-2010-2568).
- if (extension_lower == FILE_PATH_LITERAL("lnk"))
+ // .lnk and .scf files may be used to execute arbitrary code (see
+ // https://nvd.nist.gov/vuln/detail/CVE-2010-2568 and
+ // https://crbug.com/1227995, respectively).
+ if (extension_lower == FILE_PATH_LITERAL("lnk") ||
+ extension_lower == FILE_PATH_LITERAL("scf")) {
return true;
+ }
// Setting a file's extension to a CLSID may conceal its actual file type on
// some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420).
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.cc b/content/browser/file_system_access/file_system_access_manager_impl.cc
index ac3fc8ceade37805dafcafd0b9e44eb2a196513a..e2b13687d664b0ee29c320d89cc6ee00d6134717 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl.cc
+++ b/content/browser/file_system_access/file_system_access_manager_impl.cc
@@ -517,6 +517,16 @@ void FileSystemAccessManagerImpl::SetDefaultPathAndShowPicker(
suggested_name_path =
net::GenerateFileName(GURL(), std::string(), std::string(),
suggested_name, std::string(), std::string());
+
+ auto suggested_extension = suggested_name_path.Extension();
+ // Our version of `IsShellIntegratedExtension()` is more stringent than
+ // the version used in `net::GenerateFileName()`. See
+ // `FileSystemChooser::IsShellIntegratedExtension()` for details.
+ if (FileSystemChooser::IsShellIntegratedExtension(suggested_extension)) {
+ suggested_extension = FILE_PATH_LITERAL("download");
+ suggested_name_path =
+ suggested_name_path.ReplaceExtension(suggested_extension);
+ }
}
FileSystemChooser::Options file_system_chooser_options(
diff --git a/content/browser/file_system_access/file_system_chooser.cc b/content/browser/file_system_access/file_system_chooser.cc
index 6c5665aff03c28b8d4699aafcfda48648db3f47d..2f9d3b4dc999bbc7ddb16c05f2f1dd3ec12f6e15 100644
--- a/content/browser/file_system_access/file_system_chooser.cc
+++ b/content/browser/file_system_access/file_system_chooser.cc
@@ -71,33 +71,6 @@ base::FilePath::StringType GetLastExtension(
: extension;
}
-// Returns whether the specified extension receives special handling by the
-// Windows shell.
-bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
- // TODO(https://crbug.com/1154757): Figure out some way to unify this with
- // net::IsSafePortablePathComponent, with the result probably ending up in
- // base/i18n/file_util_icu.h.
- base::FilePath::StringType extension_lower = base::ToLowerASCII(extension);
-
- // .lnk files may be used to execute arbitrary code (see
- // https://nvd.nist.gov/vuln/detail/CVE-2010-2568). .local files are used by
- // Windows to determine which DLLs to load for an application.
- if ((extension_lower == FILE_PATH_LITERAL("local")) ||
- (extension_lower == FILE_PATH_LITERAL("lnk"))) {
- return true;
- }
-
- // Setting a file's extension to a CLSID may conceal its actual file type on
- // some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420).
- if (!extension_lower.empty() &&
- (extension_lower.front() == FILE_PATH_LITERAL('{')) &&
- (extension_lower.back() == FILE_PATH_LITERAL('}'))) {
- return true;
- }
-
- return false;
-}
-
// Extension validation primarily takes place in the renderer. This checks for a
// subset of invalid extensions in the event the renderer is compromised.
bool IsInvalidExtension(base::FilePath::StringType& extension) {
@@ -105,7 +78,7 @@ bool IsInvalidExtension(base::FilePath::StringType& extension) {
auto extension16 = base::UTF8ToUTF16(component8);
return !base::i18n::IsFilenameLegal(extension16) ||
- IsShellIntegratedExtension(GetLastExtension(extension));
+ FileSystemChooser::IsShellIntegratedExtension(extension);
}
// Converts the accepted mime types and extensions from `option` into a list
@@ -290,6 +263,40 @@ void FileSystemChooser::CreateAndShow(
/*params=*/nullptr);
}
+// static
+bool FileSystemChooser::IsShellIntegratedExtension(
+ const base::FilePath::StringType& extension) {
+ // TODO(https://crbug.com/1154757): Figure out some way to unify this with
+ // net::IsSafePortablePathComponent, with the result probably ending up in
+ // base/i18n/file_util_icu.h.
+ // - For the sake of consistency across platforms, we sanitize '.lnk' and
+ // '.local' files on all platforms (not just Windows)
+ // - There are some extensions (i.e. '.scf') we would like to sanitize which
+ // `net::GenerateFileName()` does not
+ base::FilePath::StringType extension_lower =
+ base::ToLowerASCII(GetLastExtension(extension));
+
+ // .lnk and .scf files may be used to execute arbitrary code (see
+ // https://nvd.nist.gov/vuln/detail/CVE-2010-2568 and
+ // https://crbug.com/1227995, respectively). .local files are used by Windows
+ // to determine which DLLs to load for an application.
+ if ((extension_lower == FILE_PATH_LITERAL("lnk")) ||
+ (extension_lower == FILE_PATH_LITERAL("local")) ||
+ (extension_lower == FILE_PATH_LITERAL("scf"))) {
+ return true;
+ }
+
+ // Setting a file's extension to a CLSID may conceal its actual file type on
+ // some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420).
+ if (!extension_lower.empty() &&
+ (extension_lower.front() == FILE_PATH_LITERAL('{')) &&
+ (extension_lower.back() == FILE_PATH_LITERAL('}'))) {
+ return true;
+ }
+
+ return false;
+}
+
FileSystemChooser::FileSystemChooser(ui::SelectFileDialog::Type type,
ResultCallback callback,
base::ScopedClosureRunner fullscreen_block)
diff --git a/content/browser/file_system_access/file_system_chooser.h b/content/browser/file_system_access/file_system_chooser.h
index 07c8e7fda7d96496f58ed9a9e6cba6558c8c37df..925df7f5ef1d1bb94926afbe29beda248ae5aabc 100644
--- a/content/browser/file_system_access/file_system_chooser.h
+++ b/content/browser/file_system_access/file_system_chooser.h
@@ -68,6 +68,12 @@ class CONTENT_EXPORT FileSystemChooser : public ui::SelectFileDialog::Listener {
ResultCallback callback,
base::ScopedClosureRunner fullscreen_block);
+ // Returns whether the specified extension receives special handling by the
+ // Windows shell. These extensions should be sanitized before being shown in
+ // the "save as" file picker.
+ static bool IsShellIntegratedExtension(
+ const base::FilePath::StringType& extension);
+
FileSystemChooser(ui::SelectFileDialog::Type type,
ResultCallback callback,
base::ScopedClosureRunner fullscreen_block);
diff --git a/content/browser/file_system_access/file_system_chooser_browsertest.cc b/content/browser/file_system_access/file_system_chooser_browsertest.cc
index b5bebd08526f684337194a8cc0f08a0b345a65a7..6033251755d68d83bc5c8300630eaebacbd2f3ce 100644
--- a/content/browser/file_system_access/file_system_chooser_browsertest.cc
+++ b/content/browser/file_system_access/file_system_chooser_browsertest.cc
@@ -1557,21 +1557,28 @@ IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, SuggestedName) {
"not_matching.jpg", false});
#if defined(OS_WIN)
- // ".local" and ".lnk" extensions should be sanitized on Windows.
+ // ".lnk", ".local", and ".scf" extensions should be sanitized.
name_infos.push_back({"dangerous_extension.local", ListValueOf(".local"),
true, "dangerous_extension.download", false});
name_infos.push_back({"dangerous_extension.lnk", ListValueOf(".lnk"), true,
"dangerous_extension.download", false});
-#else
- // ".local" and ".lnk" extensions should be allowed on other OSes.
- // TODO(https://crbug.com/1154757): `expected_exclude_accept_all_option` is
- // false here because ".local" and ".lnk" extensions are not allowed in
- // `accepts`, but are only sanitized by net::GenerateSafeFileName on Windows.
- name_infos.push_back({"dangerous_extension.local", ListValueOf(".local"),
- true, "dangerous_extension.local", false});
- name_infos.push_back({"dangerous_extension.lnk", ListValueOf(".lnk"), true,
- "dangerous_extension.lnk", false});
-#endif
+ name_infos.push_back({"dangerous_extension.scf", ListValueOf(".scf"), true,
+ "dangerous_extension.download", false});
+ // Compound extensions ending in a dangerous extension should be sanitized.
+ name_infos.push_back({"dangerous_extension.png.local", ListValueOf(".local"),
+ true, "dangerous_extension.png.download", false});
+ name_infos.push_back({"dangerous_extension.png.lnk", ListValueOf(".lnk"),
+ true, "dangerous_extension.png.download", false});
+ name_infos.push_back({"dangerous_extension.png.scf", ListValueOf(".scf"),
+ true, "dangerous_extension.png.download", false});
+ // Compound extensions not ending in a dangerous extension should not be
+ // sanitized.
+ name_infos.push_back({"dangerous_extension.local.png", ListValueOf(".png"),
+ true, "dangerous_extension.local.png", true});
+ name_infos.push_back({"dangerous_extension.lnk.png", ListValueOf(".png"),
+ true, "dangerous_extension.lnk.png", true});
+ name_infos.push_back({"dangerous_extension.scf.png", ListValueOf(".png"),
+ true, "dangerous_extension.scf.png", true});
// Invalid characters should be sanitized.
name_infos.push_back({R"(inv*l:d\\ch%rבאמת!a<ters🤓.txt)",
ListValueOf(".txt"), true,
diff --git a/content/browser/file_system_access/file_system_chooser_unittest.cc b/content/browser/file_system_access/file_system_chooser_unittest.cc
index 373de41cf5ddead27b5e036c1cc14448a731250a..9b27d6305bd00a19d94b5ec49f21a7ecff7ddc48 100644
--- a/content/browser/file_system_access/file_system_chooser_unittest.cc
+++ b/content/browser/file_system_access/file_system_chooser_unittest.cc
@@ -189,7 +189,7 @@ TEST_F(FileSystemChooserTest, IgnoreShellIntegratedExtensions) {
accepts.emplace_back(blink::mojom::ChooseFileSystemEntryAcceptsOption::New(
u"", std::vector<std::string>({}),
std::vector<std::string>(
- {"lnk", "foo.lnk", "foo.bar.local", "text", "local"})));
+ {"lnk", "foo.lnk", "foo.bar.local", "text", "local", "scf"})));
SyncShowDialog(std::move(accepts), /*include_accepts_all=*/false);
ASSERT_TRUE(dialog_params.file_types);

View File

@@ -0,0 +1,123 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alvin Ji <alvinji@chromium.org>
Date: Thu, 28 Apr 2022 00:44:28 +0000
Subject: Introduce isLowEnergyDevice() for safely downward static_cast from
BluetoothDeviceMac to BluetoothLowEnergyDeviceMac
device/bluetooth/bluetooth_adapter_mac.mm has two non safely downward static_cast BluetoothDevice to BluetoothLowEnergyDeviceMac
To avoid it, we introduce isLowEnergyDevice() to BluetoothDeviceMac so we could identify LE bluetooth device from classic bluetooth device then safely cast it downward.
(cherry picked from commit 2582158fc555edee390a050a64c1b89994a6b349)
Bug: 1318610
Change-Id: Iaf082fc2c40270237bbc0b000b80faa7f94b1026
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3601727
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Alvin Ji <alvinji@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#995419}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3606585
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5005@{#217}
Cr-Branched-From: 5b4d9450fee01f821b6400e947b3839727643a71-refs/heads/main@{#992738}
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index 902e77ce90a60c835a9a324decf3d0dd094f1c85..947dec239a51d3965de69d99e509931f27811c33 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -764,6 +764,11 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
DVLOG(1)
<< "Central no longer powered on. Notifying of device disconnection.";
for (BluetoothDevice* device : GetDevices()) {
+ // GetDevices() returns instances of BluetoothClassicDeviceMac and
+ // BluetoothLowEnergyDeviceMac. The DidDisconnectPeripheral() method is
+ // only available on BluetoothLowEnergyDeviceMac.
+ if (!static_cast<BluetoothDeviceMac*>(device)->IsLowEnergyDevice())
+ continue;
BluetoothLowEnergyDeviceMac* device_mac =
static_cast<BluetoothLowEnergyDeviceMac*>(device);
if (device_mac->IsGattConnected()) {
@@ -901,9 +906,16 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
auto iter = devices_.find(device_address);
if (iter == devices_.end()) {
- return nil;
- }
- return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second.get());
+ return nullptr;
+ }
+ // device_mac can be BluetoothClassicDeviceMac* or
+ // BluetoothLowEnergyDeviceMac* To return valid BluetoothLowEnergyDeviceMac*
+ // we need to first check with IsLowEnergyDevice()
+ BluetoothDeviceMac* device_mac =
+ static_cast<BluetoothDeviceMac*>(iter->second.get());
+ return device_mac->IsLowEnergyDevice()
+ ? static_cast<BluetoothLowEnergyDeviceMac*>(device_mac)
+ : nullptr;
}
bool BluetoothAdapterMac::DoesCollideWithKnownDevice(
diff --git a/device/bluetooth/bluetooth_classic_device_mac.h b/device/bluetooth/bluetooth_classic_device_mac.h
index b11dbbdec75ca276c6e9df50a00e4e3a97d5be8c..a7deb96690e2b64ed82ede5ade5591935ec0f308 100644
--- a/device/bluetooth/bluetooth_classic_device_mac.h
+++ b/device/bluetooth/bluetooth_classic_device_mac.h
@@ -82,6 +82,7 @@ class BluetoothClassicDeviceMac : public BluetoothDeviceMac {
// Returns the Bluetooth address for the |device|. The returned address has a
// normalized format (see below).
static std::string GetDeviceAddress(IOBluetoothDevice* device);
+ bool IsLowEnergyDevice() override;
protected:
// BluetoothDevice override
diff --git a/device/bluetooth/bluetooth_classic_device_mac.mm b/device/bluetooth/bluetooth_classic_device_mac.mm
index 3794ce8d808fe611f73d76177f0eb6890fc038c2..e98d27462abdfe080129026c58cf74fd1807914e 100644
--- a/device/bluetooth/bluetooth_classic_device_mac.mm
+++ b/device/bluetooth/bluetooth_classic_device_mac.mm
@@ -296,4 +296,8 @@ BluetoothUUID ExtractUuid(IOBluetoothSDPDataElement* service_class_data) {
base::SysNSStringToUTF8([device addressString]));
}
+bool BluetoothClassicDeviceMac::IsLowEnergyDevice() {
+ return false;
+}
+
} // namespace device
diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h
index 10245db6516b08a8e50e6637011a3a960440625c..0213e20aee170aae0a4b73e93f47c418110ef289 100644
--- a/device/bluetooth/bluetooth_device_mac.h
+++ b/device/bluetooth/bluetooth_device_mac.h
@@ -30,6 +30,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceMac : public BluetoothDevice {
BluetoothGattService::GattErrorCode error_code);
static BluetoothGattService::GattErrorCode GetGattErrorCodeFromNSError(
NSError* error);
+ virtual bool IsLowEnergyDevice() = 0;
protected:
BluetoothDeviceMac(BluetoothAdapterMac* adapter);
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.h b/device/bluetooth/bluetooth_low_energy_device_mac.h
index 75988caca296d7f6d766a35f60f2ee1d6cec2246..05d3d514039df5db84d311471d58c2005b3db08f 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.h
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.h
@@ -83,6 +83,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac
const device::BluetoothUUID& uuid,
ConnectToServiceCallback callback,
ConnectToServiceErrorCallback error_callback) override;
+ bool IsLowEnergyDevice() override;
protected:
// BluetoothDevice override.
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm
index 9a89728b0fc47cd7ca6e20d2ffbe7483010cbe39..73b1bee8e64664bdc98e45869accdf0ade2250b0 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.mm
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm
@@ -207,6 +207,10 @@ @interface CBPeripheral (HighSierraSDK)
NOTIMPLEMENTED();
}
+bool BluetoothLowEnergyDeviceMac::IsLowEnergyDevice() {
+ return true;
+}
+
void BluetoothLowEnergyDeviceMac::CreateGattConnectionImpl(
absl::optional<BluetoothUUID> serivce_uuid) {
if (!IsGattConnected()) {

View File

@@ -0,0 +1,83 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 22 Feb 2022 11:51:08 +0100
Subject: Fix --without-valid build
Regressed in commit 652dd12a.
diff --git a/third_party/libxml/src/valid.c b/third_party/libxml/src/valid.c
index 8e596f1db3db40a5decc5f4b529abc7588c6bd66..9684683a08018ca1185f85414f358791bfb1264b 100644
--- a/third_party/libxml/src/valid.c
+++ b/third_party/libxml/src/valid.c
@@ -479,35 +479,6 @@ nodeVPop(xmlValidCtxtPtr ctxt)
return (ret);
}
-/**
- * xmlValidNormalizeString:
- * @str: a string
- *
- * Normalize a string in-place.
- */
-static void
-xmlValidNormalizeString(xmlChar *str) {
- xmlChar *dst;
- const xmlChar *src;
-
- if (str == NULL)
- return;
- src = str;
- dst = str;
-
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
-}
-
#ifdef DEBUG_VALID_ALGO
static void
xmlValidPrintNode(xmlNodePtr cur) {
@@ -2636,6 +2607,35 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
+/**
+ * xmlValidNormalizeString:
+ * @str: a string
+ *
+ * Normalize a string in-place.
+ */
+static void
+xmlValidNormalizeString(xmlChar *str) {
+ xmlChar *dst;
+ const xmlChar *src;
+
+ if (str == NULL)
+ return;
+ src = str;
+ dst = str;
+
+ while (*src == 0x20) src++;
+ while (*src != 0) {
+ if (*src == 0x20) {
+ while (*src == 0x20) src++;
+ if (*src != 0)
+ *dst++ = 0x20;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
static int
xmlIsStreaming(xmlValidCtxtPtr ctxt) {
xmlParserCtxtPtr pctxt;

View File

@@ -0,0 +1,404 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Sullivan <asully@chromium.org>
Date: Fri, 11 Mar 2022 10:08:55 +0000
Subject: FSA: Pass File ownership to worker for async FSARFD file operations
We cannot access the backing file as a member of the
FileSystemAccessRegularFileDelegate since WrapCrossThreadPersistent
does NOT cancel the task posted to the worker pool if delegate is
destroyed. Passing ownership to the worker task ensures the file must
be alive when used. After the operation, ownership of the file is
passed back to the delegate.
This pattern was already used for the SetLength operation on old Macs.
Bug: 1299743
Change-Id: Ie00c09e8f77dc353f280af726a68ed6c572b750b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3498864
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Commit-Queue: Austin Sullivan <asully@chromium.org>
Cr-Commit-Position: refs/heads/main@{#980167}
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc
index bf5d3bdaace198e4da56cab27aef9d1cfa178136..a1f346c5afd6c2f3f41069a6dda4744179b1af05 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.cc
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
#if defined(OS_MAC)
#include "base/mac/mac_util.h"
@@ -64,6 +65,8 @@ FileSystemAccessRegularFileDelegate::FileSystemAccessRegularFileDelegate(
base::FileErrorOr<int> FileSystemAccessRegularFileDelegate::Read(
int64_t offset,
base::span<uint8_t> data) {
+ DCHECK_GE(offset, 0);
+
int size = base::checked_cast<int>(data.size());
int result =
backing_file_.Read(offset, reinterpret_cast<char*>(data.data()), size);
@@ -74,13 +77,14 @@ base::FileErrorOr<int> FileSystemAccessRegularFileDelegate::Read(
}
base::FileErrorOr<int> FileSystemAccessRegularFileDelegate::Write(
- int64_t write_offset,
+ int64_t offset,
const base::span<uint8_t> data) {
+ DCHECK_GE(offset, 0);
+
int write_size = base::checked_cast<int>(data.size());
int64_t write_end_offset;
- if (!base::CheckAdd(write_offset, write_size)
- .AssignIfValid(&write_end_offset)) {
+ if (!base::CheckAdd(offset, write_size).AssignIfValid(&write_end_offset)) {
return base::File::FILE_ERROR_NO_SPACE;
}
@@ -88,8 +92,8 @@ base::FileErrorOr<int> FileSystemAccessRegularFileDelegate::Write(
return base::File::FILE_ERROR_NO_SPACE;
}
- int result = backing_file_.Write(
- write_offset, reinterpret_cast<char*>(data.data()), write_size);
+ int result = backing_file_.Write(offset, reinterpret_cast<char*>(data.data()),
+ write_size);
if (write_size == result) {
capacity_tracker_->CommitFileSizeChange(write_end_offset);
return result;
@@ -112,16 +116,19 @@ void FileSystemAccessRegularFileDelegate::GetLength(
FROM_HERE, {base::MayBlock()},
CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DoGetLength,
WrapCrossThreadPersistent(this),
- std::move(wrapped_callback), task_runner_));
+ std::move(wrapped_callback), std::move(backing_file_),
+ task_runner_));
}
// static
void FileSystemAccessRegularFileDelegate::DoGetLength(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- WTF::CrossThreadOnceFunction<void(base::FileErrorOr<int64_t>)>
- wrapped_callback,
+ CrossThreadOnceFunction<void(base::FileErrorOr<int64_t>)> callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
- int64_t length = delegate->backing_file_.GetLength();
+ DCHECK(!IsMainThread());
+
+ int64_t length = file.GetLength();
// If the length is negative, the file operation failed. Get the last error
// now before another file operation might run.
@@ -130,7 +137,19 @@ void FileSystemAccessRegularFileDelegate::DoGetLength(
PostCrossThreadTask(
*task_runner, FROM_HERE,
- CrossThreadBindOnce(std::move(wrapped_callback), std::move(result)));
+ CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DidGetLength,
+ std::move(delegate), std::move(callback),
+ std::move(file), std::move(result)));
+}
+
+void FileSystemAccessRegularFileDelegate::DidGetLength(
+ CrossThreadOnceFunction<void(base::FileErrorOr<int64_t>)> callback,
+ base::File file,
+ base::FileErrorOr<int64_t> error_or_length) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ backing_file_ = std::move(file);
+
+ std::move(callback).Run(std::move(error_or_length));
}
void FileSystemAccessRegularFileDelegate::SetLength(
@@ -161,6 +180,9 @@ void FileSystemAccessRegularFileDelegate::DidCheckSetLengthCapacity(
return;
}
+ auto wrapped_callback =
+ CrossThreadOnceFunction<void(bool)>(std::move(callback));
+
#if defined(OS_MAC)
// On macOS < 10.15, a sandboxing limitation causes failures in ftruncate()
// syscalls issued from renderers. For this reason, base::File::SetLength()
@@ -173,81 +195,57 @@ void FileSystemAccessRegularFileDelegate::DidCheckSetLengthCapacity(
}
file_utilities_host_->SetLength(
std::move(backing_file_), new_length,
- WTF::Bind(&FileSystemAccessRegularFileDelegate::DidSetLengthIPC,
- WrapPersistent(this), std::move(callback), new_length));
+ WTF::Bind(&FileSystemAccessRegularFileDelegate::DidSetLength,
+ WrapPersistent(this), std::move(wrapped_callback),
+ new_length));
return;
}
#endif // defined(OS_MAC)
- auto wrapped_callback =
- CrossThreadOnceFunction<void(bool)>(std::move(callback));
-
// Truncate file on a worker thread and reply back to this sequence.
worker_pool::PostTask(
FROM_HERE, {base::MayBlock()},
CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DoSetLength,
WrapCrossThreadPersistent(this),
- std::move(wrapped_callback), task_runner_,
- new_length));
+ std::move(wrapped_callback), std::move(backing_file_),
+ task_runner_, new_length));
}
// static
void FileSystemAccessRegularFileDelegate::DoSetLength(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- CrossThreadOnceFunction<void(bool)> wrapped_callback,
+ CrossThreadOnceFunction<void(bool)> callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> task_runner,
int64_t length) {
- bool result = delegate->backing_file_.SetLength(length);
-
- if (!result) {
- // If the operation failed, the previously requested capacity is not
- // returned and no change in file size is recorded. This assumes that
- // setLength operations either succeed or do not change the file's length,
- // which is consistent with the way other file operations are implemented in
- // File System Access.
- PostCrossThreadTask(
- *task_runner, FROM_HERE,
- CrossThreadBindOnce(std::move(wrapped_callback), std::move(result)));
- return;
- }
+ DCHECK(!IsMainThread());
+
+ bool success = file.SetLength(length);
+
PostCrossThreadTask(
*task_runner, FROM_HERE,
- CrossThreadBindOnce(
- &FileSystemAccessRegularFileDelegate::DidSuccessfulSetLength,
- std::move(delegate), length, std::move(wrapped_callback)));
-}
-
-void FileSystemAccessRegularFileDelegate::DidSuccessfulSetLength(
- int64_t new_length,
- CrossThreadOnceFunction<void(bool)> callback) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- capacity_tracker_->CommitFileSizeChange(new_length);
- std::move(callback).Run(true);
+ CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DidSetLength,
+ std::move(delegate), std::move(callback), length,
+ std::move(file), success));
}
-#if defined(OS_MAC)
-void FileSystemAccessRegularFileDelegate::DidSetLengthIPC(
- base::OnceCallback<void(bool)> callback,
+void FileSystemAccessRegularFileDelegate::DidSetLength(
+ CrossThreadOnceFunction<void(bool)> callback,
int64_t new_length,
base::File file,
bool success) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
backing_file_ = std::move(file);
- if (!success) {
- // If the operation failed, the previously requested capacity is not
- // returned and no change in file size is recorded. This assumes that
- // setLength operations either succeed or do not change the file's length,
- // which is consistent with the way other file operations are implemented in
- // File System Access.
- std::move(callback).Run(success);
- return;
- }
- auto wrapped_callback =
- CrossThreadOnceFunction<void(bool)>(std::move(callback));
- DidSuccessfulSetLength(new_length, std::move(wrapped_callback));
+ // If the operation failed, no change in file size is recorded. This assumes
+ // that setLength operations either succeed or do not change the file's
+ // length, which is consistent with the way other file operations are
+ // implemented in File System Access.
+ if (success)
+ capacity_tracker_->CommitFileSizeChange(new_length);
+
+ std::move(callback).Run(success);
}
-#endif // defined(OS_MAC)
void FileSystemAccessRegularFileDelegate::Flush(
base::OnceCallback<void(bool)> callback) {
@@ -259,17 +257,34 @@ void FileSystemAccessRegularFileDelegate::Flush(
FROM_HERE, {base::MayBlock()},
CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DoFlush,
WrapCrossThreadPersistent(this),
- std::move(wrapped_callback), task_runner_));
+ std::move(wrapped_callback), std::move(backing_file_),
+ task_runner_));
}
// static
void FileSystemAccessRegularFileDelegate::DoFlush(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- CrossThreadOnceFunction<void(bool)> wrapped_callback,
+ CrossThreadOnceFunction<void(bool)> callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
- bool result = delegate->backing_file_.Flush();
- PostCrossThreadTask(*task_runner, FROM_HERE,
- CrossThreadBindOnce(std::move(wrapped_callback), result));
+ DCHECK(!IsMainThread());
+
+ bool success = file.Flush();
+ PostCrossThreadTask(
+ *task_runner, FROM_HERE,
+ CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DidFlush,
+ std::move(delegate), std::move(callback),
+ std::move(file), success));
+}
+
+void FileSystemAccessRegularFileDelegate::DidFlush(
+ CrossThreadOnceFunction<void(bool)> callback,
+ base::File file,
+ bool success) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ backing_file_ = std::move(file);
+
+ std::move(callback).Run(success);
}
void FileSystemAccessRegularFileDelegate::Close(base::OnceClosure callback) {
@@ -280,16 +295,33 @@ void FileSystemAccessRegularFileDelegate::Close(base::OnceClosure callback) {
FROM_HERE, {base::MayBlock()},
CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DoClose,
WrapCrossThreadPersistent(this),
- std::move(wrapped_callback), task_runner_));
+ std::move(wrapped_callback), std::move(backing_file_),
+ task_runner_));
}
// static
void FileSystemAccessRegularFileDelegate::DoClose(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- CrossThreadOnceClosure wrapped_callback,
+ CrossThreadOnceClosure callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
- delegate->backing_file_.Close();
- PostCrossThreadTask(*task_runner, FROM_HERE, std::move(wrapped_callback));
+ DCHECK(!IsMainThread());
+
+ file.Close();
+ PostCrossThreadTask(
+ *task_runner, FROM_HERE,
+ CrossThreadBindOnce(&FileSystemAccessRegularFileDelegate::DidClose,
+ std::move(delegate), std::move(callback),
+ std::move(file)));
+}
+
+void FileSystemAccessRegularFileDelegate::DidClose(
+ CrossThreadOnceClosure callback,
+ base::File file) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ backing_file_ = std::move(file);
+
+ std::move(callback).Run();
}
} // namespace blink
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h
index 6ecde8f42f4f8ee623d0b79b361dab3d2801021d..f1267ef98e083feaa472e6d1b14c8e1bb8df7b96 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_access_regular_file_delegate.h
@@ -28,6 +28,11 @@ namespace blink {
// Non-incognito implementation of the FileSystemAccessFileDelegate. This class
// is a thin wrapper around an OS-level file descriptor.
+//
+// For async file operations, ownership of the file descriptor is passed to
+// `task_runner_` to ensure it stays alive while being used. Ownership is passed
+// back to the delegate once the operation completes. The delegate must not be
+// used while there is an in-progress operation.
class FileSystemAccessRegularFileDelegate final
: public FileSystemAccessFileDelegate {
public:
@@ -71,24 +76,55 @@ class FileSystemAccessRegularFileDelegate final
bool IsValid() const override { return backing_file_.IsValid(); }
private:
+ // All async file operations perform I/O via a worker pool, off the main
+ // thread. To keep `backing_file_` from being garbage-collected, ownership is
+ // passed to the worker thread during the file operation. Concurrent file
+ // operations is NOT supported.
+
+ // Performs the file I/O part of getSize(), off the main thread.
static void DoGetLength(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- CrossThreadOnceFunction<void(base::FileErrorOr<int64_t>)>
- wrapped_callback,
+ CrossThreadOnceFunction<void(base::FileErrorOr<int64_t>)> callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> file_task_runner);
+ // Performs the post file I/O part of getSize(), on the main thread.
+ void DidGetLength(
+ CrossThreadOnceFunction<void(base::FileErrorOr<int64_t>)> callback,
+ base::File file,
+ base::FileErrorOr<int64_t> error_or_length);
+
+ // Performs the file I/O part of truncate(), off the main thread.
static void DoSetLength(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- CrossThreadOnceFunction<void(bool)> wrapped_callback,
+ CrossThreadOnceFunction<void(bool)> callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> task_runner,
int64_t length);
+ // Performs the post file I/O part of truncate(), on the main thread.
+ void DidSetLength(CrossThreadOnceFunction<void(bool)> callback,
+ int64_t new_length,
+ base::File file,
+ bool success);
+
+ // Performs the file I/O part of flush(), off the main thread.
static void DoFlush(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- CrossThreadOnceFunction<void(bool)> wrapped_callback,
+ CrossThreadOnceFunction<void(bool)> callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> task_runner);
+ // Performs the post file I/O part of flush(), on the main thread.
+ void DidFlush(CrossThreadOnceFunction<void(bool)> callback,
+ base::File file,
+ bool success);
+
+ // Performs the file I/O part of close(), off the main thread.
static void DoClose(
CrossThreadPersistent<FileSystemAccessRegularFileDelegate> delegate,
- CrossThreadOnceClosure wrapped_callback,
+ CrossThreadOnceClosure callback,
+ base::File file,
scoped_refptr<base::SequencedTaskRunner> task_runner);
+ // Performs the post file I/O part of close(), on the main thread.
+ void DidClose(CrossThreadOnceClosure callback, base::File file);
// Called after preconditions for SetLength, including the requesting
// additional capacity (if needed), have been performed.
@@ -98,16 +134,7 @@ class FileSystemAccessRegularFileDelegate final
int64_t new_length,
bool request_capacity_result);
- // Called after SetLength was successfully performed.
- void DidSuccessfulSetLength(int64_t new_length,
- CrossThreadOnceFunction<void(bool)> callback);
-
#if defined(OS_MAC)
- void DidSetLengthIPC(base::OnceCallback<void(bool)> callback,
- int64_t new_length,
- base::File file,
- bool result);
-
// We need the FileUtilitiesHost only on Mac, where we have to execute
// base::File::SetLength on the browser process, see crbug.com/1084565.
// We need the context_ to create the instance of FileUtilitiesHost lazily.

View File

@@ -0,0 +1,217 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rakina Zata Amni <rakina@chromium.org>
Date: Mon, 25 Apr 2022 06:18:19 +0000
Subject: Don't use GetOriginalOpener to get opener's origin on FrameTree
initialization
When setting the origin of the new main RFH on FrameTree initialization,
we base it on the opener's origin if it exists. GetOriginalOpener()
was used to get the opener, but that function will actually return the
main frame of the opener. This means when the FrameTree is opened by a
non-main frame, we might inherit the wrong origin.
This CL fixes the bug by getting the actual opener using GetOpener()
instead, and adds a regression test and warning note to
GetOriginalOpener().
(cherry picked from commit 4eb716ef5cdbca4db3a9377ee6390964d0d4025f)
Bug: 1311820, 1291764
Change-Id: I7e6f63a394ba4188eee3ce3043b174a2695508eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3564826
Reviewed-by: Charlie Reis <creis@chromium.org>
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#989165}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3600157
Auto-Submit: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: Nidhi Jaju <nidhijaju@chromium.org>
Commit-Queue: Nidhi Jaju <nidhijaju@chromium.org>
Owners-Override: Nidhi Jaju <nidhijaju@chromium.org>
Cr-Commit-Position: refs/branch-heads/4896@{#1179}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/content/browser/renderer_host/frame_tree.cc b/content/browser/renderer_host/frame_tree.cc
index dc8f28bdefb7c490104c2e88fb71f7cc91db0fda..7193d75e5daa83b4749c8e1e2497a2e99cc03ef3 100644
--- a/content/browser/renderer_host/frame_tree.cc
+++ b/content/browser/renderer_host/frame_tree.cc
@@ -789,7 +789,7 @@ void FrameTree::RegisterExistingOriginToPreventOptInIsolation(
void FrameTree::Init(SiteInstance* main_frame_site_instance,
bool renderer_initiated_creation,
const std::string& main_frame_name,
- RenderFrameHostImpl* opener) {
+ RenderFrameHostImpl* opener_for_origin) {
// blink::FrameTree::SetName always keeps |unique_name| empty in case of a
// main frame - let's do the same thing here.
std::string unique_name;
@@ -800,16 +800,16 @@ void FrameTree::Init(SiteInstance* main_frame_site_instance,
// The initial empty document should inherit the origin of its opener (the
// origin may change after the first commit), except when they are in
- // different browsing context groups (`renderer_initiated_creation` is false),
- // where it should use a new opaque origin.
+ // different browsing context groups (`renderer_initiated_creation` will be
+ // false), where it should use a new opaque origin.
// See also https://crbug.com/932067.
//
// Note that the origin of the new frame might depend on sandbox flags.
// Checking sandbox flags of the new frame should be safe at this point,
// because the flags should be already inherited when creating the root node.
- DCHECK(!renderer_initiated_creation || opener);
+ DCHECK(!renderer_initiated_creation || opener_for_origin);
root_->current_frame_host()->SetOriginDependentStateOfNewFrame(
- renderer_initiated_creation ? opener->GetLastCommittedOrigin()
+ renderer_initiated_creation ? opener_for_origin->GetLastCommittedOrigin()
: url::Origin());
if (blink::features::IsInitialNavigationEntryEnabled())
diff --git a/content/browser/renderer_host/frame_tree.h b/content/browser/renderer_host/frame_tree.h
index d1f7db763fabe942e6322e8781331df6998a6a28..ca0a0e16f4ccdf77eb1feb1fb197230579c1b01b 100644
--- a/content/browser/renderer_host/frame_tree.h
+++ b/content/browser/renderer_host/frame_tree.h
@@ -204,7 +204,7 @@ class CONTENT_EXPORT FrameTree {
// Initializes the main frame for this FrameTree. That is it creates the
// initial RenderFrameHost in the root node's RenderFrameHostManager, and also
// creates an initial NavigationEntry (if the InitialNavigationEntry feature
- // is enabled) that potentially inherits `opener`'s origin in its
+ // is enabled) that potentially inherits `opener_for_origin`'s origin in its
// NavigationController. This method will call back into the delegates so it
// should only be called once they have completed their initialization.
// TODO(carlscab): It would be great if initialization could happened in the
@@ -212,7 +212,7 @@ class CONTENT_EXPORT FrameTree {
void Init(SiteInstance* main_frame_site_instance,
bool renderer_initiated_creation,
const std::string& main_frame_name,
- RenderFrameHostImpl* opener);
+ RenderFrameHostImpl* opener_for_origin);
Type type() const { return type_; }
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index bf1494b76230c77d9dac8c66f16b4349dfb15ae8..e6b582af29dd6fa274cc0740aa272b1e62c2725c 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -6543,6 +6543,80 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, ErrorDocuments) {
EXPECT_TRUE(child_b->IsErrorDocument());
}
+// Tests that a popup that is opened by a subframe inherits the subframe's
+// origin, instead of the main frame's origin.
+// Regression test for https://crbug.com/1311820 and https://crbug.com/1291764.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+ PopupOpenedBySubframeHasCorrectOrigin) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ // Navigate to a page with a cross-site iframe.
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
+ FrameTreeNode* child = root->child_at(0);
+
+ // Verify that the main frame & subframe origin differs.
+ url::Origin a_origin = url::Origin::Create(main_url);
+ url::Origin b_origin = url::Origin::Create(child->current_url());
+ EXPECT_EQ(a_origin, root->current_frame_host()->GetLastCommittedOrigin());
+ EXPECT_EQ(b_origin, child->current_frame_host()->GetLastCommittedOrigin());
+ EXPECT_NE(a_origin, b_origin);
+
+ {
+ // From the subframe, open a popup that stays on the initial empty
+ // document.
+ WebContentsAddedObserver popup_observer;
+ ASSERT_TRUE(ExecJs(child, "var w = window.open('/nocontent');"));
+ WebContentsImpl* popup =
+ static_cast<WebContentsImpl*>(popup_observer.GetWebContents());
+ FrameTreeNode* popup_frame = popup->GetMainFrame()->frame_tree_node();
+
+ // The popup should inherit the subframe's origin. Before the fix for
+ // https://crbug.com/1311820, the popup used to inherit the main frame's
+ // origin instead.
+ EXPECT_EQ(b_origin,
+ popup_frame->current_frame_host()->GetLastCommittedOrigin());
+ EXPECT_EQ(b_origin.Serialize(), EvalJs(popup_frame, "self.origin"));
+
+ // Try calling document.open() on the popup from itself.
+ // This used to cause a renderer kill as the browser used to notice the
+ // current origin & process lock mismatched when the document.open()
+ // notification IPC arrives.
+ EXPECT_EQ(GURL("about:blank"), EvalJs(popup_frame, "location.href"));
+ EXPECT_TRUE(ExecJs(popup_frame, "document.open()"));
+ EXPECT_EQ(GURL("about:blank"), EvalJs(popup_frame, "location.href"));
+
+ // Try updating the URL of the popup to the opener subframe's URL by
+ // calling document.open() on the popup from the opener subframe.
+ // This used to cause a renderer kill as the browser used to expect that
+ // the popup frame can only update to URLs under `a_origin`, while the
+ // new URL is under `b_origin`. See also https://crbug.com/1291764.
+ EXPECT_TRUE(ExecJs(child, "w.document.open()"));
+ EXPECT_EQ(child->current_url().spec(),
+ EvalJs(popup_frame, "location.href"));
+ }
+
+ {
+ // From the subframe, open a popup that stays on the initial empty
+ // document, and specify 'noopener' to sever the opener relationship.
+ WebContentsAddedObserver popup_observer;
+ ASSERT_TRUE(
+ ExecJs(child, "var w = window.open('/nocontent', '', 'noopener');"));
+ WebContentsImpl* popup =
+ static_cast<WebContentsImpl*>(popup_observer.GetWebContents());
+ FrameTreeNode* popup_frame = popup->GetMainFrame()->frame_tree_node();
+ EXPECT_EQ(nullptr, EvalJs(popup_frame, "window.opener"));
+
+ // The popup should use a new opaque origin, instead of the subframe's
+ // origin.
+ EXPECT_NE(b_origin,
+ popup_frame->current_frame_host()->GetLastCommittedOrigin());
+ EXPECT_TRUE(
+ popup_frame->current_frame_host()->GetLastCommittedOrigin().opaque());
+ EXPECT_EQ("null", EvalJs(popup_frame, "self.origin"));
+ }
+}
+
class RenderFrameHostImplAvoidUnnecessaryBeforeUnloadBrowserTest
: public RenderFrameHostImplBeforeUnloadBrowserTest {
public:
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 00a701c92c6b3ab7aa00e6f7bfc40febc7d0439e..f66907f633fe51f220164ca8ebbf16a8059ee843 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2971,9 +2971,18 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
->PreventAssociationWithSpareProcess();
}
+ // Iniitalize the primary FrameTree.
+ // Note that GetOpener() is used here to get the opener for origin
+ // inheritance, instead of other similar functions:
+ // - GetOriginalOpener(), which would always return the main frame of the
+ // opener, which might be different from the actual opener.
+ // - FindOpenerRFH(), which will still return the opener frame if the
+ // opener is suppressed (e.g. due to 'noopener'). The opener should not
+ // be used for origin inheritance purposes in those cases, so this should
+ // not pass the opener for those cases.
primary_frame_tree_.Init(site_instance.get(),
params.renderer_initiated_creation,
- params.main_frame_name, GetOriginalOpener());
+ params.main_frame_name, GetOpener());
if (params.view && params.delegate_view) {
view_.reset(params.view);
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index aa10ae9a2154fe28c3df749c9f6c493f9101a567..52f2cd80da6ef870c9123faf388b9bfadc936b66 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -1075,8 +1075,13 @@ class WebContents : public PageNavigator,
// original owner, etc.
virtual bool HasOriginalOpener() = 0;
- // Returns the original opener if HasOriginalOpener() is true, or nullptr
- // otherwise.
+ // Returns the original opener's main frame if HasOriginalOpener() is true, or
+ // nullptr otherwise. NOTE: This will always be the main frame of the actual
+ // original opener's frame tree, so it might be different from the actual
+ // original opener if it is a subframe. See https://crbug.com/705316 for more
+ // context.
+ // TODO(https://crbug.com/1311820): Consider renaming this function and other
+ // things related to "original openers", to make the quirk more obvious.
virtual RenderFrameHost* GetOriginalOpener() = 0;
// Returns the WakeLockContext accociated with this WebContents.

View File

@@ -0,0 +1,641 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darshan Sen <raisinten@gmail.com>
Date: Fri, 17 Jun 2022 13:19:32 +0530
Subject: posix: Replace DoubleForkAndExec() with ForkAndSpawn()
The DoubleForkAndExec() function was taking over 622 milliseconds to run
on macOS 11 (BigSur) on Intel i5-1038NG7. I did some debugging by adding
some custom traces and found that the fork() syscall is the bottleneck
here, i.e., the first fork() takes around 359 milliseconds and the
nested fork() takes around 263 milliseconds. Replacing the nested fork()
and exec() with posix_spawn() reduces the time consumption to 257
milliseconds!
See https://github.com/libuv/libuv/pull/3064 to know why fork() is so
slow on macOS and why posix_spawn() is a better replacement.
Another point to note is that even base::LaunchProcess() from Chromium
calls posix_spawnp() on macOS -
https://source.chromium.org/chromium/chromium/src/+/8f8d82dea0fa8f11f57c74dbb65126f8daba58f7:base/process/launch_mac.cc;l=295-296
Change-Id: I25c6ee9629a1ae5d0c32b361b56a1ce0b4b0fd26
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3641386
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
diff --git a/third_party/crashpad/crashpad/AUTHORS b/third_party/crashpad/crashpad/AUTHORS
index 8dcac3238870920d374b86033d05d77ebde351e9..02103924332eddbd158c04f8a395bb4a247e8bd9 100644
--- a/third_party/crashpad/crashpad/AUTHORS
+++ b/third_party/crashpad/crashpad/AUTHORS
@@ -12,3 +12,4 @@ Opera Software ASA
Vewd Software AS
LG Electronics, Inc.
MIPS Technologies, Inc.
+Darshan Sen <raisinten@gmail.com>
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
index eccf204ca119a5e0b803a18df07835916f7abb22..b35f0c1b9486032f49a9154c92d277a79434a7ad 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
@@ -40,7 +40,7 @@
#include "util/linux/socket.h"
#include "util/misc/address_sanitizer.h"
#include "util/misc/from_pointer_cast.h"
-#include "util/posix/double_fork_and_exec.h"
+#include "util/posix/fork_and_spawn.h"
#include "util/posix/scoped_mmap.h"
#include "util/posix/signals.h"
@@ -401,7 +401,7 @@ bool CrashpadClient::StartHandler(
argv.push_back(FormatArgumentInt("initial-client-fd", handler_sock.get()));
argv.push_back("--shared-client-connection");
- if (!DoubleForkAndExec(argv, nullptr, handler_sock.get(), false, nullptr)) {
+ if (!ForkAndSpawn(argv, nullptr, handler_sock.get(), false, nullptr)) {
return false;
}
@@ -555,7 +555,7 @@ bool CrashpadClient::StartJavaHandlerForClient(
int socket) {
std::vector<std::string> argv = BuildAppProcessArgs(
class_name, database, metrics_dir, url, annotations, arguments, socket);
- return DoubleForkAndExec(argv, env, socket, false, nullptr);
+ return ForkAndSpawn(argv, env, socket, false, nullptr);
}
bool CrashpadClient::StartHandlerWithLinkerAtCrash(
@@ -604,7 +604,7 @@ bool CrashpadClient::StartHandlerWithLinkerForClient(
annotations,
arguments,
socket);
- return DoubleForkAndExec(argv, env, socket, false, nullptr);
+ return ForkAndSpawn(argv, env, socket, false, nullptr);
}
#endif
@@ -638,7 +638,7 @@ bool CrashpadClient::StartHandlerForClient(
argv.push_back(FormatArgumentInt("initial-client-fd", socket));
- return DoubleForkAndExec(argv, nullptr, socket, true, nullptr);
+ return ForkAndSpawn(argv, nullptr, socket, true, nullptr);
}
// static
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_mac.cc b/third_party/crashpad/crashpad/client/crashpad_client_mac.cc
index b4a365d0204612b4e4621b2e8c30d266a10e1bc1..59c7a800ad903b91a88d0ef0cb1a01a1d8036e52 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_mac.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_mac.cc
@@ -36,7 +36,7 @@
#include "util/mach/notify_server.h"
#include "util/misc/clock.h"
#include "util/misc/implicit_cast.h"
-#include "util/posix/double_fork_and_exec.h"
+#include "util/posix/fork_and_spawn.h"
namespace crashpad {
@@ -343,7 +343,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface {
// this parent process, which was probably using the exception server now
// being restarted. The handler cant monitor itself for its own crashes via
// this interface.
- if (!DoubleForkAndExec(
+ if (!ForkAndSpawn(
argv,
nullptr,
server_write_fd.get(),
diff --git a/third_party/crashpad/crashpad/handler/linux/cros_crash_report_exception_handler.cc b/third_party/crashpad/crashpad/handler/linux/cros_crash_report_exception_handler.cc
index 9e58d94aa499fdb7271a78ea21a1dcc1b12e3a52..3caa3b987b35be575558a312026cf6f19485c418 100644
--- a/third_party/crashpad/crashpad/handler/linux/cros_crash_report_exception_handler.cc
+++ b/third_party/crashpad/crashpad/handler/linux/cros_crash_report_exception_handler.cc
@@ -29,7 +29,7 @@
#include "util/linux/ptrace_client.h"
#include "util/misc/metrics.h"
#include "util/misc/uuid.h"
-#include "util/posix/double_fork_and_exec.h"
+#include "util/posix/fork_and_spawn.h"
namespace crashpad {
@@ -266,12 +266,11 @@ bool CrosCrashReportExceptionHandler::HandleExceptionWithConnection(
argv.push_back("--always_allow_feedback");
}
- if (!DoubleForkAndExec(argv,
- nullptr /* envp */,
- file_writer.fd() /* preserve_fd */,
- false /* use_path */,
- nullptr /* child_function */)) {
- LOG(ERROR) << "DoubleForkAndExec failed";
+ if (!ForkAndSpawn(argv,
+ nullptr /* envp */,
+ file_writer.fd() /* preserve_fd */,
+ false /* use_path */,
+ nullptr /* child_function */)) {
Metrics::ExceptionCaptureResult(
Metrics::CaptureResult::kFinishedWritingCrashReportFailed);
return false;
diff --git a/third_party/crashpad/crashpad/util/BUILD.gn b/third_party/crashpad/crashpad/util/BUILD.gn
index 9f178d10a9151340d34f17f2d04eef791a8d174b..20467df262354ac85e4d5ef71259e4539994c67a 100644
--- a/third_party/crashpad/crashpad/util/BUILD.gn
+++ b/third_party/crashpad/crashpad/util/BUILD.gn
@@ -296,10 +296,10 @@ crashpad_static_library("util") {
sources += [
"posix/close_multiple.cc",
"posix/close_multiple.h",
- "posix/double_fork_and_exec.cc",
- "posix/double_fork_and_exec.h",
"posix/drop_privileges.cc",
"posix/drop_privileges.h",
+ "posix/fork_and_spawn.cc",
+ "posix/fork_and_spawn.h",
"posix/process_info.h",
# These map signals to and from strings. While Fuchsia defines some of
diff --git a/third_party/crashpad/crashpad/util/posix/double_fork_and_exec.cc b/third_party/crashpad/crashpad/util/posix/double_fork_and_exec.cc
deleted file mode 100644
index 1960430954d3f6459dce688493db5c42047567b0..0000000000000000000000000000000000000000
--- a/third_party/crashpad/crashpad/util/posix/double_fork_and_exec.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2017 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "util/posix/double_fork_and_exec.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "base/check_op.h"
-#include "base/logging.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/strings/stringprintf.h"
-#include "util/posix/close_multiple.h"
-
-namespace crashpad {
-
-bool DoubleForkAndExec(const std::vector<std::string>& argv,
- const std::vector<std::string>* envp,
- int preserve_fd,
- bool use_path,
- void (*child_function)()) {
- DCHECK(!envp || !use_path);
-
- // argv_c contains const char* pointers and is terminated by nullptr. This is
- // suitable for passing to execv(). Although argv_c is not used in the parent
- // process, it must be built in the parent process because its unsafe to do
- // so in the child or grandchild process.
- std::vector<const char*> argv_c;
- argv_c.reserve(argv.size() + 1);
- for (const std::string& argument : argv) {
- argv_c.push_back(argument.c_str());
- }
- argv_c.push_back(nullptr);
-
- std::vector<const char*> envp_c;
- if (envp) {
- envp_c.reserve(envp->size() + 1);
- for (const std::string& variable : *envp) {
- envp_c.push_back(variable.c_str());
- }
- envp_c.push_back(nullptr);
- }
-
- // Double-fork(). The three processes involved are parent, child, and
- // grandchild. The grandchild will call execv(). The child exits immediately
- // after spawning the grandchild, so the grandchild becomes an orphan and its
- // parent process ID becomes 1. This relieves the parent and child of the
- // responsibility to reap the grandchild with waitpid() or similar. The
- // grandchild is expected to outlive the parent process, so the parent
- // shouldnt be concerned with reaping it. This approach means that accidental
- // early termination of the handler process will not result in a zombie
- // process.
- pid_t pid = fork();
- if (pid < 0) {
- PLOG(ERROR) << "fork";
- return false;
- }
-
- if (pid == 0) {
- // Child process.
-
- if (child_function) {
- child_function();
- }
-
- // Call setsid(), creating a new process group and a new session, both led
- // by this process. The new process group has no controlling terminal. This
- // disconnects it from signals generated by the parent process terminal.
- //
- // setsid() is done in the child instead of the grandchild so that the
- // grandchild will not be a session leader. If it were a session leader, an
- // accidental open() of a terminal device without O_NOCTTY would make that
- // terminal the controlling terminal.
- //
- // Its not desirable for the grandchild to have a controlling terminal. The
- // grandchild manages its own lifetime, such as by monitoring clients on its
- // own and exiting when it loses all clients and when it deems it
- // appropraite to do so. It may serve clients in different process groups or
- // sessions than its original client, and receiving signals intended for its
- // original clients process group could be harmful in that case.
- PCHECK(setsid() != -1) << "setsid";
-
- pid = fork();
- if (pid < 0) {
- PLOG(FATAL) << "fork";
- }
-
- if (pid > 0) {
- // Child process.
-
- // _exit() instead of exit(), because fork() was called.
- _exit(EXIT_SUCCESS);
- }
-
- // Grandchild process.
-
- CloseMultipleNowOrOnExec(STDERR_FILENO + 1, preserve_fd);
-
- // &argv_c[0] is a pointer to a pointer to const char data, but because of
- // how C (not C++) works, execvp() wants a pointer to a const pointer to
- // char data. It modifies neither the data nor the pointers, so the
- // const_cast is safe.
- char* const* argv_for_execv = const_cast<char* const*>(&argv_c[0]);
-
- if (envp) {
- // This cast is safe for the same reason that the argv_for_execv cast is.
- char* const* envp_for_execv = const_cast<char* const*>(&envp_c[0]);
- execve(argv_for_execv[0], argv_for_execv, envp_for_execv);
- PLOG(FATAL) << "execve " << argv_for_execv[0];
- }
-
- if (use_path) {
- execvp(argv_for_execv[0], argv_for_execv);
- PLOG(FATAL) << "execvp " << argv_for_execv[0];
- }
-
- execv(argv_for_execv[0], argv_for_execv);
- PLOG(FATAL) << "execv " << argv_for_execv[0];
- }
-
- // waitpid() for the child, so that it does not become a zombie process. The
- // child normally exits quickly.
- //
- // Failures from this point on may result in the accumulation of a zombie, but
- // should not be considered fatal. Log only warnings, but dont treat these
- // failures as a failure of the function overall.
- int status;
- pid_t wait_pid = HANDLE_EINTR(waitpid(pid, &status, 0));
- if (wait_pid == -1) {
- PLOG(WARNING) << "waitpid";
- return true;
- }
- DCHECK_EQ(wait_pid, pid);
-
- if (WIFSIGNALED(status)) {
- int sig = WTERMSIG(status);
- LOG(WARNING) << base::StringPrintf(
- "intermediate process terminated by signal %d (%s)%s",
- sig,
- strsignal(sig),
- WCOREDUMP(status) ? " (core dumped)" : "");
- } else if (!WIFEXITED(status)) {
- LOG(WARNING) << base::StringPrintf(
- "intermediate process: unknown termination 0x%x", status);
- } else if (WEXITSTATUS(status) != EXIT_SUCCESS) {
- LOG(WARNING) << "intermediate process exited with code "
- << WEXITSTATUS(status);
- }
-
- return true;
-}
-
-} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/posix/fork_and_spawn.cc b/third_party/crashpad/crashpad/util/posix/fork_and_spawn.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0f11eea3c61db156bc2d2322ab1c38ff44ac35bc
--- /dev/null
+++ b/third_party/crashpad/crashpad/util/posix/fork_and_spawn.cc
@@ -0,0 +1,235 @@
+// Copyright 2017 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/posix/fork_and_spawn.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "base/check.h"
+#include "base/check_op.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
+#include "util/posix/close_multiple.h"
+
+extern char** environ;
+
+namespace crashpad {
+
+namespace {
+
+#if defined(OS_MAC)
+
+class PosixSpawnAttr {
+ public:
+ PosixSpawnAttr() {
+ PCHECK((errno = posix_spawnattr_init(&attr_)) == 0)
+ << "posix_spawnattr_init";
+ }
+
+ PosixSpawnAttr(const PosixSpawnAttr&) = delete;
+ PosixSpawnAttr& operator=(const PosixSpawnAttr&) = delete;
+
+ ~PosixSpawnAttr() {
+ PCHECK((errno = posix_spawnattr_destroy(&attr_)) == 0)
+ << "posix_spawnattr_destroy";
+ }
+
+ void SetFlags(short flags) {
+ PCHECK((errno = posix_spawnattr_setflags(&attr_, flags)) == 0)
+ << "posix_spawnattr_setflags";
+ }
+
+ const posix_spawnattr_t* Get() const { return &attr_; }
+
+ private:
+ posix_spawnattr_t attr_;
+};
+
+class PosixSpawnFileActions {
+ public:
+ PosixSpawnFileActions() {
+ PCHECK((errno = posix_spawn_file_actions_init(&file_actions_)) == 0)
+ << "posix_spawn_file_actions_init";
+ }
+
+ PosixSpawnFileActions(const PosixSpawnFileActions&) = delete;
+ PosixSpawnFileActions& operator=(const PosixSpawnFileActions&) = delete;
+
+ ~PosixSpawnFileActions() {
+ PCHECK((errno = posix_spawn_file_actions_destroy(&file_actions_)) == 0)
+ << "posix_spawn_file_actions_destroy";
+ }
+
+ void AddInheritedFileDescriptor(int fd) {
+ PCHECK((errno = posix_spawn_file_actions_addinherit_np(&file_actions_,
+ fd)) == 0)
+ << "posix_spawn_file_actions_addinherit_np";
+ }
+
+ const posix_spawn_file_actions_t* Get() const { return &file_actions_; }
+
+ private:
+ posix_spawn_file_actions_t file_actions_;
+};
+
+#endif
+
+} // namespace
+
+bool ForkAndSpawn(const std::vector<std::string>& argv,
+ const std::vector<std::string>* envp,
+ int preserve_fd,
+ bool use_path,
+ void (*child_function)()) {
+ // argv_c contains const char* pointers and is terminated by nullptr. This is
+ // suitable for passing to posix_spawn() or posix_spawnp(). Although argv_c is
+ // not used in the parent process, it must be built in the parent process
+ // because its unsafe to do so in the child.
+ std::vector<const char*> argv_c;
+ argv_c.reserve(argv.size() + 1);
+ for (const std::string& argument : argv) {
+ argv_c.push_back(argument.c_str());
+ }
+ argv_c.push_back(nullptr);
+
+ std::vector<const char*> envp_c;
+ if (envp) {
+ envp_c.reserve(envp->size() + 1);
+ for (const std::string& variable : *envp) {
+ envp_c.push_back(variable.c_str());
+ }
+ envp_c.push_back(nullptr);
+ }
+
+ // The three processes involved are parent, child, and grandchild. The child
+ // exits immediately after spawning the grandchild, so the grandchild becomes
+ // an orphan and its parent process ID becomes 1. This relieves the parent and
+ // child of the responsibility to reap the grandchild with waitpid() or
+ // similar. The grandchild is expected to outlive the parent process, so the
+ // parent shouldnt be concerned with reaping it. This approach means that
+ // accidental early termination of the handler process will not result in a
+ // zombie process.
+ pid_t pid = fork();
+ if (pid < 0) {
+ PLOG(ERROR) << "fork";
+ return false;
+ }
+
+ if (pid == 0) {
+ // Child process.
+
+ if (child_function) {
+ child_function();
+ }
+
+ // Call setsid(), creating a new process group and a new session, both led
+ // by this process. The new process group has no controlling terminal. This
+ // disconnects it from signals generated by the parent process terminal.
+ //
+ // setsid() is done in the child instead of the grandchild so that the
+ // grandchild will not be a session leader. If it were a session leader, an
+ // accidental open() of a terminal device without O_NOCTTY would make that
+ // terminal the controlling terminal.
+ //
+ // Its not desirable for the grandchild to have a controlling terminal. The
+ // grandchild manages its own lifetime, such as by monitoring clients on its
+ // own and exiting when it loses all clients and when it deems it
+ // appropraite to do so. It may serve clients in different process groups or
+ // sessions than its original client, and receiving signals intended for its
+ // original clients process group could be harmful in that case.
+ PCHECK(setsid() != -1) << "setsid";
+
+ // &argv_c[0] is a pointer to a pointer to const char data, but because of
+ // how C (not C++) works, posix_spawn() and posix_spawnp() want a pointer to
+ // a const pointer to char data. They modifies neither the data nor the
+ // pointers, so the const_cast is safe.
+ char* const* argv_for_spawn = const_cast<char* const*>(argv_c.data());
+
+ // This cast is safe for the same reason that the argv_for_spawn cast is.
+ char* const* envp_for_spawn =
+ envp ? const_cast<char* const*>(envp_c.data()) : environ;
+
+#if defined(OS_MAC)
+ PosixSpawnAttr attr;
+ attr.SetFlags(POSIX_SPAWN_CLOEXEC_DEFAULT);
+
+ PosixSpawnFileActions file_actions;
+ for (int fd = 0; fd <= STDERR_FILENO; ++fd) {
+ file_actions.AddInheritedFileDescriptor(fd);
+ }
+ file_actions.AddInheritedFileDescriptor(preserve_fd);
+
+ const posix_spawnattr_t* attr_p = attr.Get();
+ const posix_spawn_file_actions_t* file_actions_p = file_actions.Get();
+#else
+ CloseMultipleNowOrOnExec(STDERR_FILENO + 1, preserve_fd);
+
+ const posix_spawnattr_t* attr_p = nullptr;
+ const posix_spawn_file_actions_t* file_actions_p = nullptr;
+#endif
+
+ auto posix_spawn_fp = use_path ? posix_spawnp : posix_spawn;
+ if ((errno = posix_spawn_fp(&pid,
+ argv_for_spawn[0],
+ file_actions_p,
+ attr_p,
+ argv_for_spawn,
+ envp_for_spawn)) != 0) {
+ PLOG(FATAL) << (use_path ? "posix_spawnp" : "posix_spawn");
+ }
+
+ // _exit() instead of exit(), because fork() was called.
+ _exit(EXIT_SUCCESS);
+ }
+
+ // waitpid() for the child, so that it does not become a zombie process. The
+ // child normally exits quickly.
+ //
+ // Failures from this point on may result in the accumulation of a zombie, but
+ // should not be considered fatal. Log only warnings, but dont treat these
+ // failures as a failure of the function overall.
+ int status;
+ pid_t wait_pid = HANDLE_EINTR(waitpid(pid, &status, 0));
+ if (wait_pid == -1) {
+ PLOG(WARNING) << "waitpid";
+ return true;
+ }
+ DCHECK_EQ(wait_pid, pid);
+
+ if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+ LOG(WARNING) << base::StringPrintf(
+ "intermediate process terminated by signal %d (%s)%s",
+ sig,
+ strsignal(sig),
+ WCOREDUMP(status) ? " (core dumped)" : "");
+ } else if (!WIFEXITED(status)) {
+ LOG(WARNING) << base::StringPrintf(
+ "intermediate process: unknown termination 0x%x", status);
+ } else if (WEXITSTATUS(status) != EXIT_SUCCESS) {
+ LOG(WARNING) << "intermediate process exited with code "
+ << WEXITSTATUS(status);
+ }
+
+ return true;
+}
+
+} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/posix/double_fork_and_exec.h b/third_party/crashpad/crashpad/util/posix/fork_and_spawn.h
similarity index 76%
rename from third_party/crashpad/crashpad/util/posix/double_fork_and_exec.h
rename to third_party/crashpad/crashpad/util/posix/fork_and_spawn.h
index 02fc0f28f196b447132a2dcfaebdaaa5a916a38a..fc55aa3a37652e4ba18c66db90124abd9cad2e51 100644
--- a/third_party/crashpad/crashpad/util/posix/double_fork_and_exec.h
+++ b/third_party/crashpad/crashpad/util/posix/fork_and_spawn.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef CRASHPAD_UTIL_POSIX_DOUBLE_FORK_AND_EXEC_H_
-#define CRASHPAD_UTIL_POSIX_DOUBLE_FORK_AND_EXEC_H_
+#ifndef CRASHPAD_UTIL_POSIX_FORK_AND_SPAWN_H_
+#define CRASHPAD_UTIL_POSIX_FORK_AND_SPAWN_H_
#include <string>
#include <vector>
@@ -23,7 +23,7 @@ namespace crashpad {
//! \brief Executes a (grand-)child process.
//!
//! The grandchild process will be started through the
-//! double-`fork()`-and-`execv()` pattern. This allows the grandchild to fully
+//! `fork()`-and-`posix_spawn()` pattern. This allows the grandchild to fully
//! disassociate from the parent. The grandchild will not be a member of the
//! parents process group or session and will not have a controlling terminal,
//! providing isolation from signals not intended for it. The grandchilds
@@ -37,7 +37,7 @@ namespace crashpad {
//! \param[in] argv The argument vector to start the grandchild process with.
//! `argv[0]` is used as the path to the executable.
//! \param[in] envp A vector of environment variables of the form `var=value` to
-//! be passed to `execve()`. If this value is `nullptr`, the current
+//! be passed to `posix_spawn()`. If this value is `nullptr`, the current
//! environment is used.
//! \param[in] preserve_fd A file descriptor to be inherited by the grandchild
//! process. This file descriptor is inherited in addition to the three file
@@ -45,16 +45,13 @@ namespace crashpad {
//! if no additional file descriptors are to be inherited.
//! \param[in] use_path Whether to consult the `PATH` environment variable when
//! requested to start an executable at a non-absolute path. If `false`,
-//! `execv()`, which does not consult `PATH`, will be used. If `true`,
-//! `execvp()`, which does consult `PATH`, will be used.
+//! `posix_spawn()`, which does not consult `PATH`, will be used. If `true`,
+//! `posix_spawnp()`, which does consult `PATH`, will be used.
//! \param[in] child_function If not `nullptr`, this function will be called in
-//! the intermediate child process, prior to the second `fork()`. Take note
+//! the intermediate child process, prior to the `posix_spawn()`. Take note
//! that this function will run in the context of a forked process, and must
//! be safe for that purpose.
//!
-//! Setting both \a envp to a value other than `nullptr` and \a use_path to
-//! `true` is not currently supported.
-//!
//! \return `true` on success, and `false` on failure with a message logged.
//! Only failures that occur in the parent process that indicate a definite
//! failure to start the the grandchild are reported in the return value.
@@ -63,12 +60,12 @@ namespace crashpad {
//! terminating. The caller assumes the responsibility for detecting such
//! failures, for example, by observing a failure to perform a successful
//! handshake with the grandchild process.
-bool DoubleForkAndExec(const std::vector<std::string>& argv,
- const std::vector<std::string>* envp,
- int preserve_fd,
- bool use_path,
- void (*child_function)());
+bool ForkAndSpawn(const std::vector<std::string>& argv,
+ const std::vector<std::string>* envp,
+ int preserve_fd,
+ bool use_path,
+ void (*child_function)());
} // namespace crashpad
-#endif // CRASHPAD_UTIL_POSIX_DOUBLE_FORK_AND_EXEC_H_
+#endif // CRASHPAD_UTIL_POSIX_FORK_AND_SPAWN_H_

View File

@@ -0,0 +1,242 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Garrett Tanzer <gtanzer@chromium.org>
Date: Wed, 2 Mar 2022 18:33:42 +0000
Subject: Reland "Fix noopener case for user activation consumption"
This is a reland of e9828a82b5c182dc9a7fb0ae7226c35ba1726e7d
The MSAN error is from checking status before err in
content/renderer/render_view_impl.cc .
https://ci.chromium.org/ui/p/chromium/builders/ci/Linux%20ChromiumOS%20MSan%20Tests/b8821495655905086193/overview
The fix is to split the check for err and kIgnore into two checks,
and put the err check before kBlocked.
It is probably possible for the browser to consume user activation
but then eventually mojo returns an error and the renderer doesn't
consume activation, but that seems pretty marginal.
Original change's description:
> Fix noopener case for user activation consumption
>
>
> The flow for user activation consumption in window.open was as follows:
>
> Renderer: ask the browser to create a new window
> Browser: consume transient user activation (in the browser, and via RPC
> to remote frames only)
> Browser: return success for opener, return ignore for noopener
> Renderer: consume transient user activation upon success
>
> So in the noopener case, the renderer with the local frame where the
> window.open originated didn't have its transient user activation
> consumed.
>
>
> The new behavior is to consume user activation in the calling renderer
> whenever it is consumed in the browser. We accomplish this by returning
> a distinct value kBlocked to represent failure before the browser
> consumes user activation.
>
> Bug: 1264543, 1291210
> Change-Id: Iffb6e3fd772bef625d3d28e600e6fb73d70ab29f
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3468171
> Reviewed-by: Dominic Farolino <dom@chromium.org>
> Reviewed-by: Ken Buchanan <kenrb@chromium.org>
> Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
> Reviewed-by: Charles Reis <creis@chromium.org>
> Reviewed-by: Jonathan Ross <jonross@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Commit-Queue: Garrett Tanzer <gtanzer@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#973876}
Bug: 1264543, 1291210
Change-Id: Ie27c4d68db34dfd98adee7cc5c743953dad59834
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3481666
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: Charles Reis <creis@chromium.org>
Commit-Queue: Garrett Tanzer <gtanzer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#976745}
diff --git a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
index 84867adc5ec36ac76a4d043e80d331ff314858d5..6c21360f68569805989598e525c89ad44ecaba11 100644
--- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
+++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -1187,6 +1187,52 @@ IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
EXPECT_FALSE(frame_c_popup_opened);
}
+// Test that opening a window with `noopener` consumes user activation.
+// crbug.com/1264543, crbug.com/1291210
+IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
+ UserActivationConsumptionNoopener) {
+ // Start on a page a.com.
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a"));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
+ content::WebContents* web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Activate the frame by executing a dummy script.
+ const std::string no_op_script = "// No-op script";
+ EXPECT_TRUE(ExecuteScript(web_contents, no_op_script));
+
+ // Add a popup observer.
+ content::TestNavigationObserver popup_observer(nullptr);
+ popup_observer.StartWatchingNewWebContents();
+
+ // Open a popup from the frame, with `noopener`. This should consume
+ // transient user activation.
+ GURL popup_url(embedded_test_server()->GetURL("popup.com", "/"));
+ EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
+ web_contents,
+ base::StringPrintf(
+ "window.w = window.open('%s'+'title1.html', '_blank', 'noopener');",
+ popup_url.spec().c_str())));
+
+ // Try to open another popup.
+ EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
+ web_contents,
+ base::StringPrintf(
+ "window.w = window.open('%s'+'title2.html', '_blank', 'noopener');",
+ popup_url.spec().c_str())));
+
+ // Wait and check that only one popup was opened.
+ popup_observer.Wait();
+ EXPECT_EQ(2, browser()->tab_strip_model()->count());
+
+ content::WebContents* popup =
+ browser()->tab_strip_model()->GetActiveWebContents();
+ EXPECT_EQ(embedded_test_server()->GetURL("popup.com", "/title1.html"),
+ popup->GetLastCommittedURL());
+ EXPECT_NE(popup, web_contents);
+}
+
// TODO(crbug.com/1021895): Flaky.
// Tests that a cross-site iframe runs its beforeunload handler when closing a
// tab. See https://crbug.com/853021.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 6bcd908794675c046bbfed26a979f7fbf123b190..4fc8b67dc616ed744735d5f6ce9a6d985edcef09 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6639,17 +6639,22 @@ void RenderFrameHostImpl::CreateNewWindow(
effective_transient_activation_state, params->opener_suppressed,
&no_javascript_access);
- bool was_consumed = false;
- if (can_create_window) {
- // Consume activation even w/o User Activation v2, to sync other renderers
- // with calling renderer.
- was_consumed = frame_tree_node_->UpdateUserActivationState(
- blink::mojom::UserActivationUpdateType::kConsumeTransientActivation,
- blink::mojom::UserActivationNotificationType::kNone);
- } else {
- std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
- return;
- }
+ // If this frame isn't allowed to create a window, return early (before we
+ // consume transient user activation).
+ if (!can_create_window) {
+ std::move(callback).Run(mojom::CreateNewWindowStatus::kBlocked, nullptr);
+ return;
+ }
+
+ // Otherwise, consume user activation before we proceed. In particular, it is
+ // important to do this before we return from the |opener_suppressed| case
+ // below.
+ // NB: This call will consume activations in the browser and the remote frame
+ // proxies for this frame. The initiating renderer will consume its view of
+ // the activations after we return.
+ bool was_consumed = frame_tree_node_->UpdateUserActivationState(
+ blink::mojom::UserActivationUpdateType::kConsumeTransientActivation,
+ blink::mojom::UserActivationNotificationType::kNone);
// For Android WebView, we support a pop-up like behavior for window.open()
// even if the embedding app doesn't support multiple windows. In this case,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index da44b637ee5fdf371974f322aaf1a07ba8c018d7..44444b35b55e6dd3af181b256515d4dad6cba749 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -558,8 +558,10 @@ struct CreateNewWindowParams {
// Operation result when the renderer asks the browser to create a new window.
enum CreateNewWindowStatus {
- // Ignore creation of the new window. This can happen because creation is
- // blocked or because the new window should have no opener relationship.
+ // Creation of the new window was blocked, e.g. because the source frame
+ // doesn't have user activation.
+ kBlocked,
+ // Ignore creation of the new window, e.g. because noopener is in effect.
kIgnore,
// Reuse the current window rather than creating a new window.
kReuse,
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 190b517cea51bd3eae29695ba45efb22c4c82877..e1d189467bbd266de01da186c1fac6e20c9f35ad 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -310,8 +310,27 @@ WebView* RenderViewImpl::CreateView(
mojom::CreateNewWindowStatus status;
mojom::CreateNewWindowReplyPtr reply;
auto* frame_host = creator_frame->GetFrameHost();
- bool err = !frame_host->CreateNewWindow(std::move(params), &status, &reply);
- if (err || status == mojom::CreateNewWindowStatus::kIgnore)
+ if (!frame_host->CreateNewWindow(std::move(params), &status, &reply)) {
+ // The sync IPC failed, e.g. maybe the render process is in the middle of
+ // shutting down. Can't create a new window without the browser process,
+ // so just bail out.
+ return nullptr;
+ }
+
+ // If creation of the window was blocked (e.g. because this frame doesn't
+ // have user activation), return before consuming user activation. A frame
+ // that isn't allowed to open a window shouldn't be able to consume the
+ // activation for the rest of the frame tree.
+ if (status == mojom::CreateNewWindowStatus::kBlocked)
+ return nullptr;
+
+ // Consume the transient user activation in the current renderer.
+ consumed_user_gesture = creator->ConsumeTransientUserActivation(
+ blink::UserActivationUpdateSource::kBrowser);
+
+ // If we should ignore the new window (e.g. because of `noopener`), return
+ // now that user activation was consumed.
+ if (status == mojom::CreateNewWindowStatus::kIgnore)
return nullptr;
// For Android WebView, we support a pop-up like behavior for window.open()
@@ -331,11 +350,6 @@ WebView* RenderViewImpl::CreateView(
DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_route_id);
DCHECK_NE(MSG_ROUTING_NONE, reply->widget_params->routing_id);
- // The browser allowed creation of a new window and consumed the user
- // activation.
- consumed_user_gesture = creator->ConsumeTransientUserActivation(
- blink::UserActivationUpdateSource::kBrowser);
-
// While this view may be a background extension page, it can spawn a visible
// render view. So we just assume that the new one is not another background
// page instead of passing on our own value.
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/restrict-size.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/restrict-size.https.html
new file mode 100644
index 0000000000000000000000000000000000000000..5668407d7e1e6ac7840fc47b76869787cb3f3d63
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/restrict-size.https.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Test fencedframe size restrictions in opaque ads mode.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<script>
+promise_test(async () => {
+ const frame = attachFencedFrameContext();
+}, 'restrict fencedframe size');
+</script>
+</body>

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nico Weber <thakis@chromium.org>
Date: Thu, 24 Feb 2022 18:15:16 +0000
Subject: Revert "[motionmark] Avoid unnecessary IPC on mac."
This reverts
https://chromium-review.googlesource.com/c/chromium/src/+/2923689
It caused us to never hit 120 Hz on ProMotion displays. Revert until
we can figure out a fix.
Bug: 1274172
Change-Id: Ia09bb0fdaf63509e08755346844dc58b59d8bb6a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3488608
Commit-Queue: Nico Weber <thakis@chromium.org>
Auto-Submit: Nico Weber <thakis@chromium.org>
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
Commit-Queue: Sadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/main@{#974729}
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
index 6efcb84af529a78e9ebc1234ef4d0c8834270c29..94bef837cb6b4c2ac379f6cab6fdcc8599c7e0c2 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -510,13 +510,10 @@ base::ScopedClosureRunner RootCompositorFrameSinkImpl::GetCacheBackBufferCb() {
void RootCompositorFrameSinkImpl::DisplayDidReceiveCALayerParams(
const gfx::CALayerParams& ca_layer_params) {
- if (last_ca_layer_params_ == ca_layer_params)
- return;
#if defined(OS_APPLE)
// If |ca_layer_params| should have content only when there exists a client
// to send it to.
DCHECK(ca_layer_params.is_empty || display_client_);
- last_ca_layer_params_ = ca_layer_params;
if (display_client_)
display_client_->OnDisplayReceivedCALayerParams(ca_layer_params);
#else
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
index cd3ed5baba3198d4f827cebf7ba89a5fefdf7087..ddb31074f8dbdbf88e4a1126f414b1afbdd589db 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
@@ -193,8 +193,6 @@ class VIZ_SERVICE_EXPORT RootCompositorFrameSinkImpl
gfx::Size last_swap_pixel_size_;
#endif
- gfx::CALayerParams last_ca_layer_params_;
-
#if defined(OS_ANDROID)
// Let client control whether it wants `DidCompleteSwapWithSize`.
bool enable_swap_competion_callback_ = false;
diff --git a/ui/gfx/ca_layer_params.h b/ui/gfx/ca_layer_params.h
index ba5767a80d13e848b7281f55307f6569a1524ce3..dcee2ec9de0e759b868b0de2c7106b2cf084c41c 100644
--- a/ui/gfx/ca_layer_params.h
+++ b/ui/gfx/ca_layer_params.h
@@ -26,16 +26,6 @@ struct GFX_EXPORT CALayerParams {
CALayerParams& operator=(const CALayerParams& params);
~CALayerParams();
- bool operator==(const CALayerParams& params) const {
- return is_empty == params.is_empty &&
- ca_context_id == params.ca_context_id &&
-#if defined(OS_MAC)
- io_surface_mach_port == params.io_surface_mach_port &&
-#endif
- pixel_size == params.pixel_size &&
- scale_factor == params.scale_factor;
- }
-
// The |is_empty| flag is used to short-circuit code to handle CALayerParams
// on non-macOS platforms.
bool is_empty = true;

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Ludwig <michaelludwig@google.com>
Date: Sat, 2 Apr 2022 01:05:15 +0000
Subject: Use RectF::Intersect in ApplyScissor
(cherry picked from commit 540e2ecde447b0757dd5bb079a59d8faef3183c1)
Bug: 1299287, 1307317
Change-Id: I026090466ebfb3dee0e9daf0609f04babcf42092
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3516507
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Reviewed-by: Brian Sheedy <bsheedy@chromium.org>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#982400}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3564640
Cr-Commit-Position: refs/branch-heads/4896@{#1017}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index ab0f0531ba9431cdadec734fe4215bcdbc39dae4..8c87ef7cce26bf9832549146f801c15b9d963e0f 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -1421,34 +1421,20 @@ void SkiaRenderer::DrawQuadParams::ApplyScissor(
// device space, it will be contained in in the original scissor.
// Applying the scissor explicitly means avoiding a clipRect() call and
// allows more quads to be batched together in a DrawEdgeAAImageSet call
- float left_inset = local_scissor.x() - visible_rect.x();
- float top_inset = local_scissor.y() - visible_rect.y();
- float right_inset = visible_rect.right() - local_scissor.right();
- float bottom_inset = visible_rect.bottom() - local_scissor.bottom();
+ float x_epsilon = kAAEpsilon / content_device_transform.matrix().get(0, 0);
+ float y_epsilon = kAAEpsilon / content_device_transform.matrix().get(1, 1);
- // The scissor is a non-AA clip, so we unset the bit flag for clipped edges.
- if (left_inset >= kAAEpsilon) {
+ // The scissor is a non-AA clip, so unset the bit flag for clipped edges.
+ if (local_scissor.x() - visible_rect.x() >= x_epsilon)
aa_flags &= ~SkCanvas::kLeft_QuadAAFlag;
- } else {
- left_inset = 0;
- }
- if (top_inset >= kAAEpsilon) {
+ if (local_scissor.y() - visible_rect.y() >= y_epsilon)
aa_flags &= ~SkCanvas::kTop_QuadAAFlag;
- } else {
- top_inset = 0;
- }
- if (right_inset >= kAAEpsilon) {
+ if (visible_rect.right() - local_scissor.right() >= x_epsilon)
aa_flags &= ~SkCanvas::kRight_QuadAAFlag;
- } else {
- right_inset = 0;
- }
- if (bottom_inset >= kAAEpsilon) {
+ if (visible_rect.bottom() - local_scissor.bottom() >= y_epsilon)
aa_flags &= ~SkCanvas::kBottom_QuadAAFlag;
- } else {
- bottom_inset = 0;
- }
- visible_rect.Inset(left_inset, top_inset, right_inset, bottom_inset);
+ visible_rect.Intersect(local_scissor);
vis_tex_coords = visible_rect;
scissor_rect.reset();
}
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index 0b88dc6803e39d76acb2e4e42b8140b35ff49b34..132b9c5480ff6557909305259e624b89b502b050 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -339,6 +339,9 @@ crbug.com/948141 Pixel_CanvasDisplaySRGBAccelerated2D [ Failure ]
crbug.com/883500 [ android android-nexus-5 ] Pixel_BackgroundImage [ Failure ]
crbug.com/1029389 [ android android-nexus-5 ] Pixel_PrecisionRoundedCorner [ Failure ]
+# Fails on Nexus 5X.
+crbug.com/1307317 [ android android-chromium android-nexus-5x ] Pixel_PrecisionRoundedCorner [ Failure ]
+
# Flakes on Nexus 5X.
crbug.com/883500 [ android android-chromium android-nexus-5x ] Pixel_BackgroundImage [ RetryOnFailure ]
crbug.com/1065514 [ android android-chromium android-nexus-5x ] Pixel_WebGLReadPixelsTabSwitch [ RetryOnFailure ]

View File

@@ -7,7 +7,7 @@ Make chrome's install-sysroot scripts point to our custom sysroot builds,
which include extra deps that Electron needs (e.g. libnotify)
diff --git a/build/linux/sysroot_scripts/install-sysroot.py b/build/linux/sysroot_scripts/install-sysroot.py
index ada6208644cb22c9f51c571f9509e335c0836163..86b55223fc21adf0e01cb276ebc613f6ea24f8b2 100755
index ada6208644cb22c9f51c571f9509e335c0836163..8f7169a0837a80c05faebce85ab4feac9e02bde2 100755
--- a/build/linux/sysroot_scripts/install-sysroot.py
+++ b/build/linux/sysroot_scripts/install-sysroot.py
@@ -41,9 +41,11 @@ except ImportError:
@@ -19,8 +19,8 @@ index ada6208644cb22c9f51c571f9509e335c0836163..86b55223fc21adf0e01cb276ebc613f6
-URL_PREFIX = 'https://commondatastorage.googleapis.com'
-URL_PATH = 'chrome-linux-sysroot/toolchain'
+URL_PREFIX = 'https://s3.amazonaws.com'
+URL_PATH = 'electronjs-sysroots/toolchain'
+URL_PREFIX = 'https://dev-cdn.electronjs.org'
+URL_PATH = 'linux-sysroots'
VALID_ARCHS = ('arm', 'arm64', 'i386', 'amd64', 'mips', 'mips64el')

View File

@@ -0,0 +1,190 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 8 Feb 2022 03:29:24 +0100
Subject: Use-after-free of ID and IDREF attributes
If a document is parsed with XML_PARSE_DTDVALID and without
XML_PARSE_NOENT, the value of ID attributes has to be normalized after
potentially expanding entities in xmlRemoveID. Otherwise, later calls
to xmlGetID can return a pointer to previously freed memory.
ID attributes which are empty or contain only whitespace after
entity expansion are affected in a similar way. This is fixed by
not storing such attributes in the ID table.
The test to detect streaming mode when validating against a DTD was
broken. In connection with the defects above, this could result in a
use-after-free when using the xmlReader interface with validation.
Fix detection of streaming mode to avoid similar issues. (This changes
the expected result of a test case. But as far as I can tell, using the
XML reader with XIncludes referencing the root document never worked
properly, anyway.)
All of these issues can result in denial of service. Using xmlReader
with validation could result in disclosure of memory via the error
channel, typically stderr. The security impact of xmlGetID returning
a pointer to freed memory depends on the application. The typical use
case of calling xmlGetID on an unmodified document is not affected.
diff --git a/third_party/libxml/src/valid.c b/third_party/libxml/src/valid.c
index 5ee391c0418327f5e46293aedafdb353550f6f5b..8e596f1db3db40a5decc5f4b529abc7588c6bd66 100644
--- a/third_party/libxml/src/valid.c
+++ b/third_party/libxml/src/valid.c
@@ -479,6 +479,35 @@ nodeVPop(xmlValidCtxtPtr ctxt)
return (ret);
}
+/**
+ * xmlValidNormalizeString:
+ * @str: a string
+ *
+ * Normalize a string in-place.
+ */
+static void
+xmlValidNormalizeString(xmlChar *str) {
+ xmlChar *dst;
+ const xmlChar *src;
+
+ if (str == NULL)
+ return;
+ src = str;
+ dst = str;
+
+ while (*src == 0x20) src++;
+ while (*src != 0) {
+ if (*src == 0x20) {
+ while (*src == 0x20) src++;
+ if (*src != 0)
+ *dst++ = 0x20;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
#ifdef DEBUG_VALID_ALGO
static void
xmlValidPrintNode(xmlNodePtr cur) {
@@ -2607,6 +2636,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
+static int
+xmlIsStreaming(xmlValidCtxtPtr ctxt) {
+ xmlParserCtxtPtr pctxt;
+
+ if (ctxt == NULL)
+ return(0);
+ /*
+ * These magic values are also abused to detect whether we're validating
+ * while parsing a document. In this case, userData points to the parser
+ * context.
+ */
+ if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
+ (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
+ return(0);
+ pctxt = ctxt->userData;
+ return(pctxt->parseMode == XML_PARSE_READER);
+}
+
/**
* xmlFreeID:
* @not: A id
@@ -2650,7 +2697,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
if (doc == NULL) {
return(NULL);
}
- if (value == NULL) {
+ if ((value == NULL) || (value[0] == 0)) {
return(NULL);
}
if (attr == NULL) {
@@ -2681,7 +2728,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
*/
ret->value = xmlStrdup(value);
ret->doc = doc;
- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
+ if (xmlIsStreaming(ctxt)) {
/*
* Operating in streaming mode, attr is gonna disappear
*/
@@ -2820,6 +2867,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
ID = xmlNodeListGetString(doc, attr->children, 1);
if (ID == NULL)
return(-1);
+ xmlValidNormalizeString(ID);
id = xmlHashLookup(table, ID);
if (id == NULL || id->attr != attr) {
@@ -3009,7 +3057,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
* fill the structure.
*/
ret->value = xmlStrdup(value);
- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
+ if (xmlIsStreaming(ctxt)) {
/*
* Operating in streaming mode, attr is gonna disappear
*/
@@ -4028,8 +4076,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlChar *
xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
- xmlChar *ret, *dst;
- const xmlChar *src;
+ xmlChar *ret;
xmlAttributePtr attrDecl = NULL;
int extsubset = 0;
@@ -4070,19 +4117,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
ret = xmlStrdup(value);
if (ret == NULL)
return(NULL);
- src = value;
- dst = ret;
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
+ xmlValidNormalizeString(ret);
if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
"standalone: %s on %s value had to be normalized based on external subset declaration\n",
@@ -4114,8 +4149,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlChar *
xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
const xmlChar *name, const xmlChar *value) {
- xmlChar *ret, *dst;
- const xmlChar *src;
+ xmlChar *ret;
xmlAttributePtr attrDecl = NULL;
if (doc == NULL) return(NULL);
@@ -4145,19 +4179,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
ret = xmlStrdup(value);
if (ret == NULL)
return(NULL);
- src = value;
- dst = ret;
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
+ xmlValidNormalizeString(ret);
return(ret);
}

View File

@@ -0,0 +1,266 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fergal Daly <fergal@chromium.org>
Date: Thu, 7 Apr 2022 02:16:11 +0000
Subject: Use IsErrorDocument() to prevent BFCacheing of interstitials and
errors.
In the bug, a crash occurs because we try to cache an interstitial. We
catch some error documents via status codes etc but interstitials do
not consistently set those. Checking IsErrorDocument() is more reliable.
(cherry picked from commit 7a05b426c6c51254a08de9a8dee8db9c1911b9c9)
Bug: 1274308,1287996,1283050
Change-Id: Ifec662c169c77e33ca5dc4d56b0e42c8d71f1d97
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3319862
Commit-Queue: Fergal Daly <fergal@chromium.org>
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Alexander Timin <altimin@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#981026}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3559271
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Owners-Override: Hiroki Nakagawa <nhiroki@chromium.org>
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/branch-heads/4896@{#1065}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/base/tracing/protos/chrome_track_event.proto b/base/tracing/protos/chrome_track_event.proto
index d85626908f9c9e8ddb661a34cb89be4523b07ee4..47df2f78c611f0ac47b4de85078e07b01f603306 100644
--- a/base/tracing/protos/chrome_track_event.proto
+++ b/base/tracing/protos/chrome_track_event.proto
@@ -514,6 +514,7 @@ message BackForwardCacheCanStoreDocumentResult {
CACHE_CONTROL_NO_STORE_HTTP_ONLY_COOKIE_MODIFIED = 51;
NO_RESPONSE_HEAD = 52;
ACTIVATION_NAVIGATION_DISALLOWED_FOR_BUG_1234857 = 53;
+ ERROR_DOCUMENT = 54;
}
optional BackForwardCacheNotRestoredReason
diff --git a/content/browser/back_forward_cache_basics_browsertest.cc b/content/browser/back_forward_cache_basics_browsertest.cc
index 450e27a2e7a3477a08c911923bd6d055dba5a77d..0511b468f25d3430e3e725ae262ca45c6777a6f8 100644
--- a/content/browser/back_forward_cache_basics_browsertest.cc
+++ b/content/browser/back_forward_cache_basics_browsertest.cc
@@ -744,7 +744,8 @@ IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
EXPECT_FALSE(WaitForLoadStop(shell()->web_contents()));
ExpectNotRestored(
{BackForwardCacheMetrics::NotRestoredReason::kHTTPStatusNotOK,
- BackForwardCacheMetrics::NotRestoredReason::kNoResponseHead},
+ BackForwardCacheMetrics::NotRestoredReason::kNoResponseHead,
+ NotRestoredReason::kErrorDocument},
{}, {}, {}, {}, FROM_HERE);
}
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index 72d9f9b0c056a384d446f576b725e53e78d5474f..51d3829bee15be4bb8e315908772b6ab02a8ee56 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -52,6 +52,7 @@
#include "content/public/test/test_navigation_throttle_inserter.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/text_input_test_utils.h"
+#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_javascript_dialog_manager.h"
#include "content/test/web_contents_observer_test_utils.h"
@@ -665,6 +666,23 @@ void BackForwardCacheBrowserTest::ExpectBrowsingInstanceNotSwappedReasons(
<< location.ToString();
}
+void BackForwardCacheBrowserTest::NavigateAndBlock(GURL url,
+ int history_offset) {
+ // Block the navigation with an error.
+ std::unique_ptr<URLLoaderInterceptor> url_interceptor =
+ URLLoaderInterceptor::SetupRequestFailForURL(url,
+ net::ERR_BLOCKED_BY_CLIENT);
+ TestNavigationManager manager(web_contents(), url);
+ if (history_offset) {
+ shell()->GoBackOrForward(history_offset);
+ } else {
+ shell()->LoadURL(url);
+ }
+ manager.WaitForNavigationFinished();
+ ASSERT_EQ(current_frame_host()->GetLastCommittedURL(), url);
+ ASSERT_TRUE(current_frame_host()->IsErrorDocument());
+}
+
std::initializer_list<RenderFrameHostImpl*> Elements(
std::initializer_list<RenderFrameHostImpl*> t) {
return t;
diff --git a/content/browser/back_forward_cache_browsertest.h b/content/browser/back_forward_cache_browsertest.h
index fa1c8d0223ba43366ff34acd2a150901ca04b239..e5c915382bbffd8ded673b9c997532eded4184f4 100644
--- a/content/browser/back_forward_cache_browsertest.h
+++ b/content/browser/back_forward_cache_browsertest.h
@@ -167,6 +167,11 @@ class BackForwardCacheBrowserTest : public ContentBrowserTest,
void ReleaseKeyboardLock(RenderFrameHostImpl* rfh);
+ // Start a navigation to |url| but block it on an error. If |history_offset|
+ // is not 0, then the navigation will be a history navigation and this will
+ // assert that the URL after navigation is |url|.
+ void NavigateAndBlock(GURL url, int history_offset);
+
base::HistogramTester histogram_tester_;
bool same_site_back_forward_cache_enabled_ = true;
diff --git a/content/browser/back_forward_cache_internal_browsertest.cc b/content/browser/back_forward_cache_internal_browsertest.cc
index aad18a04a8775c937fa2ccb57cc2f102da729dbe..41e637bb394d4f5df3cd86d467336e7457e4aa39 100644
--- a/content/browser/back_forward_cache_internal_browsertest.cc
+++ b/content/browser/back_forward_cache_internal_browsertest.cc
@@ -3659,4 +3659,69 @@ IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
tester.IsDisabledForFrameWithReason(process_id, routing_id, reason));
}
+// Test that when we navigate away from an error page and back with no error
+// that we don't serve the error page from BFCache.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
+ ErrorDocumentNotCachedWithSecondError) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+ // Navigate to a.com.
+ ASSERT_TRUE(NavigateToURL(web_contents(), url_a));
+
+ // Navigate to b.com and block due to an error.
+ NavigateAndBlock(url_b, /*history_offset=*/0);
+ RenderFrameHostImplWrapper rfh_b(current_frame_host());
+
+ // Navigate back to a.com.
+ ASSERT_TRUE(HistoryGoBack(web_contents()));
+ ExpectRestored(FROM_HERE);
+ ASSERT_TRUE(rfh_b.WaitUntilRenderFrameDeleted());
+
+ // Navigate forward to b.com again and block with an error again.
+ NavigateAndBlock(url_b, /*history_offset=*/1);
+ ExpectNotRestored(
+ {NotRestoredReason::kHTTPStatusNotOK, NotRestoredReason::kNoResponseHead,
+ NotRestoredReason::kErrorDocument},
+ {}, {}, {}, {}, FROM_HERE);
+}
+
+// Test that when we navigate away from an error page and back with no error
+// that we don't serve the error page from BFCache.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
+ ErrorDocumentNotCachedWithoutSecondError) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+ // Navigate to a.com.
+ ASSERT_TRUE(NavigateToURL(web_contents(), url_a));
+
+ // Navigate to b.com and block due to an error.
+ NavigateAndBlock(url_b, /*history_offset=*/0);
+ RenderFrameHostImplWrapper rfh_b(current_frame_host());
+
+ int history_entry_id =
+ web_contents()->GetController().GetLastCommittedEntry()->GetUniqueID();
+
+ // Navigate back to a.com.
+ ASSERT_TRUE(HistoryGoBack(web_contents()));
+ ASSERT_TRUE(rfh_b.WaitUntilRenderFrameDeleted());
+
+ // Navigate forward to b.com again with no error.
+ ASSERT_TRUE(HistoryGoForward(web_contents()));
+
+ // We would normally confirm that the blocking reasons are correct, however,
+ // when performing a history navigations back to an error document, a new
+ // entry is created and the reasons in the old entry are not recorded.
+ //
+ // Check that we indeed got a new history entry.
+ ASSERT_NE(
+ history_entry_id,
+ web_contents()->GetController().GetLastCommittedEntry()->GetUniqueID());
+}
+
} // namespace content
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index d48b48718e5eb3ca09b439af4766d8749cb0be98..842fdf70c1d826d5fb26a2e8c2a3f228a18b24ea 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1407,6 +1407,8 @@ Page::BackForwardCacheNotRestoredReason NotRestoredReasonToProtocol(
case Reason::kActivationNavigationsDisallowedForBug1234857:
return Page::BackForwardCacheNotRestoredReasonEnum::
ActivationNavigationsDisallowedForBug1234857;
+ case Reason::kErrorDocument:
+ return Page::BackForwardCacheNotRestoredReasonEnum::ErrorDocument;
case Reason::kBlocklistedFeatures:
// Blocklisted features should be handled separately and be broken down
// into sub reasons.
@@ -1686,6 +1688,7 @@ Page::BackForwardCacheNotRestoredReasonType MapNotRestoredReasonToType(
case Reason::kCacheControlNoStoreCookieModified:
case Reason::kCacheControlNoStoreHTTPOnlyCookieModified:
case Reason::kNoResponseHead:
+ case Reason::kErrorDocument:
return Page::BackForwardCacheNotRestoredReasonTypeEnum::Circumstantial;
case Reason::kOptInUnloadHeaderNotPresent:
case Reason::kUnloadHandlerExistsInMainFrame:
diff --git a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
index 9077a176fff2af3ec4a84f918e81601b618902df..d2b7608067198a4bc623854feb8c1495a6662a87 100644
--- a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
+++ b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
@@ -183,6 +183,8 @@ ProtoEnum::BackForwardCacheNotRestoredReason NotRestoredReasonToTraceEnum(
return ProtoEnum::NO_RESPONSE_HEAD;
case Reason::kActivationNavigationsDisallowedForBug1234857:
return ProtoEnum::ACTIVATION_NAVIGATION_DISALLOWED_FOR_BUG_1234857;
+ case Reason::kErrorDocument:
+ return ProtoEnum::ERROR_DOCUMENT;
case Reason::kBlocklistedFeatures:
return ProtoEnum::BLOCKLISTED_FEATURES;
case Reason::kUnknown:
@@ -396,6 +398,8 @@ std::string BackForwardCacheCanStoreDocumentResult::NotRestoredReasonToString(
return "Activation navigations are disallowed to avoid bypassing "
"PasswordProtectionService as a workaround for "
"https://crbug.com/1234857.";
+ case Reason::kErrorDocument:
+ return "Error documents cannot be stored in bfcache";
}
}
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc
index ac7cb84e8059be774f48da429e21fd40a7bc53b8..5db2853cdb207bc3ceeccd9bf5ec0092db0aed25 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.cc
+++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -727,6 +727,13 @@ BackForwardCacheImpl::CanPotentiallyStorePageLater(RenderFrameHostImpl* rfh) {
if (rfh->last_http_status_code() != net::HTTP_OK)
result.No(BackForwardCacheMetrics::NotRestoredReason::kHTTPStatusNotOK);
+ // Interstitials and other internal error pages should set an error status
+ // code but there's no guarantee, e.g. https://crbug/1274308,
+ // https://crbug/1287996. This catches those cases. It might also make the
+ // kHTTPStatusNotOK check redundant.
+ if (rfh->IsErrorDocument())
+ result.No(BackForwardCacheMetrics::NotRestoredReason::kErrorDocument);
+
// Only store documents that were fetched via HTTP GET method.
if (rfh->last_http_method() != net::HttpRequestHeaders::kGetMethod)
result.No(BackForwardCacheMetrics::NotRestoredReason::kHTTPMethodNotGET);
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.h b/content/browser/renderer_host/back_forward_cache_metrics.h
index 05289d0ab65faf2939f74d76530091b8a9efd123..c2338608889ce4936c3a8b00833a5205c74a78af 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics.h
+++ b/content/browser/renderer_host/back_forward_cache_metrics.h
@@ -110,7 +110,8 @@ class BackForwardCacheMetrics
kCacheControlNoStoreHTTPOnlyCookieModified = 55,
kNoResponseHead = 56,
kActivationNavigationsDisallowedForBug1234857 = 57,
- kMaxValue = kActivationNavigationsDisallowedForBug1234857,
+ kErrorDocument = 58,
+ kMaxValue = kErrorDocument,
};
using NotRestoredReasons =
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 0ae53ce429dbc1bf254ac773e0499dfe07273d46..d7231d7cdf9c230b24cb661a86bd64da5d6e7eb8 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -7988,6 +7988,7 @@ domain Page
NoResponseHead
Unknown
ActivationNavigationsDisallowedForBug1234857
+ ErrorDocument
#Blocklisted features
WebSocket
WebTransport

View File

@@ -11,9 +11,15 @@
"src/electron/patches/node": "src/third_party/electron_node",
"src/electron/patches/ffmpeg": "src/third_party/ffmpeg",
"src/electron/patches/squirrel.mac": "src/third_party/squirrel.mac",
"src/electron/patches/Mantle": "src/third_party/squirrel.mac/vendor/Mantle",
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC"
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"src/electron/patches/angle": "src/third_party/angle",
"src/electron/patches/icu": "src/third_party/icu"
}

1
patches/ffmpeg/.patches Normal file
View File

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

View File

@@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dan Sanders <sandersd@chromium.org>
Date: Tue, 3 May 2022 14:39:37 -0700
Subject: Do not parse late SEI messages during decoding.
Bug: 1306751
Change-Id: I2088b9ff89bd8eee8ab82675258af302d9bfccf9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/third_party/ffmpeg/+/3625832
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index d7bcba332d4c0b2fdc3c6679de84738b4cd49623..f639a9206bbd8fcd7797b177c0a36008b5274ab5 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -678,6 +678,12 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
avpriv_request_sample(avctx, "data partitioning");
break;
case H264_NAL_SEI:
+ // If setup is finished, threads can contend over the contents of
+ // the active SEI.
+ if (h->setup_finished) {
+ av_log(h->avctx, AV_LOG_DEBUG, "Late SEI\n");
+ break;
+ }
ret = ff_h264_sei_decode(&h->sei, &nal->gb, &h->ps, avctx);
h->has_recovery_point = h->has_recovery_point || h->sei.recovery_point.recovery_frame_cnt != -1;
if (avctx->debug & FF_DEBUG_GREEN_MD)

1
patches/icu/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-14e51893e5b5.patch

View File

@@ -0,0 +1,415 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Frank Tang <ftang@chromium.org>
Date: Fri, 29 Apr 2022 16:50:59 -0700
Subject: CP PR 2070 fix int32 overflow
https://github.com/unicode-org/icu/pull/2070
https://unicode-org.atlassian.net/browse/ICU-22005
Bug: chromium:1316946
Change-Id: I6cd7d687a55b6cc157b1afa52365908be2992fa6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/deps/icu/+/3614280
Reviewed-by: Jungshik Shin <jshin@chromium.org>
(cherry picked from commit 85814e1af52482199a13d284545623ffbc9eef83)
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/deps/icu/+/3632709
diff --git a/README.chromium b/README.chromium
index db26d214ccf1b452339c1f9de759c4c9c7aafe58..2b319327cbfea9b7fb7a1ca240bbbd272e1dab14 100644
--- a/README.chromium
+++ b/README.chromium
@@ -264,3 +264,7 @@ D. Local Modifications
- upstream bug:
https://unicode-org.atlassian.net/browse/ICU-21865
+12. Patch i18n/formatted_string_builder to fix int32_t overflow bug
+ patches/formatted_string_builder.patch
+ - https://github.com/unicode-org/icu/pull/2070
+ - https://unicode-org.atlassian.net/browse/ICU-22005
diff --git a/patches/formatted_string_builder.patch b/patches/formatted_string_builder.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4fad6f18601f7b4097e2d46bfe6660bec2e2882d
--- /dev/null
+++ b/patches/formatted_string_builder.patch
@@ -0,0 +1,191 @@
+diff --git a/source/i18n/formatted_string_builder.cpp b/source/i18n/formatted_string_builder.cpp
+index 73407864..628fbea8 100644
+--- a/source/i18n/formatted_string_builder.cpp
++++ b/source/i18n/formatted_string_builder.cpp
+@@ -6,6 +6,7 @@
+ #if !UCONFIG_NO_FORMATTING
+
+ #include "formatted_string_builder.h"
++#include "putilimp.h"
+ #include "unicode/ustring.h"
+ #include "unicode/utf16.h"
+ #include "unicode/unum.h" // for UNumberFormatFields literals
+@@ -197,6 +198,9 @@ FormattedStringBuilder::splice(int32_t startThis, int32_t endThis, const Unicod
+ int32_t thisLength = endThis - startThis;
+ int32_t otherLength = endOther - startOther;
+ int32_t count = otherLength - thisLength;
++ if (U_FAILURE(status)) {
++ return count;
++ }
+ int32_t position;
+ if (count > 0) {
+ // Overall, chars need to be added.
+@@ -221,6 +225,9 @@ int32_t FormattedStringBuilder::append(const FormattedStringBuilder &other, UErr
+
+ int32_t
+ FormattedStringBuilder::insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status) {
++ if (U_FAILURE(status)) {
++ return 0;
++ }
+ if (this == &other) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+@@ -255,12 +262,18 @@ int32_t FormattedStringBuilder::prepareForInsert(int32_t index, int32_t count, U
+ U_ASSERT(index >= 0);
+ U_ASSERT(index <= fLength);
+ U_ASSERT(count >= 0);
++ U_ASSERT(fZero >= 0);
++ U_ASSERT(fLength >= 0);
++ U_ASSERT(getCapacity() - fZero >= fLength);
++ if (U_FAILURE(status)) {
++ return count;
++ }
+ if (index == 0 && fZero - count >= 0) {
+ // Append to start
+ fZero -= count;
+ fLength += count;
+ return fZero;
+- } else if (index == fLength && fZero + fLength + count < getCapacity()) {
++ } else if (index == fLength && count <= getCapacity() - fZero - fLength) {
+ // Append to end
+ fLength += count;
+ return fZero + fLength - count;
+@@ -275,18 +288,26 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+ int32_t oldZero = fZero;
+ char16_t *oldChars = getCharPtr();
+ Field *oldFields = getFieldPtr();
+- if (fLength + count > oldCapacity) {
+- if ((fLength + count) > INT32_MAX / 2) {
+- // If we continue, then newCapacity will overflow int32_t in the next line.
++ int32_t newLength;
++ if (uprv_add32_overflow(fLength, count, &newLength)) {
++ status = U_INPUT_TOO_LONG_ERROR;
++ return -1;
++ }
++ int32_t newZero;
++ if (newLength > oldCapacity) {
++ if (newLength > INT32_MAX / 2) {
++ // We do not support more than 1G char16_t in this code because
++ // dealing with >2G *bytes* can cause subtle bugs.
+ status = U_INPUT_TOO_LONG_ERROR;
+ return -1;
+ }
+- int32_t newCapacity = (fLength + count) * 2;
+- int32_t newZero = newCapacity / 2 - (fLength + count) / 2;
++ // Keep newCapacity also to at most 1G char16_t.
++ int32_t newCapacity = newLength * 2;
++ newZero = (newCapacity - newLength) / 2;
+
+ // C++ note: malloc appears in two places: here and in the assignment operator.
+- auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * newCapacity));
+- auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * newCapacity));
++ auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * static_cast<size_t>(newCapacity)));
++ auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * static_cast<size_t>(newCapacity)));
+ if (newChars == nullptr || newFields == nullptr) {
+ uprv_free(newChars);
+ uprv_free(newFields);
+@@ -315,10 +336,8 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+ fChars.heap.capacity = newCapacity;
+ fFields.heap.ptr = newFields;
+ fFields.heap.capacity = newCapacity;
+- fZero = newZero;
+- fLength += count;
+ } else {
+- int32_t newZero = oldCapacity / 2 - (fLength + count) / 2;
++ newZero = (oldCapacity - newLength) / 2;
+
+ // C++ note: memmove is required because src and dest may overlap.
+ // First copy the entire string to the location of the prefix, and then move the suffix
+@@ -331,18 +350,20 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+ uprv_memmove2(oldFields + newZero + index + count,
+ oldFields + newZero + index,
+ sizeof(Field) * (fLength - index));
+-
+- fZero = newZero;
+- fLength += count;
+ }
+- U_ASSERT((fZero + index) >= 0);
++ fZero = newZero;
++ fLength = newLength;
+ return fZero + index;
+ }
+
+ int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) {
+- // TODO: Reset the heap here? (If the string after removal can fit on stack?)
++ U_ASSERT(0 <= index);
++ U_ASSERT(index <= fLength);
++ U_ASSERT(count <= (fLength - index));
++ U_ASSERT(index <= getCapacity() - fZero);
++
+ int32_t position = index + fZero;
+- U_ASSERT(position >= 0);
++ // TODO: Reset the heap here? (If the string after removal can fit on stack?)
+ uprv_memmove2(getCharPtr() + position,
+ getCharPtr() + position + count,
+ sizeof(char16_t) * (fLength - index - count));
+diff --git a/source/test/intltest/formatted_string_builder_test.cpp b/source/test/intltest/formatted_string_builder_test.cpp
+index 45721a32..57294e24 100644
+--- a/source/test/intltest/formatted_string_builder_test.cpp
++++ b/source/test/intltest/formatted_string_builder_test.cpp
+@@ -22,6 +22,7 @@ class FormattedStringBuilderTest : public IntlTest {
+ void testFields();
+ void testUnlimitedCapacity();
+ void testCodePoints();
++ void testInsertOverflow();
+
+ void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
+
+@@ -50,6 +51,7 @@ void FormattedStringBuilderTest::runIndexedTest(int32_t index, UBool exec, const
+ TESTCASE_AUTO(testFields);
+ TESTCASE_AUTO(testUnlimitedCapacity);
+ TESTCASE_AUTO(testCodePoints);
++ TESTCASE_AUTO(testInsertOverflow);
+ TESTCASE_AUTO_END;
+ }
+
+@@ -308,6 +310,45 @@ void FormattedStringBuilderTest::testCodePoints() {
+ assertEquals("Code point count is 2", 2, nsb.codePointCount());
+ }
+
++void FormattedStringBuilderTest::testInsertOverflow() {
++ if (quick) return;
++ // Setup the test fixture in sb, sb2, ustr.
++ UErrorCode status = U_ZERO_ERROR;
++ FormattedStringBuilder sb;
++ int32_t data_length = INT32_MAX / 2;
++ UnicodeString ustr(data_length, u'a', data_length);
++ sb.append(ustr, kUndefinedField, status);
++ assertSuccess("Setup the first FormattedStringBuilder", status);
++
++ FormattedStringBuilder sb2;
++ sb2.append(ustr, kUndefinedField, status);
++ sb2.insert(0, ustr, 0, data_length / 2, kUndefinedField, status);
++ sb2.writeTerminator(status);
++ assertSuccess("Setup the second FormattedStringBuilder", status);
++
++ ustr = sb2.toUnicodeString();
++ // Complete setting up the test fixture in sb, sb2 and ustr.
++
++ // Test splice() of the second UnicodeString
++ sb.splice(0, 1, ustr, 1, ustr.length(),
++ kUndefinedField, status);
++ assertEquals(
++ "splice() long text should not crash but return U_INPUT_TOO_LONG_ERROR",
++ U_INPUT_TOO_LONG_ERROR, status);
++
++ // Test sb.insert() of the first FormattedStringBuilder with the second one.
++ sb.insert(0, sb2, status);
++ assertEquals(
++ "insert() long FormattedStringBuilder should not crash but return "
++ "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
++
++ // Test sb.insert() of the first FormattedStringBuilder with UnicodeString.
++ sb.insert(0, ustr, 0, ustr.length(), kUndefinedField, status);
++ assertEquals(
++ "insert() long UnicodeString should not crash but return "
++ "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
++}
++
+ void FormattedStringBuilderTest::assertEqualsImpl(const UnicodeString &a, const FormattedStringBuilder &b) {
+ // TODO: Why won't this compile without the IntlTest:: qualifier?
+ IntlTest::assertEquals("Lengths should be the same", a.length(), b.length());
diff --git a/source/i18n/formatted_string_builder.cpp b/source/i18n/formatted_string_builder.cpp
index 734078644b88efd47b47a58e97fee5bd06afb4f8..628fbea871167619f60cc6eed0ee4b7776dab7fe 100644
--- a/source/i18n/formatted_string_builder.cpp
+++ b/source/i18n/formatted_string_builder.cpp
@@ -6,6 +6,7 @@
#if !UCONFIG_NO_FORMATTING
#include "formatted_string_builder.h"
+#include "putilimp.h"
#include "unicode/ustring.h"
#include "unicode/utf16.h"
#include "unicode/unum.h" // for UNumberFormatFields literals
@@ -197,6 +198,9 @@ FormattedStringBuilder::splice(int32_t startThis, int32_t endThis, const Unicod
int32_t thisLength = endThis - startThis;
int32_t otherLength = endOther - startOther;
int32_t count = otherLength - thisLength;
+ if (U_FAILURE(status)) {
+ return count;
+ }
int32_t position;
if (count > 0) {
// Overall, chars need to be added.
@@ -221,6 +225,9 @@ int32_t FormattedStringBuilder::append(const FormattedStringBuilder &other, UErr
int32_t
FormattedStringBuilder::insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status) {
+ if (U_FAILURE(status)) {
+ return 0;
+ }
if (this == &other) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
@@ -255,12 +262,18 @@ int32_t FormattedStringBuilder::prepareForInsert(int32_t index, int32_t count, U
U_ASSERT(index >= 0);
U_ASSERT(index <= fLength);
U_ASSERT(count >= 0);
+ U_ASSERT(fZero >= 0);
+ U_ASSERT(fLength >= 0);
+ U_ASSERT(getCapacity() - fZero >= fLength);
+ if (U_FAILURE(status)) {
+ return count;
+ }
if (index == 0 && fZero - count >= 0) {
// Append to start
fZero -= count;
fLength += count;
return fZero;
- } else if (index == fLength && fZero + fLength + count < getCapacity()) {
+ } else if (index == fLength && count <= getCapacity() - fZero - fLength) {
// Append to end
fLength += count;
return fZero + fLength - count;
@@ -275,18 +288,26 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
int32_t oldZero = fZero;
char16_t *oldChars = getCharPtr();
Field *oldFields = getFieldPtr();
- if (fLength + count > oldCapacity) {
- if ((fLength + count) > INT32_MAX / 2) {
- // If we continue, then newCapacity will overflow int32_t in the next line.
+ int32_t newLength;
+ if (uprv_add32_overflow(fLength, count, &newLength)) {
+ status = U_INPUT_TOO_LONG_ERROR;
+ return -1;
+ }
+ int32_t newZero;
+ if (newLength > oldCapacity) {
+ if (newLength > INT32_MAX / 2) {
+ // We do not support more than 1G char16_t in this code because
+ // dealing with >2G *bytes* can cause subtle bugs.
status = U_INPUT_TOO_LONG_ERROR;
return -1;
}
- int32_t newCapacity = (fLength + count) * 2;
- int32_t newZero = newCapacity / 2 - (fLength + count) / 2;
+ // Keep newCapacity also to at most 1G char16_t.
+ int32_t newCapacity = newLength * 2;
+ newZero = (newCapacity - newLength) / 2;
// C++ note: malloc appears in two places: here and in the assignment operator.
- auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * newCapacity));
- auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * newCapacity));
+ auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * static_cast<size_t>(newCapacity)));
+ auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * static_cast<size_t>(newCapacity)));
if (newChars == nullptr || newFields == nullptr) {
uprv_free(newChars);
uprv_free(newFields);
@@ -315,10 +336,8 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
fChars.heap.capacity = newCapacity;
fFields.heap.ptr = newFields;
fFields.heap.capacity = newCapacity;
- fZero = newZero;
- fLength += count;
} else {
- int32_t newZero = oldCapacity / 2 - (fLength + count) / 2;
+ newZero = (oldCapacity - newLength) / 2;
// C++ note: memmove is required because src and dest may overlap.
// First copy the entire string to the location of the prefix, and then move the suffix
@@ -331,18 +350,20 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
uprv_memmove2(oldFields + newZero + index + count,
oldFields + newZero + index,
sizeof(Field) * (fLength - index));
-
- fZero = newZero;
- fLength += count;
}
- U_ASSERT((fZero + index) >= 0);
+ fZero = newZero;
+ fLength = newLength;
return fZero + index;
}
int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) {
- // TODO: Reset the heap here? (If the string after removal can fit on stack?)
+ U_ASSERT(0 <= index);
+ U_ASSERT(index <= fLength);
+ U_ASSERT(count <= (fLength - index));
+ U_ASSERT(index <= getCapacity() - fZero);
+
int32_t position = index + fZero;
- U_ASSERT(position >= 0);
+ // TODO: Reset the heap here? (If the string after removal can fit on stack?)
uprv_memmove2(getCharPtr() + position,
getCharPtr() + position + count,
sizeof(char16_t) * (fLength - index - count));
diff --git a/source/test/intltest/formatted_string_builder_test.cpp b/source/test/intltest/formatted_string_builder_test.cpp
index 45721a320ac816b3cf35a40fd7c0db6ff9ccf206..57294e2485639983cbd3a98a78ba236068846cb8 100644
--- a/source/test/intltest/formatted_string_builder_test.cpp
+++ b/source/test/intltest/formatted_string_builder_test.cpp
@@ -22,6 +22,7 @@ class FormattedStringBuilderTest : public IntlTest {
void testFields();
void testUnlimitedCapacity();
void testCodePoints();
+ void testInsertOverflow();
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
@@ -50,6 +51,7 @@ void FormattedStringBuilderTest::runIndexedTest(int32_t index, UBool exec, const
TESTCASE_AUTO(testFields);
TESTCASE_AUTO(testUnlimitedCapacity);
TESTCASE_AUTO(testCodePoints);
+ TESTCASE_AUTO(testInsertOverflow);
TESTCASE_AUTO_END;
}
@@ -308,6 +310,45 @@ void FormattedStringBuilderTest::testCodePoints() {
assertEquals("Code point count is 2", 2, nsb.codePointCount());
}
+void FormattedStringBuilderTest::testInsertOverflow() {
+ if (quick) return;
+ // Setup the test fixture in sb, sb2, ustr.
+ UErrorCode status = U_ZERO_ERROR;
+ FormattedStringBuilder sb;
+ int32_t data_length = INT32_MAX / 2;
+ UnicodeString ustr(data_length, u'a', data_length);
+ sb.append(ustr, kUndefinedField, status);
+ assertSuccess("Setup the first FormattedStringBuilder", status);
+
+ FormattedStringBuilder sb2;
+ sb2.append(ustr, kUndefinedField, status);
+ sb2.insert(0, ustr, 0, data_length / 2, kUndefinedField, status);
+ sb2.writeTerminator(status);
+ assertSuccess("Setup the second FormattedStringBuilder", status);
+
+ ustr = sb2.toUnicodeString();
+ // Complete setting up the test fixture in sb, sb2 and ustr.
+
+ // Test splice() of the second UnicodeString
+ sb.splice(0, 1, ustr, 1, ustr.length(),
+ kUndefinedField, status);
+ assertEquals(
+ "splice() long text should not crash but return U_INPUT_TOO_LONG_ERROR",
+ U_INPUT_TOO_LONG_ERROR, status);
+
+ // Test sb.insert() of the first FormattedStringBuilder with the second one.
+ sb.insert(0, sb2, status);
+ assertEquals(
+ "insert() long FormattedStringBuilder should not crash but return "
+ "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
+
+ // Test sb.insert() of the first FormattedStringBuilder with UnicodeString.
+ sb.insert(0, ustr, 0, ustr.length(), kUndefinedField, status);
+ assertEquals(
+ "insert() long UnicodeString should not crash but return "
+ "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
+}
+
void FormattedStringBuilderTest::assertEqualsImpl(const UnicodeString &a, const FormattedStringBuilder &b) {
// TODO: Why won't this compile without the IntlTest:: qualifier?
IntlTest::assertEquals("Lengths should be the same", a.length(), b.length());

View File

@@ -44,3 +44,6 @@ process_simplify_uv_write_int_calls_3519.patch
macos_don_t_use_thread-unsafe_strtok_3524.patch
process_fix_hang_after_note_exit_3521.patch
worker_thread_add_asar_support.patch
macos_avoid_posix_spawnp_cwd_bug_3597.patch
build_disable_v8_pointer_compression_on_32bit_archs.patch
feat_add_knostartdebugsignalhandler_to_environment_to_prevent.patch

View File

@@ -1793,11 +1793,11 @@ index 08e957472cfeca84af8cdc951af3c0de99c7b56c..330d77e868a50e1d0b71d773ab6b4b33
// which the Node binary being built supports.
diff --git a/tools/generate_gn_filenames_json.py b/tools/generate_gn_filenames_json.py
new file mode 100755
index 0000000000000000000000000000000000000000..8f884a41f57630ac432eb85ebfc9b8bc82cddaca
index 0000000000000000000000000000000000000000..87621ba1d7f1c80aadb81461824b0c2edab1de22
--- /dev/null
+++ b/tools/generate_gn_filenames_json.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#!/usr/bin/env python3
+import json
+import os
+import sys
@@ -1874,11 +1874,11 @@ index 0000000000000000000000000000000000000000..8f884a41f57630ac432eb85ebfc9b8bc
+ f.write('\n')
diff --git a/tools/generate_node_version_header.py b/tools/generate_node_version_header.py
new file mode 100755
index 0000000000000000000000000000000000000000..3088ae4bdf814ae255c9805ebd393b2eee17e941
index 0000000000000000000000000000000000000000..2a92eccfa582df361f2a889c0d9b32c1059baa7d
--- /dev/null
+++ b/tools/generate_node_version_header.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+#!/usr/bin/env python3
+import re
+import sys
+

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Tue, 12 Oct 2021 10:41:55 +0900
Subject: build: disable v8 pointer compression on 32bit archs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PR-URL: https://github.com/nodejs/node/pull/40418
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Stewart X Addison <sxa@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
diff --git a/common.gypi b/common.gypi
index 8a85c7c3d0ab0e2906c417f2cc2fc9ca584fd601..f6ea8340b696103d0949df7fb7b75a1d05e90f87 100644
--- a/common.gypi
+++ b/common.gypi
@@ -130,6 +130,11 @@
['target_arch == "arm64" or target_arch == "x64"', {
'v8_enable_pointer_compression': 1,
}],
+ # V8 pointer compression only supports 64bit architectures.
+ ['target_arch in "arm ia32 mips mipsel ppc x32"', {
+ 'v8_enable_pointer_compression': 0,
+ 'v8_enable_31bit_smis_on_64bit_arch': 0,
+ }],
['target_arch in "ppc64 s390x"', {
'v8_enable_backtrace': 1,
}],

View File

@@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Mon, 7 Mar 2022 16:36:28 -0800
Subject: feat: add kNoStartDebugSignalHandler to Environment to prevent
SIGUSR1 handling
This patch should be upstreamed, it allows embedders to prevent the call to StartDebugSignalHandler which handles SIGUSR1 and starts the inspector agent. Apps that have --inspect disabled also don't want SIGUSR1 to have this affect.
diff --git a/src/env-inl.h b/src/env-inl.h
index 845e00208af4b12960ed8b3f3926323af7685185..1ebc33324907654d16e9c0e19b2955efbac7cac7 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -896,6 +896,10 @@ inline bool Environment::should_initialize_inspector() const {
return (flags_ & EnvironmentFlags::kNoInitializeInspector) == 0;
}
+inline bool Environment::should_start_debug_signal_handler() const {
+ return (flags_ & EnvironmentFlags::kNoStartDebugSignalHandler) == 0;
+}
+
bool Environment::filehandle_close_warning() const {
return emit_filehandle_warning_;
}
diff --git a/src/env.h b/src/env.h
index ab8334bf0e3405fee4d21a4b541bd1164d92ca89..b2537ebd44bc5b37dd97752735f84e87de1f24bf 100644
--- a/src/env.h
+++ b/src/env.h
@@ -1207,6 +1207,7 @@ class Environment : public MemoryRetainer {
inline bool hide_console_windows() const;
inline bool no_global_search_paths() const;
inline bool should_initialize_inspector() const;
+ inline bool should_start_debug_signal_handler() const;
inline uint64_t thread_id() const;
inline worker::Worker* worker_context() const;
Environment* worker_parent_env() const;
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
index c4a3322c6d972fc2052af75b79389c522924d9c5..39ff8df415be1908ba404fba34d9cedda04a88af 100644
--- a/src/inspector_agent.cc
+++ b/src/inspector_agent.cc
@@ -680,8 +680,10 @@ bool Agent::Start(const std::string& path,
StartIoThreadAsyncCallback));
uv_unref(reinterpret_cast<uv_handle_t*>(&start_io_thread_async));
start_io_thread_async.data = this;
- // Ignore failure, SIGUSR1 won't work, but that should not block node start.
- StartDebugSignalHandler();
+ if (parent_env_->should_start_debug_signal_handler()) {
+ // Ignore failure, SIGUSR1 won't work, but that should not block node start.
+ StartDebugSignalHandler();
+ }
parent_env_->AddCleanupHook([](void* data) {
Environment* env = static_cast<Environment*>(data);
diff --git a/src/node.h b/src/node.h
index 4201c0d0460b032721ef42a26d79c38a9ee20c24..6873fc89406b046823db9e45234eb7f6b767099d 100644
--- a/src/node.h
+++ b/src/node.h
@@ -425,7 +425,11 @@ enum Flags : uint64_t {
// Controls whether or not the Environment should call InitializeInspector.
// This control is needed by embedders who may not want to initialize the V8
// inspector in situations where it already exists.
- kNoInitializeInspector = 1 << 8
+ kNoInitializeInspector = 1 << 8,
+ // Controls where or not the InspectorAgent for this Environment should
+ // call StartDebugSignalHandler. This control is needed by embedders who may
+ // not want to allow other processes to start the V8 inspector.
+ kNoStartDebugSignalHandler = 1 << 9
};
} // namespace EnvironmentFlags

View File

@@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash@gmail.com>
Date: Fri, 15 Apr 2022 14:10:27 -0400
Subject: macos: avoid posix_spawnp() cwd bug (#3597)
macOS 10.15 has a bug where configuring the working directory with
posix_spawn_file_actions_addchdir_np() makes posix_spawnp() fail with
ENOENT even though the executable is spawned successfully.
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index c8816b85b7e531648064e739fb89257565ad64bb..de51bac3d0e8daf519d35c6a3994f1479590607a 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -671,27 +671,25 @@ static int uv__spawn_resolve_and_spawn(const uv_process_options_t* options,
if (options->env != NULL)
env = options->env;
- /* If options->file contains a slash, posix_spawn/posix_spawnp behave
- * the same, and don't involve PATH resolution at all. Otherwise, if
- * options->file does not include a slash, but no custom environment is
- * to be used, the environment used for path resolution as well for the
- * child process is that of the parent process, so posix_spawnp is the
- * way to go. */
- if (strchr(options->file, '/') != NULL || options->env == NULL) {
+ /* If options->file contains a slash, posix_spawn/posix_spawnp should behave
+ * the same, and do not involve PATH resolution at all. The libc
+ * `posix_spawnp` provided by Apple is buggy (since 10.15), so we now emulate it
+ * here, per https://github.com/libuv/libuv/pull/3583. */
+ if (strchr(options->file, '/') != NULL) {
do
- err = posix_spawnp(pid, options->file, actions, attrs, options->args, env);
+ err = posix_spawn(pid, options->file, actions, attrs, options->args, env);
while (err == EINTR);
return err;
}
/* Look for the definition of PATH in the provided env */
- path = uv__spawn_find_path_in_env(options->env);
+ path = uv__spawn_find_path_in_env(env);
/* The following resolution logic (execvpe emulation) is copied from
* https://git.musl-libc.org/cgit/musl/tree/src/process/execvp.c
* and adapted to work for our specific usage */
- /* If no path was provided in options->env, use the default value
+ /* If no path was provided in env, use the default value
* to look for the executable */
if (path == NULL)
path = _PATH_DEFPATH;
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 58489c4be7b3a7b36d5b01a1f07d411ef3d99ae3..b4c039706417ab679c4f24a863118e736635371c 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -319,6 +319,7 @@ TEST_DECLARE (spawn_inherit_streams)
TEST_DECLARE (spawn_quoted_path)
TEST_DECLARE (spawn_tcp_server)
TEST_DECLARE (spawn_exercise_sigchld_issue)
+TEST_DECLARE (spawn_relative_path)
TEST_DECLARE (fs_poll)
TEST_DECLARE (fs_poll_getpath)
TEST_DECLARE (fs_poll_close_request)
@@ -946,6 +947,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_quoted_path)
TEST_ENTRY (spawn_tcp_server)
TEST_ENTRY (spawn_exercise_sigchld_issue)
+ TEST_ENTRY (spawn_relative_path)
TEST_ENTRY (fs_poll)
TEST_ENTRY (fs_poll_getpath)
TEST_ENTRY (fs_poll_close_request)
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index dfd5458ef37c664af9a55a8383bdb3121885db3b..de9c710020ef7da66e45f5617a8a697e698fa202 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -1981,3 +1981,37 @@ void spawn_stdin_stdout(void) {
}
}
#endif /* !_WIN32 */
+
+TEST_IMPL(spawn_relative_path) {
+ char* sep;
+
+ init_process_options("spawn_helper1", exit_cb);
+
+ exepath_size = sizeof(exepath) - 2;
+ ASSERT_EQ(0, uv_exepath(exepath, &exepath_size));
+ exepath[exepath_size] = '\0';
+
+ /* Poor man's basename(3). */
+ sep = strrchr(exepath, '/');
+ if (sep == NULL)
+ sep = strrchr(exepath, '\\');
+ ASSERT_NOT_NULL(sep);
+
+ /* Split into dirname and basename and make basename relative. */
+ memmove(sep + 2, sep, 1 + strlen(sep));
+ sep[0] = '\0';
+ sep[1] = '.';
+ sep[2] = '/';
+
+ options.cwd = exepath;
+ options.file = options.args[0] = sep + 1;
+
+ ASSERT_EQ(0, uv_spawn(uv_default_loop(), &process, &options));
+ ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT_EQ(1, exit_cb_called);
+ ASSERT_EQ(1, close_cb_called);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}

View File

@@ -511,11 +511,11 @@ index 0000000000000000000000000000000000000000..bdfaf95f3eca65b3e0831db1b66f651d
+}
diff --git a/build/xcrun.py b/build/xcrun.py
new file mode 100644
index 0000000000000000000000000000000000000000..18ac587f80441106405d00fafd9ee1f25b147772
index 0000000000000000000000000000000000000000..a7aeeb7d3e187bd91ef12ed860d1e37eaea31fc1
--- /dev/null
+++ b/build/xcrun.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+#!/usr/bin/env python3
+from __future__ import print_function
+import os
+import subprocess

View File

@@ -8,3 +8,9 @@ fix_build_deprecated_attirbute_for_older_msvc_versions.patch
fix_disable_implies_dcheck_for_node_stream_array_buffers.patch
fix_use_allocationtype_kold_in_v8_scriptormodule_legacy_lifetime.patch
fix_destructor_for_embedderstatescope.patch
cherry-pick-36b66b5cc991.patch
cherry-pick-f546ac11eec7.patch
cherry-pick-e42dbcdedb7a.patch
cherry-pick-b2d3ef69ef99.patch
cherry-pick-2004594a46c8.patch
cherry-pick-723ed8a9cfff.patch

View File

@@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nico Hartmann <nicohartmann@chromium.org>
Date: Thu, 17 Mar 2022 17:03:12 +0100
Subject: Fix NumberConstant used with Word32 rep in ISel
Bug: chromium:1304658
(cherry picked from commit bbea5909c797dec7c620b9fee43d80a1420c2e08)
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: I6a82603a7c5de5ae8f5a895990c1a904bbdd39b2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3532263
Auto-Submit: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79526}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3541919
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/9.6@{#58}
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
diff --git a/src/compiler/backend/instruction-selector.cc b/src/compiler/backend/instruction-selector.cc
index fc04b37ec3fe1a3f4e9db0a1ba825b71696ec0cb..c6b41ca79120c1f553e4c10eff8d3285bf9bbe91 100644
--- a/src/compiler/backend/instruction-selector.cc
+++ b/src/compiler/backend/instruction-selector.cc
@@ -30,6 +30,14 @@ namespace v8 {
namespace internal {
namespace compiler {
+Smi NumberConstantToSmi(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kNumberConstant);
+ const double d = OpParameter<double>(node->op());
+ Smi smi = Smi::FromInt(static_cast<int32_t>(d));
+ CHECK_EQ(smi.value(), d);
+ return smi;
+}
+
InstructionSelector::InstructionSelector(
Zone* zone, size_t node_count, Linkage* linkage,
InstructionSequence* sequence, Schedule* schedule,
@@ -501,11 +509,17 @@ InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g,
switch (input->opcode()) {
case IrOpcode::kInt32Constant:
case IrOpcode::kInt64Constant:
- case IrOpcode::kNumberConstant:
case IrOpcode::kFloat32Constant:
case IrOpcode::kFloat64Constant:
case IrOpcode::kDelayedStringConstant:
return g->UseImmediate(input);
+ case IrOpcode::kNumberConstant:
+ if (rep == MachineRepresentation::kWord32) {
+ Smi smi = NumberConstantToSmi(input);
+ return g->UseImmediate(static_cast<int32_t>(smi.ptr()));
+ } else {
+ return g->UseImmediate(input);
+ }
case IrOpcode::kCompressedHeapConstant:
case IrOpcode::kHeapConstant: {
if (!CanBeTaggedOrCompressedPointer(rep)) {

View File

@@ -0,0 +1,142 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Fri, 1 Apr 2022 17:41:24 +0200
Subject: Merged: [runtime] Fix handling of interceptors, pt.3
... in JSObject::DefineOwnPropertyIgnoreAttributes().
Don't execute interceptor again if it declined to handle the operation.
Bug: chromium:1311641
(cherry picked from commit c4e66b89b4ecd0e90b31e9e4ed08d38085a84c49)
Change-Id: Ie9aef5a98959403f6a26e6bef7f4a77d312bd62a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3563560
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.0@{#16}
Cr-Branched-From: 6ea73a738c467dc26abbbe84e27a36aac1c6e119-refs/heads/10.0.139@{#1}
Cr-Branched-From: ccc689011280419901e6ee42cae39980c0e96030-refs/heads/main@{#79131}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 1df13df72c29f804168ab1f57117650922378a07..d823bba604936c1c99b4e3aea694afc8fa267d83 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -3451,9 +3451,18 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
if (can_define.IsNothing() || !can_define.FromJust()) {
return can_define;
}
- it->Restart();
}
- break;
+
+ // The interceptor declined to handle the operation, so proceed defining
+ // own property without the interceptor.
+ Isolate* isolate = it->isolate();
+ Handle<Object> receiver = it->GetReceiver();
+ LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
+ LookupIterator own_lookup =
+ it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
+ : LookupIterator(isolate, receiver, it->name(), c);
+ return JSObject::DefineOwnPropertyIgnoreAttributes(
+ &own_lookup, value, attributes, should_throw, handling, semantics);
}
case LookupIterator::ACCESSOR: {
diff --git a/test/cctest/test-api-interceptors.cc b/test/cctest/test-api-interceptors.cc
index 909795ece407ac2089f15e562d308733371fbb65..7eb96a54f77519a8b968d40fab4d01070e0ed179 100644
--- a/test/cctest/test-api-interceptors.cc
+++ b/test/cctest/test-api-interceptors.cc
@@ -60,6 +60,16 @@ void EmptyInterceptorDeleter(
void EmptyInterceptorEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {}
+void EmptyInterceptorDefinerWithSideEffect(
+ Local<Name> name, const v8::PropertyDescriptor& desc,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ ApiTestFuzzer::Fuzz();
+ v8::Local<v8::Value> result = CompileRun("interceptor_definer_side_effect()");
+ if (!result->IsNull()) {
+ info.GetReturnValue().Set(result);
+ }
+}
+
void SimpleAccessorGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
Local<Object> self = info.This().As<Object>();
@@ -869,13 +879,17 @@ THREADED_TEST(InterceptorHasOwnPropertyCausingGC) {
namespace {
void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
+ v8::GenericNamedPropertySetterCallback setter,
v8::GenericNamedPropertyQueryCallback query,
- const char* source, int expected) {
+ v8::GenericNamedPropertyDefinerCallback definer,
+ v8::PropertyHandlerFlags flags, const char* source,
+ int expected) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
- getter, nullptr, query, nullptr, nullptr, v8_str("data")));
+ getter, setter, query, nullptr /* deleter */, nullptr /* enumerator */,
+ definer, nullptr /* descriptor */, v8_str("data"), flags));
LocalContext context;
context->Global()
->Set(context.local(), v8_str("o"),
@@ -885,9 +899,17 @@ void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
CHECK_EQ(expected, value->Int32Value(context.local()).FromJust());
}
+void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
+ v8::GenericNamedPropertyQueryCallback query,
+ const char* source, int expected) {
+ CheckInterceptorIC(getter, nullptr, query, nullptr,
+ v8::PropertyHandlerFlags::kNone, source, expected);
+}
+
void CheckInterceptorLoadIC(v8::GenericNamedPropertyGetterCallback getter,
const char* source, int expected) {
- CheckInterceptorIC(getter, nullptr, source, expected);
+ CheckInterceptorIC(getter, nullptr, nullptr, nullptr,
+ v8::PropertyHandlerFlags::kNone, source, expected);
}
void InterceptorLoadICGetter(Local<Name> name,
@@ -1581,6 +1603,38 @@ THREADED_TEST(InterceptorStoreICWithSideEffectfulCallbacks) {
19);
}
+THREADED_TEST(InterceptorDefineICWithSideEffectfulCallbacks) {
+ CheckInterceptorIC(EmptyInterceptorGetter, EmptyInterceptorSetter,
+ EmptyInterceptorQuery,
+ EmptyInterceptorDefinerWithSideEffect,
+ v8::PropertyHandlerFlags::kNonMasking,
+ "let inside_side_effect = false;"
+ "let interceptor_definer_side_effect = function() {"
+ " if (!inside_side_effect) {"
+ " inside_side_effect = true;"
+ " o.y = 153;"
+ " inside_side_effect = false;"
+ " }"
+ " return null;"
+ "};"
+ "class Base {"
+ " constructor(arg) {"
+ " return arg;"
+ " }"
+ "}"
+ "class ClassWithField extends Base {"
+ " y = (() => {"
+ " return 42;"
+ " })();"
+ " constructor(arg) {"
+ " super(arg);"
+ " }"
+ "}"
+ "new ClassWithField(o);"
+ "o.y",
+ 42);
+}
+
static void InterceptorStoreICSetter(
Local<Name> key, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {

View File

@@ -0,0 +1,195 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakob Kummerow <jkummerow@chromium.org>
Date: Mon, 2 May 2022 19:52:11 +0200
Subject: Merged: [wasm] Fix Int64Lowering for tagged stack-passed parameters
When lowering signatures, we must preserve the separation of parameters
into tagged and untagged sections.
Fixed: chromium:1320614
(cherry picked from commit 8062598f26127d833c237acb3da154c91c1ec7e7)
Change-Id: I2f84535f785ce5c96e9c892994416986965eaa40
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3632515
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.1@{#28}
Cr-Branched-From: b003970395b7efcc309eb30b4ca06dd8385acd55-refs/heads/10.1.124@{#1}
Cr-Branched-From: e62f556862624103ea1da5b9dcef9b216832033b-refs/heads/main@{#79503}
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
index 07bb41358898fbd9c5968fb8a37dff161e71ed65..5bd325035726d4e91ede2b54076dd0d2cfdce8c0 100644
--- a/src/compiler/wasm-compiler.cc
+++ b/src/compiler/wasm-compiler.cc
@@ -8233,16 +8233,10 @@ class LinkageLocationAllocator {
// must be offset to just before the param slots, using this |slot_offset_|.
int slot_offset_;
};
-} // namespace
-// General code uses the above configuration data.
-CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
- WasmCallKind call_kind,
- bool need_frame_state) {
- // The extra here is to accomodate the instance object as first parameter
- // and, when specified, the additional callable.
- bool extra_callable_param =
- call_kind == kWasmImportWrapper || call_kind == kWasmCapiFunction;
+LocationSignature* BuildLocations(Zone* zone, const wasm::FunctionSig* fsig,
+ bool extra_callable_param,
+ int* parameter_slots, int* return_slots) {
int extra_params = extra_callable_param ? 2 : 1;
LocationSignature::Builder locations(zone, fsig->return_count(),
fsig->parameter_count() + extra_params);
@@ -8285,19 +8279,37 @@ CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
kJSFunctionRegister.code(), MachineType::TaggedPointer()));
}
- int parameter_slots = AddArgumentPaddingSlots(params.NumStackSlots());
+ *parameter_slots = AddArgumentPaddingSlots(params.NumStackSlots());
// Add return location(s).
LinkageLocationAllocator rets(wasm::kGpReturnRegisters,
- wasm::kFpReturnRegisters, parameter_slots);
+ wasm::kFpReturnRegisters, *parameter_slots);
- const int return_count = static_cast<int>(locations.return_count_);
- for (int i = 0; i < return_count; i++) {
+ const size_t return_count = locations.return_count_;
+ for (size_t i = 0; i < return_count; i++) {
MachineRepresentation ret = fsig->GetReturn(i).machine_representation();
locations.AddReturn(rets.Next(ret));
}
- int return_slots = rets.NumStackSlots();
+ *return_slots = rets.NumStackSlots();
+
+ return locations.Build();
+}
+} // namespace
+
+// General code uses the above configuration data.
+CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
+ WasmCallKind call_kind,
+ bool need_frame_state) {
+ // The extra here is to accomodate the instance object as first parameter
+ // and, when specified, the additional callable.
+ bool extra_callable_param =
+ call_kind == kWasmImportWrapper || call_kind == kWasmCapiFunction;
+
+ int parameter_slots;
+ int return_slots;
+ LocationSignature* location_sig = BuildLocations(
+ zone, fsig, extra_callable_param, &parameter_slots, &return_slots);
const RegList kCalleeSaveRegisters = 0;
const RegList kCalleeSaveFPRegisters = 0;
@@ -8323,7 +8335,7 @@ CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
descriptor_kind, // kind
target_type, // target MachineType
target_loc, // target location
- locations.Build(), // location_sig
+ location_sig, // location_sig
parameter_slots, // parameter slot count
compiler::Operator::kNoProperties, // properties
kCalleeSaveRegisters, // callee-saved registers
@@ -8374,78 +8386,45 @@ const wasm::FunctionSig* ReplaceTypeInSig(Zone* zone,
CallDescriptor* ReplaceTypeInCallDescriptorWith(
Zone* zone, const CallDescriptor* call_descriptor, size_t num_replacements,
wasm::ValueType input_type, wasm::ValueType output_type) {
- size_t parameter_count = call_descriptor->ParameterCount();
- size_t return_count = call_descriptor->ReturnCount();
- for (size_t i = 0; i < call_descriptor->ParameterCount(); i++) {
- if (call_descriptor->GetParameterType(i) == input_type.machine_type()) {
- parameter_count += num_replacements - 1;
+ if (call_descriptor->wasm_sig() == nullptr) {
+ // This happens for builtins calls. They need no replacements anyway.
+#if DEBUG
+ for (size_t i = 0; i < call_descriptor->ParameterCount(); i++) {
+ DCHECK_NE(call_descriptor->GetParameterType(i),
+ input_type.machine_type());
}
- }
- for (size_t i = 0; i < call_descriptor->ReturnCount(); i++) {
- if (call_descriptor->GetReturnType(i) == input_type.machine_type()) {
- return_count += num_replacements - 1;
+ for (size_t i = 0; i < call_descriptor->ReturnCount(); i++) {
+ DCHECK_NE(call_descriptor->GetReturnType(i), input_type.machine_type());
}
+#endif
+ return const_cast<CallDescriptor*>(call_descriptor);
}
- if (parameter_count == call_descriptor->ParameterCount() &&
- return_count == call_descriptor->ReturnCount()) {
+ const wasm::FunctionSig* sig =
+ ReplaceTypeInSig(zone, call_descriptor->wasm_sig(), input_type,
+ output_type, num_replacements);
+ // If {ReplaceTypeInSig} took the early fast path, there's nothing to do.
+ if (sig == call_descriptor->wasm_sig()) {
return const_cast<CallDescriptor*>(call_descriptor);
}
- LocationSignature::Builder locations(zone, return_count, parameter_count);
-
// The last parameter may be the special callable parameter. In that case we
// have to preserve it as the last parameter, i.e. we allocate it in the new
// location signature again in the same register.
- bool has_callable_param =
+ bool extra_callable_param =
(call_descriptor->GetInputLocation(call_descriptor->InputCount() - 1) ==
LinkageLocation::ForRegister(kJSFunctionRegister.code(),
MachineType::TaggedPointer()));
- LinkageLocationAllocator params(
- wasm::kGpParamRegisters, wasm::kFpParamRegisters, 0 /* no slot offset */);
-
- for (size_t i = 0;
- i < call_descriptor->ParameterCount() - (has_callable_param ? 1 : 0);
- i++) {
- if (call_descriptor->GetParameterType(i) == input_type.machine_type()) {
- for (size_t j = 0; j < num_replacements; j++) {
- locations.AddParam(params.Next(output_type.machine_representation()));
- }
- } else {
- locations.AddParam(
- params.Next(call_descriptor->GetParameterType(i).representation()));
- }
- }
- if (has_callable_param) {
- locations.AddParam(LinkageLocation::ForRegister(
- kJSFunctionRegister.code(), MachineType::TaggedPointer()));
- }
-
- int parameter_slots = AddArgumentPaddingSlots(params.NumStackSlots());
-
- LinkageLocationAllocator rets(wasm::kGpReturnRegisters,
- wasm::kFpReturnRegisters, parameter_slots);
-
- for (size_t i = 0; i < call_descriptor->ReturnCount(); i++) {
- if (call_descriptor->GetReturnType(i) == input_type.machine_type()) {
- for (size_t j = 0; j < num_replacements; j++) {
- locations.AddReturn(rets.Next(output_type.machine_representation()));
- }
- } else {
- locations.AddReturn(
- rets.Next(call_descriptor->GetReturnType(i).representation()));
- }
- }
-
- int return_slots = rets.NumStackSlots();
- auto sig = ReplaceTypeInSig(zone, call_descriptor->wasm_sig(), input_type,
- output_type, num_replacements);
+ int parameter_slots;
+ int return_slots;
+ LocationSignature* location_sig = BuildLocations(
+ zone, sig, extra_callable_param, &parameter_slots, &return_slots);
return zone->New<CallDescriptor>( // --
call_descriptor->kind(), // kind
call_descriptor->GetInputType(0), // target MachineType
call_descriptor->GetInputLocation(0), // target location
- locations.Build(), // location_sig
+ location_sig, // location_sig
parameter_slots, // parameter slot count
call_descriptor->properties(), // properties
call_descriptor->CalleeSavedRegisters(), // callee-saved registers

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Wed, 13 Apr 2022 16:30:36 +0000
Subject: mark receiver and function as escaping
(cherry picked from commit 8081a5ffa7ebdb0e5b35cf63aa0490ad3578b940)
Bug: chromium:1315901
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: Ic44bfcae32aba202ba25c5f59fe579214a444584
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584117
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79968}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584531
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/9.6@{#62}
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc
index bf693c71dc670fdf290c6c5b84012d9965978c69..fe8126f9638e77ef72ddc56c7ae67822786d3020 100644
--- a/src/compiler/escape-analysis.cc
+++ b/src/compiler/escape-analysis.cc
@@ -5,10 +5,12 @@
#include "src/compiler/escape-analysis.h"
#include "src/codegen/tick-counter.h"
+#include "src/compiler/frame-states.h"
#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/simplified-operator.h"
+#include "src/compiler/state-values-utils.h"
#include "src/handles/handles-inl.h"
#include "src/init/bootstrapper.h"
#include "src/objects/map-inl.h"
@@ -224,6 +226,11 @@ class EscapeAnalysisTracker : public ZoneObject {
return tracker_->ResolveReplacement(
NodeProperties::GetContextInput(current_node()));
}
+ // Accessing the current node is fine for `FrameState nodes.
+ Node* CurrentNode() {
+ DCHECK_EQ(current_node()->opcode(), IrOpcode::kFrameState);
+ return current_node();
+ }
void SetReplacement(Node* replacement) {
replacement_ = replacement;
@@ -799,9 +806,25 @@ void ReduceNode(const Operator* op, EscapeAnalysisTracker::Scope* current,
break;
}
case IrOpcode::kStateValues:
- case IrOpcode::kFrameState:
// These uses are always safe.
break;
+ case IrOpcode::kFrameState: {
+ // We mark the receiver as escaping due to the non-standard `.getThis`
+ // API.
+ FrameState frame_state{current->CurrentNode()};
+ if (frame_state.frame_state_info().type() !=
+ FrameStateType::kUnoptimizedFunction)
+ break;
+ StateValuesAccess::iterator it =
+ StateValuesAccess(frame_state.parameters()).begin();
+ if (!it.done()) {
+ if (Node* receiver = it.node()) {
+ current->SetEscaped(receiver);
+ }
+ current->SetEscaped(frame_state.function());
+ }
+ break;
+ }
default: {
// For unknown nodes, treat all value inputs as escaping.
int value_input_count = op->ValueInputCount();

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brendon Tiszka <btiszka@gmail.com>
Date: Fri, 18 Mar 2022 01:32:54 -0400
Subject: Merged: Update write barrier when storing HeapNumber to last index.
(cherry picked from commit bdc4f54a50293507d9ef51573bab537883560cc8)
No-Try: true
No-Presubmit: true
No-Treechecks: true
Bug: chromium:1307610
Change-Id: I60aaa0e58e13b705b5eff4b57411a0ad4a2e9b3f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3534849
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79538}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3565716
Reviewed-by: Patrick Thier <pthier@chromium.org>
Commit-Queue: Jakob Linke <jgruber@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.0@{#18}
Cr-Branched-From: 6ea73a738c467dc26abbbe84e27a36aac1c6e119-refs/heads/10.0.139@{#1}
Cr-Branched-From: ccc689011280419901e6ee42cae39980c0e96030-refs/heads/main@{#79131}
diff --git a/src/regexp/regexp-utils.cc b/src/regexp/regexp-utils.cc
index dabe5ee4a280eb27a9e3ef3200a712f465f327aa..b26007191d3dbe52b05eb30394520dbce2983b9e 100644
--- a/src/regexp/regexp-utils.cc
+++ b/src/regexp/regexp-utils.cc
@@ -49,7 +49,8 @@ MaybeHandle<Object> RegExpUtils::SetLastIndex(Isolate* isolate,
Handle<Object> value_as_object =
isolate->factory()->NewNumberFromInt64(value);
if (HasInitialRegExpMap(isolate, *recv)) {
- JSRegExp::cast(*recv).set_last_index(*value_as_object, SKIP_WRITE_BARRIER);
+ JSRegExp::cast(*recv).set_last_index(*value_as_object,
+ UPDATE_WRITE_BARRIER);
return recv;
} else {
return Object::SetProperty(

View File

@@ -0,0 +1,92 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marja=20H=C3=B6ltt=C3=A4?= <marja@chromium.org>
Date: Thu, 24 Mar 2022 17:30:16 +0100
Subject: Turn off super ICs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
M96 merge issues:
Conflicts in the bytecode test expectations
They make assumptions which don't hold for API handlers.
(cherry picked from commit c6b68cbfbd49a24bd9d343d718132125370da729)
Bug: v8:9237,chromium:1308360
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: I9f122c4e75a24d83ef3653cbf7a223ed522e4d13
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3548899
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79614}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3553109
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/9.6@{#60}
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
diff --git a/src/flags/flag-definitions.h b/src/flags/flag-definitions.h
index 6a8eb146770118d9d0d8ae5efc5a7162a094e26b..9c000959f55e42f388ba4ae75b98a6a80201ed44 100644
--- a/src/flags/flag-definitions.h
+++ b/src/flags/flag-definitions.h
@@ -1659,7 +1659,7 @@ DEFINE_INT(max_valid_polymorphic_map_count, 4,
DEFINE_BOOL(native_code_counters, DEBUG_BOOL,
"generate extra code for manipulating stats counters")
-DEFINE_BOOL(super_ic, true, "use an IC for super property loads")
+DEFINE_BOOL(super_ic, false, "use an IC for super property loads")
DEFINE_BOOL(enable_mega_dom_ic, false, "use MegaDOM IC state for API objects")
diff --git a/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden b/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
index 82b6e16be98d8dd9d8fe6b8419653d2c02f7bf79..c433538d8ed52c52277f2ad7163fc4b15c29591c 100644
--- a/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
+++ b/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
@@ -20,14 +20,18 @@ snippet: "
test();
})();
"
-frame size: 1
+frame size: 5
parameter count: 1
-bytecode array length: 16
+bytecode array length: 24
bytecodes: [
/* 104 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
- /* 117 E> */ B(LdaNamedPropertyFromSuper), R(this), U8(0), U8(1),
+ B(Star3),
+ B(LdaConstant), U8(0),
+ B(Star4),
+ B(Mov), R(this), R(2),
+ /* 117 E> */ B(CallRuntime), U16(Runtime::kLoadFromSuper), R(2), U8(3),
B(Star0),
- /* 117 E> */ B(CallAnyReceiver), R(0), R(this), U8(1), U8(3),
+ /* 117 E> */ B(CallAnyReceiver), R(0), R(this), U8(1), U8(1),
/* 126 E> */ B(AddSmi), I8(1), U8(0),
/* 130 S> */ B(Return),
]
@@ -54,7 +58,7 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 24
+bytecode array length: 32
bytecodes: [
/* 130 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star1),
@@ -65,7 +69,11 @@ bytecodes: [
B(Mov), R(this), R(0),
/* 138 E> */ B(CallRuntime), U16(Runtime::kStoreToSuper), R(0), U8(4),
/* 143 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
- /* 156 E> */ B(LdaNamedPropertyFromSuper), R(this), U8(0), U8(0),
+ B(Star1),
+ B(LdaConstant), U8(0),
+ B(Star2),
+ B(Mov), R(this), R(0),
+ /* 156 E> */ B(CallRuntime), U16(Runtime::kLoadFromSuper), R(0), U8(3),
/* 158 S> */ B(Return),
]
constant pool: [

View File

@@ -1 +1,3 @@
add_thread_local_to_x_error_trap_cc.patch
adding_fuzzer_for_pcm16b_decoder_and_fixing_a_fuzzer_problem.patch
cherry-pick-a18fddcb53e6.patch

View File

@@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Henrik Lundin <henrik.lundin@webrtc.org>
Date: Tue, 15 Feb 2022 15:13:34 +0000
Subject: Adding fuzzer for PCM16b decoder and fixing a fuzzer problem
Bug: chromium:1280852
Change-Id: I7f6c5de86ceee01156743c0389c59f875e53bb5f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/251580
Reviewed-by: Minyue Li <minyue@webrtc.org>
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36005}
diff --git a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
index 1dd2ff289ee10280963c3db5de58545886c60d49..7761efe8b3b2d1627021e9f19dfb25ca871be049 100644
--- a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
+++ b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
@@ -42,7 +42,12 @@ int AudioDecoderPcm16B::DecodeInternal(const uint8_t* encoded,
int16_t* decoded,
SpeechType* speech_type) {
RTC_DCHECK_EQ(sample_rate_hz_, sample_rate_hz);
- size_t ret = WebRtcPcm16b_Decode(encoded, encoded_len, decoded);
+ // Adjust the encoded length down to ensure the same number of samples in each
+ // channel.
+ const size_t encoded_len_adjusted =
+ PacketDuration(encoded, encoded_len) * 2 *
+ Channels(); // 2 bytes per sample per channel
+ size_t ret = WebRtcPcm16b_Decode(encoded, encoded_len_adjusted, decoded);
*speech_type = ConvertSpeechType(1);
return static_cast<int>(ret);
}
diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn
index 2e94f40fa2f9deefc867428e1a80aaec3a2d822b..e32da276c91ea67e02eeadf826947e2903090c61 100644
--- a/test/fuzzers/BUILD.gn
+++ b/test/fuzzers/BUILD.gn
@@ -308,6 +308,14 @@ webrtc_fuzzer_test("audio_decoder_multiopus_fuzzer") {
]
}
+webrtc_fuzzer_test("audio_decoder_pcm16b_fuzzer") {
+ sources = [ "audio_decoder_pcm16b_fuzzer.cc" ]
+ deps = [
+ ":audio_decoder_fuzzer",
+ "../../modules/audio_coding:pcm16b",
+ ]
+}
+
rtc_library("audio_encoder_fuzzer") {
testonly = true
sources = [
diff --git a/test/fuzzers/audio_decoder_pcm16b_fuzzer.cc b/test/fuzzers/audio_decoder_pcm16b_fuzzer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6e5d6e2190638185578ac71b400913f46f6b67cf
--- /dev/null
+++ b/test/fuzzers/audio_decoder_pcm16b_fuzzer.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022 The WebRTC 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 in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <memory>
+
+#include "modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h"
+#include "test/fuzzers/audio_decoder_fuzzer.h"
+
+namespace webrtc {
+void FuzzOneInput(const uint8_t* data, size_t size) {
+ if (size > 10000 || size < 2) {
+ return;
+ }
+
+ int sample_rate_hz;
+ switch (data[0] % 4) {
+ case 0:
+ sample_rate_hz = 8000;
+ break;
+ case 1:
+ sample_rate_hz = 16000;
+ break;
+ case 2:
+ sample_rate_hz = 32000;
+ break;
+ case 3:
+ sample_rate_hz = 48000;
+ break;
+ default:
+ RTC_DCHECK_NOTREACHED();
+ return;
+ }
+ const size_t num_channels = data[1] % 16 + 1;
+
+ // Two first bytes of the data are used. Move forward.
+ data += 2;
+ size -= 2;
+
+ AudioDecoderPcm16B dec(sample_rate_hz, num_channels);
+ // Allocate a maximum output size of 100 ms.
+ const size_t allocated_ouput_size_samples =
+ sample_rate_hz * num_channels / 10;
+ std::unique_ptr<int16_t[]> output =
+ std::make_unique<int16_t[]>(allocated_ouput_size_samples);
+ FuzzAudioDecoder(
+ DecoderFunctionType::kNormalDecode, data, size, &dec, sample_rate_hz,
+ allocated_ouput_size_samples * sizeof(int16_t), output.get());
+}
+} // namespace webrtc

View File

@@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tony Herre <herre@google.com>
Date: Fri, 25 Mar 2022 09:33:14 +0100
Subject: Filter out Mac StatusIndicator window from desktop capture list
Since 12.2, the orange/red indicator at the top right of the screen shows up as a window in the Chrome getDisplayMedia() picker, as it's not filtered out by the existing filters. Screenshots in the bug.
Bug: chromium:1297731, b/218211225
Change-Id: I0f87e8d2af42a5a2e3d84f69fe73596e9cf35622
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/251841
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Commit-Queue: Tony Herre <herre@google.com>
Cr-Commit-Position: refs/heads/main@{#36350}
diff --git a/modules/desktop_capture/mac/window_list_utils.cc b/modules/desktop_capture/mac/window_list_utils.cc
index d2fb20ed4ca0689fd6f51ee994308e876680ab1e..5d881662ea2f2d86d2c33bf20f79d31ef4e7a481 100644
--- a/modules/desktop_capture/mac/window_list_utils.cc
+++ b/modules/desktop_capture/mac/window_list_utils.cc
@@ -31,6 +31,11 @@ namespace webrtc {
namespace {
+// WindowName of the status indicator dot shown since Monterey in the taskbar.
+// Testing on 12.2.1 shows this is independent of system language setting.
+const CFStringRef kStatusIndicator = CFSTR("StatusIndicator");
+const CFStringRef kStatusIndicatorOwnerName = CFSTR("Window Server");
+
bool ToUtf8(const CFStringRef str16, std::string* str8) {
size_t maxlen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str16),
kCFStringEncodingUTF8) +
@@ -145,6 +150,17 @@ bool GetWindowList(rtc::FunctionView<bool(CFDictionaryRef)> on_window,
continue;
}
+ CFStringRef window_owner_name = reinterpret_cast<CFStringRef>(
+ CFDictionaryGetValue(window, kCGWindowOwnerName));
+ // Ignore the red dot status indicator shown in the stats bar. Unlike the
+ // rest of the system UI it has a window_layer of 0, so was otherwise
+ // included. See crbug.com/1297731.
+ if (window_title && CFEqual(window_title, kStatusIndicator) &&
+ window_owner_name &&
+ CFEqual(window_owner_name, kStatusIndicatorOwnerName)) {
+ continue;
+ }
+
if (!on_window(window)) {
break;
}

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import argparse
import os

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import argparse
import json

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os
@@ -41,7 +41,7 @@ def getBrokenLinks(filepath):
brokenLinks = []
try:
f = open(filepath, 'r')
f = open(filepath, 'r', encoding="utf-8")
lines = f.readlines()
except KeyboardInterrupt:
print('Keyboard interruption while parsing. Please try again.')
@@ -77,7 +77,7 @@ def getBrokenLinks(filepath):
tempFile = os.path.join(currentDir, sections[0])
if os.path.isfile(tempFile):
try:
newFile = open(tempFile, 'r')
newFile = open(tempFile, 'r', encoding="utf-8")
newLines = newFile.readlines()
except KeyboardInterrupt:
print('Keyboard interruption while parsing. Please try again.')

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import argparse
import os

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import os
import subprocess

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import argparse
import json

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import ast

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import zipfile
import sys

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import argparse
import sys

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import argparse
import sys

43
script/lib/azput.js Normal file
View File

@@ -0,0 +1,43 @@
/* eslint-disable camelcase */
const { BlobServiceClient } = require('@azure/storage-blob');
const fs = require('fs');
const path = require('path');
const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.ELECTRON_ARTIFACTS_BLOB_STORAGE);
const args = require('minimist')(process.argv.slice(2));
let { prefix = '/', key_prefix = '', _: files } = args;
if (prefix && !prefix.endsWith(path.sep)) prefix = path.resolve(prefix) + path.sep;
function filenameToKey (file) {
file = path.resolve(file);
if (file.startsWith(prefix)) file = file.substr(prefix.length - 1);
return key_prefix + (path.sep === '\\' ? file.replace(/\\/g, '/') : file);
}
let anErrorOccurred = false;
function next (done) {
const file = files.shift();
if (!file) return done();
const key = filenameToKey(file);
const [containerName, ...keyPath] = key.split('/');
const blobKey = keyPath.join('/');
console.log(`Uploading '${file}' to container '${containerName}' with key '${blobKey}'...`);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blockBlobClient = containerClient.getBlockBlobClient(blobKey);
blockBlobClient.uploadFile(file)
.then((uploadBlobResponse) => {
console.log(`Upload block blob ${blobKey} successfully: https://artifacts.electronjs.org/${key}`, uploadBlobResponse.requestId);
})
.catch((err) => {
console.error(err);
anErrorOccurred = true;
})
.then(() => next(done));
}
next(() => {
process.exit(anErrorOccurred ? 1 : 0);
});

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
import os
@@ -53,17 +53,6 @@ def get_env_var(name):
return value
def s3_config():
config = (get_env_var('S3_BUCKET'),
get_env_var('S3_ACCESS_KEY'),
get_env_var('S3_SECRET_KEY'))
message = ('Error: Please set the $ELECTRON_S3_BUCKET, '
'$ELECTRON_S3_ACCESS_KEY, and '
'$ELECTRON_S3_SECRET_KEY environment variables')
assert all(len(c) for c in config), message
return config
def enable_verbose_mode():
print('Running in verbose mode')
global verbose_mode

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""Git helper functions.

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import codecs
import os

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