Compare commits

..

153 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
0b804177fa Bump v15.5.7 2022-05-24 07:51:39 -07:00
trop[bot]
77478353c6 fix: crash on navigator.serial.getPorts() (#34333)
(cherry picked from commit 7f9431764f)
(cherry picked from commit 1b5738e308)

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-24 10:46:50 -04:00
Sudowoodo Release Bot
30e8011b9f Bump v15.5.6 2022-05-23 08:04:01 -07:00
Keeley Hammond
54432ab8b2 build: fix index upload error on 15-x-y (#34314) 2022-05-23 14:04:05 +02:00
trop[bot]
37558a6215 revert: some frameless windows showing a frame on Windows (#33608)
Revert "fix: some frameless windows showing a frame on Windows (#32692)"

This reverts commit 7c701367c0.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2022-05-19 10:15:03 +02:00
Darshan Sen
d5ba5c8e0a fix: crash in safeStorage on Linux (#34263) 2022-05-19 10:04:19 +02:00
Sudowoodo Release Bot
b1b83f79b7 Revert "Bump v15.5.6"
This reverts commit ade9151181.
2022-05-18 11:38:29 -07:00
trop[bot]
a85b38847e fix: building with printing disabled (#34273)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-18 09:42:13 -07:00
Sudowoodo Release Bot
ade9151181 Bump v15.5.6 2022-05-18 08:32:28 -07:00
Pedro Pontes
9d2961868c chore: cherry-pick 99c3f3bfd507 from chromium (#34227)
* chore: cherry-pick 99c3f3bfd507 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:15:47 -04:00
Pedro Pontes
cdd6fc93b2 chore: cherry-pick d49484c21e3c from angle (#34014)
Co-authored-by: Electron Bot <electron@github.com>
2022-05-17 13:30:48 -04:00
Pedro Pontes
1e21b7c910 chore: cherry-pick 14e51893e5 from icu (#34224)
* chore: cherry-pick 14e51893e5 from icu

* chore: fixup patch for lint

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-17 11:26:59 -04:00
trop[bot]
c224431ae8 docs: add missing explanation for [angle|dawn]_enable_vulkan_validation_layers = false (#34255)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-17 11:24:32 -04:00
Pedro Pontes
9e0fda8393 chore: cherry-pick ec0cce63f47d from chromium (#34234)
* chore: cherry-pick ec0cce63f47d from chromium

* chore: update patches

* Trigger Build

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-16 18:12:09 -04:00
Pedro Pontes
36b72ba5ee chore: cherry-pick a4f71e40e5 from angle (#34231) 2022-05-16 14:58:12 -04:00
Darshan Sen
dd8c63e15a docs: note safeStorage.isEncryptionAvailable() needs ready event (#34220)
docs: note safeStorage.isEncryptionAvailable() needs ready event (#33724)

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-05-16 12:12:14 -04:00
Pedro Pontes
6bfa54fcf2 chore: cherry-pick a602a068e022 from angle (#34201)
* chore: cherry-pick a602a068e022 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-12 20:19:44 -04:00
Samuel Attard
6d9f3a4945 fix: ensure ElectronBrowser mojo service is only bound to appropriate render frames (#34191)
fix: ensure ElectronBrowser mojo service is only bound to appropriate render frames (#33367)

* Make ElectronBrowser mojo interface frame associated. (#32815)

Co-authored-by: Marek Haranczyk <marek@openfin.co>

* fix: ensure ElectronBrowser mojo service is only bound to appropriate render frames (#33323) (#33350)

* fix: ensure ElectronBrowser mojo service is only bound to authorized render frames

Notes: no-notes

* refactor: extract electron API IPC to its own mojo interface

* fix: just check main frame not primary main frame

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Marek Haranczyk <marek@openfin.co>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Marek Haranczyk <marek@openfin.co>
2022-05-12 15:26:59 -07:00
Samuel Attard
a20396588a build: improve CI speeds and reduce CI costs (#34184)
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>

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-11 12:38:19 -07:00
Sudowoodo Release Bot
f988853128 Bump v15.5.5 2022-05-11 08:31:43 -07:00
trop[bot]
8bc25e8a9d build: change upload-to-s3 vars to upload-to-storage (#34142)
* 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:02:03 -04:00
trop[bot]
a8f8b507aa build: use azure function to hash assets instead of lambda (#34119)
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-05-08 09:30:23 -07:00
trop[bot]
eb320cbbf9 build: stop uploading assets to S3 (#34112)
* 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-07 14:48:27 -07:00
Pedro Pontes
37eab5c66e chore: cherry-pick 5be8e065f43e from chromium (#34040)
* 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-05 09:58:08 -04:00
Pedro Pontes
fc912026e2 chore: cherry-pick 5361d836ae from chromium (#34009) 2022-05-04 16:53:02 -07:00
Pedro Pontes
6aa0609a97 chore: cherry-pick 6b66a45021 from chromium (#34075) 2022-05-04 16:30:38 -07:00
trop[bot]
620d615fe0 test: fix nativeModulesEnabled in spec/webview-spec.js (#34063)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-04 11:57:24 -04:00
Sudowoodo Release Bot
ec7baba401 Bump v15.5.4 2022-05-04 08:34:57 -07:00
Pedro Pontes
f8ba4d6012 chore: cherry-pick d27d9d059b51 from angle (#34045)
* chore: cherry-pick d27d9d059b51 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-05-04 16:28:55 +02:00
Pedro Pontes
79af6f3493 chore: cherry-pick 5ff02e4d7368 from chromium (#34019)
* 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>
2022-05-03 23:57:14 -07:00
Pedro Pontes
6a952c4ff1 chore: cherry-pick d24570fb65 from angle (#34037)
* 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:03 -07:00
Pedro Pontes
ce7c83e8d6 chore: cherry-pick 12ba78f3fa7a from chromium (#34051)
* chore: cherry-pick 12ba78f3fa7a from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-03 16:15:53 -07:00
Pedro Pontes
a686f7e102 chore: cherry-pick 1665a1d16d46 from chromium (#33682)
* chore: cherry-pick 1665a1d16d46 from chromium

* chore: update patches

* Trigger Build

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-03 16:40:38 +09:00
trop[bot]
fa07b74836 build: allow script/spec-runner.js with empty list of runners (#33999)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-02 11:09:21 -04:00
trop[bot]
587353dbc9 spec: allow connections to port 2049 (#33989)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-02 14:47:39 +09:00
Samuel Attard
21b8b3064d build: use dev-cdn instead of sysroots s3 bucket (#33987)
* 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:34 +09:00
Sudowoodo Release Bot
0f05991c3e Bump v15.5.3 2022-04-29 15:16:22 -07:00
Keeley Hammond
6bdab4a353 build: revert migrate urllib to python3 (#33980)
This reverts commit a29136950e.
2022-04-29 15:04:24 -07:00
Sudowoodo Release Bot
6e5f02426a Revert "Bump v15.5.3"
This reverts commit 30da5dee2a.
2022-04-29 12:33:33 -07:00
Sudowoodo Release Bot
30da5dee2a Bump v15.5.3 2022-04-29 09:14:26 -07:00
Pedro Pontes
bd9c7c41ba chore: cherry-pick 2004594a46c8 from v8 (#33884)
* chore: cherry-pick 2004594a46c8 from v8

* chore: update patches

* Trigger Build

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-04-29 01:51:41 -07:00
Pedro Pontes
76f4ced8d4 chore: cherry-pick 4d26949260aa from chromium (#33676)
* chore: cherry-pick 4d26949260aa 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-28 20:36:58 -04:00
Pedro Pontes
cac38cb6ea chore: cherry-pick 4deb522c22 and d88e959e01 from chromium (#33852)
* 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

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-28 20:27:49 -04:00
trop[bot]
e8f89da1c4 build: ensure sync-done file exists during git cache save (#33954)
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-04-27 18:27:13 -07:00
Samuel Attard
a0f73938cd build: upload to AZ as well as S3 (#33927)
* build: upload to AZ as well as S3

* build: actually verify az urls too
2022-04-27 10:44:28 -07:00
Samuel Attard
1bf71fa81f build: improve circleci config (#33945)
* 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:01 -07:00
Sudowoodo Release Bot
0de8079b33 Revert "Bump v15.5.3"
This reverts commit 52fd3da443.
2022-04-27 09:34:00 -07:00
Sudowoodo Release Bot
52fd3da443 Bump v15.5.3 2022-04-27 08:32:55 -07:00
Pedro Pontes
742aab764e chore: cherry-pick 1a31e2110440 from chromium (#33856)
* 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:28 +09:00
trop[bot]
1f669c3cc5 chore: use semantic-commit-action (#33863)
* 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-21 14:55:29 -07:00
Pedro Pontes
d26d064082 chore: cherry-pick e42dbcdedb7a from v8 (#33831)
* 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-21 17:24:26 +09:00
Pedro Pontes
a31e722d43 chore: cherry-pick 5cb934a23d from chromium (#33860) 2022-04-21 15:09:55 +09:00
Sudowoodo Release Bot
81b923c8f5 Revert "Bump v15.5.3"
This reverts commit 91cf2e2163.
2022-04-20 16:24:29 -07:00
Pedro Pontes
b745364907 chore: cherry-pick b2d3ef69ef99 from v8 (#33836) 2022-04-20 13:51:53 -07:00
Sudowoodo Release Bot
91cf2e2163 Bump v15.5.3 2022-04-20 08:32:27 -07:00
Pedro Pontes
53af38ad54 chore: cherry-pick 652dd12a85 from chromium (#33670)
Co-authored-by: Electron Bot <electron@github.com>
2022-04-18 12:37:00 +09:00
trop[bot]
2fef020e06 chore: interpret bytes to string (#33772)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-04-14 06:28:46 -07:00
Pedro Pontes
b60dfe4117 chore: cherry-pick a1dc371d66 from chromium (#33679) 2022-04-14 12:35:40 +02:00
Pedro Pontes
7e123ac6e5 chore: cherry-pick f546ac11eec7 from v8 (#33763)
* chore: cherry-pick f546ac11eec7 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-14 19:17:23 +09:00
trop[bot]
a29136950e build: migrate urllib to python3 (#33741)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-04-13 10:55:10 -07:00
Jeremy Rose
458a843174 chore: cherry-pick a48de319c521 from pdfium (#33715)
* chore: cherry-pick a48de319c521 from pdfium

* Update config.json

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-12 12:00:25 +02:00
Pedro Pontes
e11e12d5b3 chore: cherry-pick ac341df436 from webrtc (#33673) 2022-04-12 11:04:40 +02:00
trop[bot]
25ed65150d fix: report more detailed errors in shell.openExternal() on Windows (#33656)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-04-11 08:52:27 -07:00
Jeremy Rose
8737aa046d fix: prevent UAF crash in setCertificateVerifyProc (#33256) 2022-04-06 12:37:25 -07:00
Sudowoodo Release Bot
0d94bdda50 Bump v15.5.2 2022-04-06 08:31:42 -07:00
Jeremy Rose
2c3081afb8 chore: cherry-pick f599381978f2 from v8 (#33606) 2022-04-05 09:42:19 -07:00
John Kleinschmidt
f583acff46 test: disable newly added/failing test on Windows (#33615) 2022-04-05 12:23:31 -04:00
Milan Burda
271e98c059 fix: building with printing disabled (#33603) 2022-04-04 16:40:01 -07:00
trop[bot]
8279c02e9a fix: gn check when //printing component is disabled (#33601)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-04-04 16:39:40 -07:00
David Sanders
ef4cbe86af fix: on macOS show BrowserWindow on maximize if not currently shown (#33523) 2022-03-30 19:20:28 -04:00
Jeremy Rose
300a40f939 chore: cherry-pick a1427aad7cef from v8 (#33525)
* chore: cherry-pick a1427aad7cef from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-03-30 19:06:49 -04:00
Sudowoodo Release Bot
79b45ac5f6 Bump v15.5.1 2022-03-30 08:32:53 -07:00
trop[bot]
e5e8dd5156 fix: libuv patches to address child_process.spawn slowness (#33406)
* fix: libuv patches to address child_process.spawn slowness

* chore: backport additional patches

* Update .patches

* chore: update patches

* chore: update patches

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-03-29 19:45:46 -04:00
trop[bot]
4e75499270 fix: crash when WindowButtonsProxy references cleared NSWindow (#33487)
* resets WindowButtonsProxy on window delete on macOS

* fixes reset

* chore: empty commit

Co-authored-by: Gellert Hegyi <gellert.hegyi@around.co>
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-03-29 19:43:28 -04:00
Sudowoodo Release Bot
1bc5b6177f Bump v15.5.0 2022-03-28 13:24:07 -07:00
Pedro Pontes
5647382a55 chore: cherry-pick 26b7ad6967b1 from v8 (#33473)
* chore: cherry-pick 26b7ad6967b1 from v8

* chore: update patches

* kick lint

* kick lint

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: Electron Bot <electron@github.com>
2022-03-28 13:12:10 -07:00
Pedro Pontes
fd272d89bc chore: cherry-pick c46fb3a15ec2 from v8 (#33393)
* chore: cherry-pick c46fb3a15ec2 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-03-28 12:45:57 -04:00
Calvin
d745647c54 fix: non-client windows messages on legacy widget host (again) (#33449) 2022-03-28 16:34:53 +09:00
trop[bot]
9038bdd7bc fix: use stricter options in SecStaticCodeCheckValidity (#33376)
* fix: use stricter options in SecStaticCodeCheckValidity

* Update patches/squirrel.mac/fix_use_kseccschecknestedcode_kseccsstrictvalidate_in_the_sec.patch

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* Trigger Build

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-03-25 10:53:56 +01:00
trop[bot]
bbc862c878 test: disable webview.capturePage test (#33433)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-03-24 12:19:24 -04:00
trop[bot]
ff57df1ecb ci: abort CI if goma authentication is invalid (#33417)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-03-24 09:01:35 -04:00
Milan Burda
37dfd8be4a feat: add nativeTheme.inForcedColorsMode (#32956) (#33360) 2022-03-23 16:55:09 -07:00
Sudowoodo Release Bot
f043e665dd Bump v15.4.2 2022-03-23 08:32:18 -07:00
Pedro Pontes
798f151e05 chore: cherry-pick 2b75a29bf2 from angle (#33390)
* chore: cherry-pick 2b75a29bf2 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-03-23 09:48:49 -04:00
Robin Ebert
a9a3910aa0 chore: backport dd4c3ddadbb9 from chromium (#33038)
* chore: backport dd4c3ddadbb9 from chromium

* Fix mapping of keymap fd

* Implement a proper wayland keymap fix that doesn't depend on fd permissions

* Close keymap fd at the end of Keymap-event handler
2022-03-23 18:42:26 +09:00
Pedro Pontes
2f28e10543 chore: cherry-pick ca32852e4f from angle (#33222)
Co-authored-by: Electron Bot <electron@github.com>
2022-03-22 20:11:21 -04:00
trop[bot]
f1021b93d0 fix: non-client mouse events on WCO-enabled windows (#33199)
* fix: non-client mouse events on WCO-enabled windows

* chore: cleanup .patches after merge

Co-authored-by: clavin <clavin@electronjs.org>
Co-authored-by: Calvin <clavin@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-03-22 11:29:04 -04:00
Pedro Pontes
6788561bb3 chore: cherry-pick 161f0866e8 from angle (#33342)
* chore: cherry-pick 161f0866e8 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-03-22 15:08:45 +09:00
Pedro Pontes
35d3f35a44 chore: cherry-pick 905302eb3a2b from chromium (#33237)
* chore: cherry-pick 905302eb3a2b 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-03-22 08:27:15 +09:00
trop[bot]
f949a1aafd chore: cherry-pick 2ed58f4 from chromium (#33109) (#33248)
Refs: https://chromium-review.googlesource.com/c/chromium/src/+/3492658
Fixes: https://github.com/electron/electron/issues/33049
Signed-off-by: Darshan Sen <raisinten@gmail.com>

Co-authored-by: Charles Kerr <charles@charleskerr.com>

Co-authored-by: Darshan Sen <raisinten@gmail.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2022-03-21 11:09:31 +09:00
Pedro Pontes
b8e22532b0 chore: cherry-pick 246c10dede97 from chromium (#33245)
* chore: cherry-pick 246c10dede97 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-03-21 10:26:20 +09:00
trop[bot]
c2758554ed fix: crash when destroying node env with pending promises (#33300)
* fix: crash when destroying node env with pending promises

* chore: add spec

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-03-21 10:20:30 +09:00
trop[bot]
05cb4240bd build: drop pywin32 usage (#33296)
* build: drop pywin32 usage

* chore: ignore extra output on AppVeyor

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2022-03-21 10:16:28 +09:00
trop[bot]
c84b152164 docs: remove "marked" from process.getBlinkMemoryInfo() (#33289)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2022-03-17 14:08:45 +01:00
David Sanders
20f8c10977 fix: ensure external memory adjustments are balanced (#33311) 2022-03-16 22:17:18 -07:00
Pedro Pontes
38be2dfb25 chore: cherry-pick eb967bf211 from chromium (#33242) 2022-03-16 12:34:55 +01:00
Jeremy Rose
0c371e53a4 chore: cherry-pick 62142d222a80 from chromium (#33185)
* chore: cherry-pick 62142d222a80 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-03-09 16:27:32 -05:00
Sudowoodo Release Bot
8e517202ea Bump v15.4.1 2022-03-09 07:31:54 -08:00
Jeremy Rose
3410147699 chore: cherry-pick 1887414c016d from chromium (#33178)
* chore: cherry-pick 1887414c016d 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-03-08 14:36:13 -05:00
Jeremy Rose
ce5157236c chore: cherry-pick 49e8ff16f1fe from angle (#33181)
* chore: cherry-pick 49e8ff16f1fe from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-03-08 10:54:31 -05:00
Jeremy Rose
8ec2469379 chore: cherry-pick 6b2643846ae3 from chromium (#33168)
* chore: cherry-pick 6b2643846ae3 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-03-07 16:52:22 -08:00
trop[bot]
ddf348d609 fix: really strip crashpad handler binary (#33173)
Co-authored-by: Micha Hanselmann <micha.hanselmann@gmail.com>
2022-03-07 17:05:50 -05:00
trop[bot]
f757a17821 fix: macOS tray icon alternate images (#33104)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-03-02 12:01:13 -08:00
Sudowoodo Release Bot
8519ba881e Bump v15.4.0 2022-02-28 16:11:36 -08:00
Michaela Laurencin
bd31023314 feat: add WCO height option (#33064)
* feat: add WCO height option (#31222)

* feat: add WCO height option

* add docs and mac functionality

* add macOS functionality and height lowerbound

* Update docs/api/browser-window.md

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* update macOS functionality

* add chromium related notes

* add test and fix pixel under button bug and fix typo

* revert changes to docs/api/frameless-window.md

* modify `useCustomHeight` calls

* update `useCustomHeight` and `getCurrentMargin`

* modify margin calculation

* fix minimum custom height on macOS

* Update window_buttons_proxy.mm

* fix specified traffic light positions

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* Update win_caption_button.h

* Update win_caption_button_container.h

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-02-28 11:35:04 -08:00
trop[bot]
fb0eb6c0ca fix: tray garbage collection (#33077)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-02-24 16:34:27 -05:00
Sudowoodo Release Bot
390349e3db Revert "Bump v15.3.8"
This reverts commit f6e6873971.
2022-02-23 15:45:05 -08:00
Sudowoodo Release Bot
f6e6873971 Bump v15.3.8 2022-02-23 11:30:58 -08:00
Robo
ecd6918166 chore: cherry-pick a1c1ec1ea from chromium (#32800)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/3244046

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-02-22 16:33:44 +09:00
Shelley Vohr
d54f1d58f7 fix: savePage throw on relative paths (#33018) 2022-02-22 16:30:46 +09:00
trop[bot]
5d5b2bf8e5 fix: command string for windows protocol handler (#33011)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-02-22 16:26:43 +09:00
Pedro Pontes
fa37e1533f chore: cherry-pick 11505c3867 from chromium (#32912) 2022-02-21 14:07:46 -08:00
Pedro Pontes
f9cf232597 chore: cherry-pick 05e714a87c from chromium (#32908)
Co-authored-by: Electron Bot <electron@github.com>
2022-02-21 10:41:47 -08:00
trop[bot]
615c15c914 chore: add @electron/wg-security to patches/ CODEOWNERS (#33004)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-02-21 11:47:52 +01:00
Pedro Pontes
4550baa7a5 chore: cherry-pick be50c60b4225 from chromium (#32917)
* chore: cherry-pick be50c60b4225 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-02-21 16:46:12 +09:00
Robo
7469c72d80 chore: cherry-pick e8379497e from chromium (#32799)
* chore: cherry-pick e8379497e from chromium

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

* chore: update patches

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-02-21 16:43:59 +09:00
Robo
bedb5e1055 chore: cherry-pick ebddaedee from v8 (#32797)
* chore: cherry-pick ebddaedee from v8

Backports https://chromium-review.googlesource.com/c/v8/v8/+/3218193

* chore: update patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-02-21 16:36:00 +09:00
trop[bot]
6815c823b3 fix: stale renderer process on quit (#32967)
Co-authored-by: Micha Hanselmann <micha.hanselmann@gmail.com>
2022-02-21 10:26:22 +09:00
Cheng Zhao
78c5a2cf4b chore: cherry-pick fix for 1277917 from chromium (#32786)
Co-authored-by: Electron Bot <electron@github.com>
2022-02-18 11:11:54 +09:00
Pedro Pontes
3c3d279182 chore: cherry-pick ebc188ad769e from chromium (#32914)
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-02-17 13:19:27 -08:00
Pedro Pontes
1c7a612931 chore: cherry-pick e3805f29fed7 from chromium (#32901)
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-02-17 10:03:12 -08:00
Cheng Zhao
4615dcbbfd chore: cherry-pick fix for 1281979 from chromium (#32785)
Co-authored-by: Electron Bot <electron@github.com>
2022-02-17 21:07:15 +09:00
Pedro Pontes
3bbe839403 chore: cherry-pick b790affce3 and 9c1efd3def from angle (#32904) 2022-02-17 21:06:21 +09:00
Pedro Pontes
0f5967fce2 chore: cherry-pick 0081bb347e67 from chromium (#32919)
* chore: cherry-pick 0081bb347e67 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-02-17 15:00:09 +09:00
Robo
da171befe7 chore: cherry-pick 1c93e2afc8 from v8 (#32796)
Backports https://chromium-review.googlesource.com/c/v8/v8/+/3338698

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-02-17 14:53:48 +09:00
Cheng Zhao
c850e2452c chore: cherry-pick fix for 1282354 from chromium (#32783)
Co-authored-by: Electron Bot <electron@github.com>
2022-02-17 14:53:12 +09:00
Cheng Zhao
f3ca6ff998 chore: cherry-pick fix for 1283198 from chromium (#32781)
* chore: cherry-pick fix for 1283198 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-02-16 17:05:14 +09:00
Sudowoodo Release Bot
58e9dedd76 Bump v15.3.7 2022-02-14 11:23:11 -08:00
Cheng Zhao
51a673e7e0 chore: cherry-pick fix for 1283375 from chromium (#32777)
Co-authored-by: Electron Bot <electron@github.com>
2022-02-14 20:04:39 +09:00
Milan Burda
fed01fb57d fix: will-attach-webview handler modifying params.instanceId does not break <webview> (#32386) (#32855) 2022-02-13 22:33:31 -08:00
Micha Hanselmann
65c9f47e15 chore: cherry-pick c1700c5 from v8 (#32770)
* chore: cherry-pick c1700c5 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-02-10 11:27:01 -05:00
Cheng Zhao
1b54c4bc44 chore: cherry-pick fix for 1283371 from chromium (#32779)
Co-authored-by: Electron Bot <electron@github.com>
2022-02-10 10:03:37 -06:00
Robo
f903141394 chore: cherry-pick 06504ff3b1 from chromium (#32793)
* chore: cherry-pick 06504ff3b1 from chromium

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

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-02-10 22:16:55 +09:00
Robo
6c1f9f8270 chore: cherry-pick 5c41beab6 from chromium (#32798)
* chore: cherry-pick 5c41beab6 from chromium

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

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-02-10 19:36:18 +09:00
Robo
7432ea43b7 chore: cherry-pick 91fbf1798 and cff03c22c5 from chromium (#32792)
Backports
https://chromium-review.googlesource.com/c/chromium/src/+/3347570
https://chromium-review.googlesource.com/c/chromium/src/+/3348406

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-02-10 17:22:19 +09:00
Robo
0d1b7be451 chore: cherry-pick efdfe711dc5 from chromium (#32791)
Backports
https://chromium-review.googlesource.com/c/chromium/src/+/3242785
https://chromium-review.googlesource.com/c/angle/angle/+/3242963

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-02-10 15:13:26 +09:00
Robo
e0a7f869de chore: cherry-pick 349a35b19 from chromium (#32790)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/3226142

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-02-10 09:37:43 +09:00
Jeremy Rose
d9dd6138e2 chore: cherry-pick 9db9911e1242 from chromium (#32741)
* chore: cherry-pick 9db9911e1242 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-02-09 16:49:44 -05:00
trop[bot]
c1651e333b test: disable the test that makes spec runner hang on exit (#32836)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-02-09 12:11:16 -05:00
trop[bot]
c0ea40e71d build: rebuild the dist_zips when the deps get modified (#32819)
* build: rebuild the dist_zips when the deps get modified

The dist.zip generated by the electron_dist_zip action was not getting
updated when changes were being made to the dependencies, like the
source files. It turns out, we were using data_deps for the dependencies
instead of deps. Here is the difference:

data_deps: things needed to ultimately run the thing built by a target
deps: things needed to build the target

So the difference in treatment of both sets of dependencies is actually
intentional.

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

* fixup! build: rebuild the dist_zips when the deps get modified

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

Co-authored-by: Darshan Sen <raisinten@gmail.com>
2022-02-09 11:13:28 -05:00
Robo
501bb98a10 chore: cherry-pick 5f8ddef5a6 from chromium (#32789)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/3193885

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-02-09 13:04:10 +09:00
Robo
9fe9a0ccc1 chore: cherry-pick ce8b70863 from angle (#32795)
Backports https://chromium-review.googlesource.com/c/angle/angle/+/3335173
2022-02-09 09:41:57 +09:00
Robo
f6d2b9dc63 chore: cherry-pick 55f6cb37 from chromium (#32794)
* chore: cherry-pick 55f6cb37 from chromium

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

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-02-09 09:41:24 +09:00
Jeremy Rose
b04be1dff6 chore: cherry-pick 27bc67f761e6 from v8 (#32739)
* chore: cherry-pick 27bc67f761e6 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-02-09 09:40:26 +09:00
Cheng Zhao
656463c2f4 chore: cherry-pick fix for 1284367 from chromium (#32775) 2022-02-08 11:32:00 -05:00
trop[bot]
a0e9cc6c02 fix: WCO window hover on window controls on Windows (#32717) 2022-02-03 10:06:48 +01:00
trop[bot]
27e2c79dd0 docs: fix missing tag end in clipboard example (#32693)
Co-authored-by: Paul Hollinsky <paulhollinsky@gmail.com>
2022-02-02 10:13:58 -05:00
trop[bot]
d74441f00e docs: fix typo in BrowserWindow description (#32697)
Co-authored-by: Tobias Nießen <tniessen@tnie.de>
2022-02-02 10:09:58 -05:00
trop[bot]
97e52764a8 fix: some frameless windows showing a frame on Windows (#32708)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-02-02 15:38:37 +01:00
trop[bot]
112392c414 fix: expose all serial devices to setDevicePermissionHandler (#32686)
* fix: expose all serial devices to setDevicePermissionHandler

* Trigger Build

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-02-01 19:28:20 -05:00
trop[bot]
42c2eecdef fix: transparent window max/unmax event firing (#32688)
* fix: transparent window max/unmax event firing

* chore: fixup tests

* Update spec-main/api-browser-window-spec.ts

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

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2022-02-01 20:21:42 +09:00
trop[bot]
98603c645e fix: missing comma in config.py (#32676)
* Fix missing comma

Co-authored-by: Marek Šuppa <mrshu@users.noreply.github.com>
2022-02-01 17:52:59 +09:00
trop[bot]
11391e7351 docs: update context bridge docs about Promises and Errors (#32533) (#32646)
* Update context bridge docs about Promises

From my testing it doesn't remove Promises in nested objects,
also according to the test suite it does not:
80577a4f08/spec-main/api-context-bridge-spec.ts (L693)

* docs: Update docs for errors too

Co-authored-by: Mikael Finstad <finstaden@gmail.com>
2022-01-28 19:59:28 +09:00
203 changed files with 15882 additions and 935 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

View File

@@ -5,7 +5,7 @@ parameters:
type: boolean
default: false
upload-to-s3:
upload-to-storage:
type: string
default: '1'
@@ -322,10 +322,27 @@ step-setup-goma-for-build: &step-setup-goma-for-build
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
third_party/goma/goma_ctl.py ensure_start
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
echo "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token."
exit 1
fi
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
cd ..
touch "${TMPDIR:=/tmp}"/.goma-ready
background: true
step-wait-for-goma: &step-wait-for-goma
run:
name: Wait for Goma
command: |
until [ -f "${TMPDIR:=/tmp}"/.goma-ready ]
do
sleep 5
done
echo "Goma ready"
no_output_timeout: 2m
step-restore-brew-cache: &step-restore-brew-cache
restore_cache:
@@ -539,14 +556,6 @@ step-electron-build: &step-electron-build
cp out/Default/.ninja_log out/electron_ninja_log
node electron/script/check-symlinks.js
step-native-unittests-build: &step-native-unittests-build
run:
name: Build native test targets
no_output_timeout: 30m
command: |
cd src
ninja -C out/Default shell_browser_ui_unittests -j $NUMBER_OF_NINJA_PROCESSES
step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
run:
name: Strip electron binaries
@@ -565,40 +574,6 @@ step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
electron/script/add-debug-link.py --target-cpu="$target_cpu" --debug-dir=out/Default/debug
fi
step-electron-dist-build: &step-electron-dist-build
run:
name: Build dist.zip
command: |
cd src
if [ "$SKIP_DIST_ZIP" != "1" ]; then
ninja -C out/Default electron:electron_dist_zip
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
if [ "`uname`" == "Darwin" ]; then
target_os=mac
target_cpu=x64
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
if [ "$TARGET_ARCH" == "arm64" ]; then
target_cpu=arm64
fi
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
else
echo "Unknown system: `uname`"
exit 1
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
fi
fi
step-electron-chromedriver-build: &step-electron-chromedriver-build
run:
name: Build chromedriver.zip
@@ -635,9 +610,9 @@ step-electron-publish: &step-electron-publish
fi
cd src/electron
if [ "$UPLOAD_TO_S3" == "1" ]; then
echo 'Uploading Electron release distribution to S3'
script/release/uploaders/upload.py --verbose --upload_to_s3
if [ "$UPLOAD_TO_STORAGE" == "1" ]; then
echo 'Uploading Electron release distribution to Azure'
script/release/uploaders/upload.py --verbose --UPLOAD_TO_STORAGE
else
echo 'Uploading Electron release distribution to Github releases'
script/release/uploaders/upload.py --verbose
@@ -651,7 +626,6 @@ step-persist-data-for-tests: &step-persist-data-for-tests
- src/out/Default/dist.zip
- src/out/Default/mksnapshot.zip
- src/out/Default/chromedriver.zip
- src/out/Default/shell_browser_ui_unittests
- src/out/Default/gen/node_headers
- src/out/ffmpeg/ffmpeg.zip
- src/electron
@@ -762,6 +736,7 @@ step-show-goma-stats: &step-show-goma-stats
$LOCAL_GOMA_DIR/diagnose_goma_log.py
true
when: always
background: true
step-mksnapshot-build: &step-mksnapshot-build
run:
@@ -886,12 +861,12 @@ step-touch-sync-done: &step-touch-sync-done
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
restore_cache:
keys:
- v8-src-cache-{{ checksum "src/electron/.depshash" }}
- v14-src-cache-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
restore_cache:
keys:
- v1-src-cache-marker-{{ checksum "src/electron/.depshash" }}
- v14-src-cache-marker-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache marker
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
@@ -900,10 +875,10 @@ step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
step-maybe-restore-git-cache: &step-maybe-restore-git-cache
restore_cache:
paths:
- ~/.gclient-cache
- git-cache
keys:
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}
name: Conditionally restoring git cache
step-restore-out-cache: &step-restore-out-cache
@@ -920,15 +895,15 @@ step-set-git-cache-path: &step-set-git-cache-path
command: |
# CircleCI does not support interpolation when setting environment variables.
# https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-shell-command
echo 'export GIT_CACHE_PATH="$HOME/.gclient-cache"' >> $BASH_ENV
echo 'export GIT_CACHE_PATH="$PWD/git-cache"' >> $BASH_ENV
# Persist the git cache based on the hash of DEPS and .circle-sync-done
# If the src cache was restored above then this will persist an empty cache
step-save-git-cache: &step-save-git-cache
save_cache:
paths:
- ~/.gclient-cache
key: v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- git-cache
key: v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
name: Persisting git cache
step-save-out-cache: &step-save-out-cache
@@ -973,7 +948,7 @@ step-save-src-cache: &step-save-src-cache
save_cache:
paths:
- /var/portal
key: v8-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v14-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
name: Persisting src cache
step-make-src-cache-marker: &step-make-src-cache-marker
run:
@@ -983,7 +958,7 @@ step-save-src-cache-marker: &step-save-src-cache-marker
save_cache:
paths:
- .src-cache-marker
key: v1-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v14-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
run:
@@ -1004,11 +979,15 @@ step-ts-compile: &step-ts-compile
# List of all steps.
steps-electron-gn-check: &steps-electron-gn-check
steps:
- attach_workspace:
at: .
- *step-checkout-electron
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-generate-deps-hash
- *step-touch-sync-done
- maybe-restore-portaled-src-cache
- *step-wait-for-goma
- *step-gn-gen-default
- *step-gn-check
@@ -1021,6 +1000,7 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- *step-get-more-space-on-mac
- *step-setup-goma-for-build
- *step-generate-deps-hash
- *step-touch-sync-done
- maybe-restore-portaled-src-cache
@@ -1040,7 +1020,7 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-get-more-space-on-mac
- *step-install-npm-deps-on-mac
- *step-fix-sync-on-mac
@@ -1056,6 +1036,7 @@ steps-native-tests: &steps-native-tests
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- run:
@@ -1241,7 +1222,6 @@ commands:
fi
}
mv_if_exist src/out/Default/dist.zip
mv_if_exist src/out/Default/shell_browser_ui_unittests
mv_if_exist src/out/Default/gen/node_headers.tar.gz
mv_if_exist src/out/Default/symbols.zip
mv_if_exist src/out/Default/mksnapshot.zip
@@ -1278,6 +1258,46 @@ commands:
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
step-electron-dist-build:
parameters:
additional-targets:
type: string
default: ''
steps:
- run:
name: Build dist.zip
command: |
cd src
if [ "$SKIP_DIST_ZIP" != "1" ]; then
ninja -C out/Default electron:electron_dist_zip << parameters.additional-targets >>
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
if [ "`uname`" == "Darwin" ]; then
target_os=mac
target_cpu=x64
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
if [ "$TARGET_ARCH" == "arm64" ]; then
target_cpu=arm64
fi
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
else
echo "Unknown system: `uname`"
exit 1
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
fi
fi
electron-build:
parameters:
attach:
@@ -1323,6 +1343,10 @@ commands:
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- *step-save-brew-cache
- when:
condition: << parameters.build >>
steps:
- *step-setup-goma-for-build
- when:
condition: << parameters.checkout-and-assume-cache >>
steps:
@@ -1359,6 +1383,40 @@ commands:
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-touch-sync-done
- when:
condition: << parameters.save-git-cache >>
steps:
- *step-save-git-cache
# Mark sync as done _after_ saving the git cache so that it is uploaded
# only when the src cache was not present
# Their are theoretically two cases for this cache key
# 1. `vX-git-cache-DONE-{deps_hash}
# 2. `vX-git-cache-EMPTY-{deps_hash}
#
# Case (1) occurs when the flag file has "DONE" in it
# which only occurs when "step-mark-sync-done" is run
# or when the src cache was restored successfully as that
# flag file contains "DONE" in the src cache.
#
# Case (2) occurs when the flag file is empty, this occurs
# when the src cache was not restored and "step-mark-sync-done"
# has not run yet.
#
# Notably both of these cases also have completely different
# gclient cache states.
# In (1) the git cache is completely empty as we didn't run
# "gclient sync" because the src cache was restored.
# In (2) the git cache is full as we had to run "gclient sync"
#
# This allows us to do make the follow transitive assumption:
# In cases where the src cache is restored, saving the git cache
# will save an empty cache. In cases where the src cache is built
# during this build the git cache will save a full cache.
#
# In order words if there is a src cache for a given DEPS hash
# the git cache restored will be empty. But if the src cache
# is missing we will restore a useful git cache.
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- *step-delete-git-directories
@@ -1388,7 +1446,7 @@ commands:
steps:
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-get-more-space-on-mac
- *step-fix-sync-on-mac
- *step-delete-git-directories
@@ -1401,13 +1459,8 @@ commands:
- *step-gn-gen-default
- *step-electron-build
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
# Native test targets
- *step-native-unittests-build
# Node.js headers
- *step-nodejs-headers-build
- step-electron-dist-build:
additional-targets: shell_browser_ui_unittests third_party/electron_node:headers electron:hunspell_dictionaries_zip
- *step-show-goma-stats
@@ -1425,13 +1478,14 @@ commands:
- *step-ffmpeg-gn-gen
- *step-ffmpeg-build
# hunspell
- *step-hunspell-build
# Save all data needed for a further tests run.
- when:
condition: << parameters.persist >>
steps:
- *step-minimize-workspace-size-from-checkout
- run: |
rm -rf src/third_party/electron_node/deps/openssl
rm -rf src/third_party/electron_node/deps/v8
- *step-persist-data-for-tests
- when:
@@ -1497,6 +1551,7 @@ commands:
- *step-fix-sync-on-mac
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-gn-gen-default
# Electron app
@@ -1504,7 +1559,7 @@ commands:
- *step-show-goma-stats
- *step-maybe-generate-breakpad-symbols
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
- step-electron-dist-build
- *step-maybe-zip-symbols
# mksnapshot
@@ -1547,20 +1602,10 @@ jobs:
<<: *steps-electron-ts-compile-for-doc-change
# Layer 1: Checkout.
linux-checkout-for-workspace:
executor: linux-docker
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
linux-make-src-cache:
executor: linux-docker
executor:
name: linux-docker
size: xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
@@ -1611,22 +1656,10 @@ jobs:
persist-checkout: true
restore-src-cache: false
mac-checkout-for-workspace:
executor: linux-docker
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
mac-make-src-cache:
executor: linux-docker
executor:
name: linux-docker
size: xlarge
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
@@ -1651,7 +1684,8 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-x64-testing-asan:
@@ -1691,6 +1725,7 @@ jobs:
environment:
<<: *env-linux-medium
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
linux-x64-release:
@@ -1711,7 +1746,7 @@ jobs:
environment:
<<: *env-linux-2xlarge-release
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1760,7 +1795,7 @@ jobs:
<<: *env-ia32
<<: *env-release-build
<<: *env-32bit-release
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1787,7 +1822,8 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm-release:
@@ -1812,7 +1848,7 @@ jobs:
<<: *env-release-build
<<: *env-32bit-release
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1839,7 +1875,8 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm64-testing-gn-check:
@@ -1850,6 +1887,7 @@ jobs:
<<: *env-linux-medium
<<: *env-arm64
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
linux-arm64-release:
@@ -1873,7 +1911,7 @@ jobs:
<<: *env-arm64
<<: *env-release-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1909,6 +1947,7 @@ jobs:
environment:
<<: *env-machine-mac
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-electron-gn-check
osx-publish-x64-skip-checkout:
@@ -1916,7 +1955,7 @@ jobs:
environment:
<<: *env-mac-large-release
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1936,7 +1975,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-release-build
<<: *env-apple-silicon
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1991,6 +2030,7 @@ jobs:
<<: *env-machine-mac
<<: *env-mas
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-electron-gn-check
mas-publish-x64-skip-checkout:
@@ -1999,7 +2039,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-mas
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
steps:
- run: echo running
- when:
@@ -2018,7 +2058,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-mas-apple-silicon
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -2317,14 +2357,19 @@ workflows:
- equal: [false, << pipeline.parameters.run-linux-publish >>]
- equal: [true, << pipeline.parameters.run-build-linux >>]
jobs:
- linux-checkout-for-workspace
- linux-make-src-cache
- linux-x64-testing
- linux-x64-testing-asan
- linux-x64-testing-no-run-as-node
- linux-x64-testing:
requires:
- linux-make-src-cache
- linux-x64-testing-asan:
requires:
- linux-make-src-cache
- linux-x64-testing-no-run-as-node:
requires:
- linux-make-src-cache
- linux-x64-testing-gn-check:
requires:
- linux-checkout-for-workspace
- linux-make-src-cache
- linux-x64-testing-tests:
requires:
- linux-x64-testing
@@ -2337,7 +2382,9 @@ workflows:
- linux-x64-testing-node:
requires:
- linux-x64-testing
- linux-ia32-testing
- linux-ia32-testing:
requires:
- linux-make-src-cache
- linux-ia32-testing-tests:
requires:
- linux-ia32-testing
@@ -2347,7 +2394,9 @@ workflows:
- linux-ia32-testing-node:
requires:
- linux-ia32-testing
- linux-arm-testing
- linux-arm-testing:
requires:
- linux-make-src-cache
- linux-arm-testing-tests:
filters:
branches:
@@ -2355,7 +2404,9 @@ workflows:
ignore: /pull\/[0-9]+/
requires:
- linux-arm-testing
- linux-arm64-testing
- linux-arm64-testing:
requires:
- linux-make-src-cache
- linux-arm64-testing-tests:
filters:
branches:
@@ -2365,7 +2416,7 @@ workflows:
- linux-arm64-testing
- linux-arm64-testing-gn-check:
requires:
- linux-checkout-for-workspace
- linux-make-src-cache
build-mac:
when:
@@ -2374,14 +2425,13 @@ workflows:
- equal: [false, << pipeline.parameters.run-linux-publish >>]
- equal: [true, << pipeline.parameters.run-build-mac >>]
jobs:
- mac-checkout-for-workspace
- mac-make-src-cache
- osx-testing-x64:
requires:
- mac-make-src-cache
- osx-testing-x64-gn-check:
requires:
- mac-checkout-for-workspace
- mac-make-src-cache
- osx-testing-x64-tests:
requires:
- osx-testing-x64
@@ -2400,7 +2450,7 @@ workflows:
- mac-make-src-cache
- mas-testing-x64-gn-check:
requires:
- mac-checkout-for-workspace
- mac-make-src-cache
- mas-testing-x64-tests:
requires:
- mas-testing-x64
@@ -2414,3 +2464,6 @@ workflows:
ignore: /pull\/[0-9]+/
requires:
- mas-testing-arm64
lint:
jobs:
- lint

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

2
.github/CODEOWNERS vendored
View File

@@ -4,7 +4,7 @@
# https://git-scm.com/docs/gitignore
# Upgrades WG
/patches/ @electron/wg-upgrades
/patches/ @electron/wg-upgrades @electron/wg-security
DEPS @electron/wg-upgrades
# Releases WG

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

@@ -1231,6 +1231,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" ]
}
}
}
@@ -1367,11 +1371,13 @@ dist_zip("electron_dist_zip") {
if (is_linux) {
data_deps += [ "//sandbox/linux:chrome_sandbox" ]
}
deps = data_deps
outputs = [ "$root_build_dir/dist.zip" ]
}
dist_zip("electron_ffmpeg_zip") {
data_deps = [ "//third_party/ffmpeg" ]
deps = data_deps
outputs = [ "$root_build_dir/ffmpeg.zip" ]
}
@@ -1389,6 +1395,7 @@ group("electron_chromedriver") {
dist_zip("electron_chromedriver_zip") {
testonly = true
data_deps = electron_chromedriver_deps
deps = data_deps
outputs = [ "$root_build_dir/chromedriver.zip" ]
}
@@ -1407,6 +1414,7 @@ group("electron_mksnapshot") {
dist_zip("electron_mksnapshot_zip") {
data_deps = mksnapshot_deps
deps = data_deps
outputs = [ "$root_build_dir/mksnapshot.zip" ]
}
@@ -1417,6 +1425,7 @@ copy("hunspell_dictionaries") {
dist_zip("hunspell_dictionaries_zip") {
data_deps = [ ":hunspell_dictionaries" ]
deps = data_deps
flatten = true
outputs = [ "$root_build_dir/hunspell_dictionaries.zip" ]
@@ -1430,6 +1439,7 @@ copy("libcxx_headers") {
dist_zip("libcxx_headers_zip") {
data_deps = [ ":libcxx_headers" ]
deps = data_deps
flatten = true
flatten_relative_to = rebase_path(
"$target_gen_dir/electron_libcxx_include/buildtools/third_party/libc++/trunk",
@@ -1445,6 +1455,7 @@ copy("libcxxabi_headers") {
dist_zip("libcxxabi_headers_zip") {
data_deps = [ ":libcxxabi_headers" ]
deps = data_deps
flatten = true
flatten_relative_to = rebase_path(
"$target_gen_dir/electron_libcxxabi_include/buildtools/third_party/libc++abi/trunk",

View File

@@ -1 +1 @@
15.3.6
15.5.7

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.)
#
@@ -66,6 +66,31 @@ build_script:
- mkdir src
- update_depot_tools.bat
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
$host.SetShouldExit(1)
}
}
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
@@ -129,21 +154,6 @@ build_script:
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
}
}
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
@@ -221,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

@@ -16,6 +16,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,9 +1,12 @@
from __future__ import with_statement
from __future__ import unicode_literals
import contextlib
import sys
import os
import optparse
import json
import re
import subprocess
sys.path.append("%s/../../build" % os.path.dirname(os.path.realpath(__file__)))
@@ -33,36 +36,56 @@ def calculate_hash(root):
return CalculateHash('.', None)
def windows_installed_software():
import win32com.client
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer, "root\cimv2")
colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
items = []
powershell_command = [
"Get-CimInstance",
"-Namespace",
"root\cimv2",
"-Class",
"Win32_product",
"|",
"Select",
"vendor,",
"description,",
"@{l='install_location';e='InstallLocation'},",
"@{l='install_date';e='InstallDate'},",
"@{l='install_date_2';e='InstallDate2'},",
"caption,",
"version,",
"name,",
"@{l='sku_number';e='SKUNumber'}",
"|",
"ConvertTo-Json",
]
for objItem in colItems:
item = {}
if objItem.Caption:
item['caption'] = objItem.Caption
if objItem.Caption:
item['description'] = objItem.Description
if objItem.InstallDate:
item['install_date'] = objItem.InstallDate
if objItem.InstallDate2:
item['install_date_2'] = objItem.InstallDate2
if objItem.InstallLocation:
item['install_location'] = objItem.InstallLocation
if objItem.Name:
item['name'] = objItem.Name
if objItem.SKUNumber:
item['sku_number'] = objItem.SKUNumber
if objItem.Vendor:
item['vendor'] = objItem.Vendor
if objItem.Version:
item['version'] = objItem.Version
items.append(item)
proc = subprocess.Popen(
["powershell.exe", "-Command", "-"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
return items
stdout, _ = proc.communicate(" ".join(powershell_command).encode("utf-8"))
if proc.returncode != 0:
raise RuntimeError("Failed to get list of installed software")
# On AppVeyor there's other output related to PSReadline,
# so grab only the JSON output and ignore everything else
json_match = re.match(
r".*(\[.*{.*}.*\]).*", stdout.decode("utf-8"), re.DOTALL
)
if not json_match:
raise RuntimeError(
"Couldn't find JSON output for list of installed software"
)
# Filter out missing keys
return list(
map(
lambda info: {k: info[k] for k in info if info[k]},
json.loads(json_match.group(1)),
)
)
def windows_profile():
@@ -89,7 +112,7 @@ def windows_profile():
def main(options):
if sys.platform == 'win32':
with open(options.output_json, 'wb') as f:
with open(options.output_json, 'w') as f:
json.dump(windows_profile(), f)
else:
raise OSError("Unsupported OS")

View File

@@ -394,6 +394,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from

View File

@@ -76,7 +76,7 @@ Writes `markup` to the clipboard.
```js
const { clipboard } = require('electron')
clipboard.writeHTML('<b>Hi</b')
clipboard.writeHTML('<b>Hi</b>')
```
### `clipboard.readImage([type])`

View File

@@ -102,8 +102,8 @@ has been included below for completeness:
| `Boolean` | Simple | ✅ | ✅ | N/A |
| `Object` | Complex | ✅ | ✅ | Keys must be supported using only "Simple" types in this table. Values must be supported in this table. Prototype modifications are dropped. Sending custom classes will copy values but not the prototype. |
| `Array` | Complex | ✅ | ✅ | Same limitations as the `Object` type |
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context |
| `Promise` | Complex | ✅ | ✅ | Promises are only proxied if they are the return value or exact parameter. Promises nested in arrays or objects will be dropped. |
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context, and any custom properties on the Error object [will be lost](https://github.com/electron/electron/issues/25596) |
| `Promise` | Complex | ✅ | ✅ | N/A
| `Function` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending classes or constructors will not work. |
| [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types |
| `Element` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending custom elements will not work. |

View File

@@ -67,3 +67,8 @@ or is being instructed to show a high-contrast UI.
A `Boolean` for if the OS / Chromium currently has an inverted color scheme
or is being instructed to use an inverted color scheme.
### `nativeTheme.inForcedColorsMode` _Windows_ _Readonly_
A `boolean` indicating whether Chromium is in forced colors mode, controlled by system accessibility settings.
Currently, Windows high contrast is the only system setting that triggers forced colors mode.

View File

@@ -178,7 +178,6 @@ Returns an object with V8 heap statistics. Note that all statistics are reported
Returns `Object`:
* `allocated` Integer - Size of all allocated objects in Kilobytes.
* `marked` Integer - Size of all marked objects in Kilobytes.
* `total` Integer - Total allocated space in Kilobytes.
Returns an object with Blink memory information.

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

@@ -1840,7 +1840,7 @@ the cursor when dragging.
#### `contents.savePage(fullPath, saveType)`
* `fullPath` String - The full file path.
* `fullPath` String - The absolute file path.
* `saveType` String - Specify the save type.
* `HTMLOnly` - Save only the HTML of the page.
* `HTMLComplete` - Save complete-html page.

View File

@@ -352,6 +352,8 @@ filenames = {
"shell/browser/child_web_contents_tracker.h",
"shell/browser/cookie_change_notifier.cc",
"shell/browser/cookie_change_notifier.h",
"shell/browser/electron_api_ipc_handler_impl.cc",
"shell/browser/electron_api_ipc_handler_impl.h",
"shell/browser/electron_autofill_driver.cc",
"shell/browser/electron_autofill_driver.h",
"shell/browser/electron_autofill_driver_factory.cc",
@@ -360,8 +362,6 @@ filenames = {
"shell/browser/electron_browser_client.h",
"shell/browser/electron_browser_context.cc",
"shell/browser/electron_browser_context.h",
"shell/browser/electron_browser_handler_impl.cc",
"shell/browser/electron_browser_handler_impl.h",
"shell/browser/electron_browser_main_parts.cc",
"shell/browser/electron_browser_main_parts.h",
"shell/browser/electron_download_manager_delegate.cc",
@@ -378,6 +378,8 @@ filenames = {
"shell/browser/electron_quota_permission_context.h",
"shell/browser/electron_speech_recognition_manager_delegate.cc",
"shell/browser/electron_speech_recognition_manager_delegate.h",
"shell/browser/electron_web_contents_utility_handler_impl.cc",
"shell/browser/electron_web_contents_utility_handler_impl.h",
"shell/browser/electron_web_ui_controller_factory.cc",
"shell/browser/electron_web_ui_controller_factory.h",
"shell/browser/event_emitter_mixin.cc",

View File

@@ -28,6 +28,17 @@ function sanitizeOptionsForGuest (options: Record<string, any>) {
return ret;
}
function makeLoadURLOptions (params: Record<string, any>) {
const opts: Electron.LoadURLOptions = {};
if (params.httpreferrer) {
opts.httpReferrer = params.httpreferrer;
}
if (params.useragent) {
opts.userAgent = params.useragent;
}
return opts;
}
// Create a new guest instance.
const createGuest = function (embedder: Electron.WebContents, params: Record<string, any>) {
// eslint-disable-next-line no-undef
@@ -51,7 +62,7 @@ const createGuest = function (embedder: Electron.WebContents, params: Record<str
// Init guest web view after attached.
guest.once('did-attach' as any, function (this: Electron.WebContents, event: Electron.Event) {
params = this.attachParams!;
const params = this.attachParams!;
delete this.attachParams;
const previouslyAttached = this.viewInstanceId != null;
@@ -63,14 +74,7 @@ const createGuest = function (embedder: Electron.WebContents, params: Record<str
}
if (params.src) {
const opts: Electron.LoadURLOptions = {};
if (params.httpreferrer) {
opts.httpReferrer = params.httpreferrer;
}
if (params.useragent) {
opts.userAgent = params.useragent;
}
this.loadURL(params.src, opts);
this.loadURL(params.src, params.opts);
}
embedder.emit('did-attach-webview', event, guest);
});
@@ -149,13 +153,15 @@ const attachGuest = function (event: Electron.IpcMainInvokeEvent,
throw new Error(`Access denied to guestInstanceId: ${guestInstanceId}`);
}
const { instanceId } = params;
// If this guest is already attached to an element then remove it
if (guestInstance.elementInstanceId) {
const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`;
embedderElementsMap.delete(oldKey);
// Remove guest from embedder if moving across web views
if (guest.viewInstanceId !== params.instanceId) {
if (guest.viewInstanceId !== instanceId) {
webViewManager.removeGuest(guestInstance.embedder, guestInstanceId);
guestInstance.embedder._sendInternal(`${IPC_MESSAGES.GUEST_VIEW_INTERNAL_DESTROY_GUEST}-${guest.viewInstanceId}`);
}
@@ -206,12 +212,12 @@ const attachGuest = function (event: Electron.IpcMainInvokeEvent,
embedder.emit('will-attach-webview', event, webPreferences, params);
if (event.defaultPrevented) {
if (guest.viewInstanceId == null) guest.viewInstanceId = params.instanceId;
if (guest.viewInstanceId == null) guest.viewInstanceId = instanceId;
guest.destroy();
return;
}
guest.attachParams = params;
guest.attachParams = { instanceId, src: params.src, opts: makeLoadURLOptions(params) };
embedderElementsMap.set(key, guestInstanceId);
guest.setEmbedder(embedder);

View File

@@ -27,7 +27,6 @@ export class WebViewImpl {
public hasFocus = false
public internalInstanceId?: number;
public resizeObserver?: ResizeObserver;
public userAgentOverride?: string;
public viewInstanceId: number
// on* Event handlers.
@@ -180,8 +179,7 @@ export class WebViewImpl {
buildParams () {
const params: Record<string, any> = {
instanceId: this.viewInstanceId,
userAgentOverride: this.userAgentOverride
instanceId: this.viewInstanceId
};
for (const [attributeName, attribute] of this.attributes) {

View File

@@ -1,9 +1,10 @@
{
"name": "electron",
"version": "15.3.6",
"version": "15.5.7",
"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.2",
"@electron/typescript-definitions": "^8.9.5",
"@octokit/auth-app": "^2.10.0",

View File

@@ -3,3 +3,17 @@ cherry-pick-05e69c75905f.patch
cherry-pick-891020ed64d4.patch
cherry-pick-2b98abd8cb6c.patch
cherry-pick-cc44ae61f37b.patch
vangle_change_the_default_vulkan_device_choose_logic.patch
m96_validate_samplerformat.patch
m98_vulkan_fix_vkcmdresolveimage_extents.patch
m98_vulkan_fix_vkcmdresolveimage_offsets.patch
cherry-pick-49e8ff16f1fe.patch
m99_vulkan_prevent_out_of_bounds_read_in_divisor_emulation_path.patch
m99_vulkan_streamvertexdatawithdivisor_write_beyond_buffer_boundary.patch
m98_protect_against_deleting_a_current_xfb_buffer.patch
m96-lts_vulkan_fix_issue_with_redefining_a_layered_attachment.patch
cherry-pick-d27d9d059b51.patch
m100_fix_crash_when_pausing_xfb_then_deleting_a_buffer.patch
cherry-pick-d49484c21e3c.patch
cherry-pick-a602a068e022.patch
fix_checkednumeric_using_the_wrong_type.patch

View File

@@ -0,0 +1,381 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Tue, 25 Jan 2022 12:15:16 -0500
Subject: M99: Vulkan: Fix texture array level redefinition
When a level of a texture is redefined, all staged updates to that level
should be removed, not the ones specific to the new layers. The bug
fixed was that if the texture was redefined to have its number of layers
changed, the staged higher-layer-count update to the image was not
removed.
Bug: chromium:1289383
Change-Id: Iab79c38d846d1abbdd92e11b1b60a3adf0fbde4c
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3441309
Reviewed-by: Lingfeng Yang <lfy@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index b43f41dbae29356f1ffe4f961ed83e0f0e9cdcd2..610f720b68d37aaddf142b0dca538749386cef7e 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -1553,12 +1553,25 @@ angle::Result TextureVk::redefineLevel(const gl::Context *context,
if (mImage != nullptr)
{
- // If there is any staged changes for this index, we can remove them since we're going to
+ // If there are any staged changes for this index, we can remove them since we're going to
// override them with this call.
gl::LevelIndex levelIndexGL(index.getLevelIndex());
uint32_t layerIndex = index.hasLayer() ? index.getLayerIndex() : 0;
- mImage->removeSingleSubresourceStagedUpdates(contextVk, levelIndexGL, layerIndex,
- index.getLayerCount());
+ if (gl::IsArrayTextureType(index.getType()))
+ {
+ // A multi-layer texture is being redefined, remove all updates to this level; the
+ // number of layers may have changed.
+ mImage->removeStagedUpdates(contextVk, levelIndexGL, levelIndexGL);
+ }
+ else
+ {
+ // Otherwise remove only updates to this layer. For example, cube map updates can be
+ // done through glTexImage2D, one per cube face (i.e. layer) and so should not remove
+ // updates to the other layers.
+ ASSERT(index.getLayerCount() == 1);
+ mImage->removeSingleSubresourceStagedUpdates(contextVk, levelIndexGL, layerIndex,
+ index.getLayerCount());
+ }
if (mImage->valid())
{
diff --git a/src/tests/gl_tests/MipmapTest.cpp b/src/tests/gl_tests/MipmapTest.cpp
index 8a6d01ca36a84a9e294de3f6f0114ee7a54e1d9a..957a52304edc9aa245f9f21e5557cc105cbad789 100644
--- a/src/tests/gl_tests/MipmapTest.cpp
+++ b/src/tests/gl_tests/MipmapTest.cpp
@@ -1686,6 +1686,106 @@ TEST_P(MipmapTestES3, MipmapsForTexture3D)
EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
}
+// Create a 2D array, then immediately redefine it to have fewer layers. Regression test for a bug
+// in the Vulkan backend where the old higher-layer-count data upload was not removed.
+TEST_P(MipmapTestES3, TextureArrayRedefineThenGenerateMipmap)
+{
+ int px = getWindowWidth() / 2;
+ int py = getWindowHeight() / 2;
+
+ glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
+
+ // Fill the whole texture with red, then redefine it and fill with green
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsRed.data());
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsGreen.data());
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ EXPECT_GL_NO_ERROR();
+
+ // Generate mipmaps
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
+ EXPECT_GL_NO_ERROR();
+
+ glUseProgram(mArrayProgram);
+ EXPECT_GL_NO_ERROR();
+
+ // Draw the first slice
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
+ drawQuad(mArrayProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+
+ // Draw the second slice
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
+ drawQuad(mArrayProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+}
+
+// Create a 2D array, use it, then redefine it to have fewer layers. Regression test for a bug in
+// the Vulkan backend where the old higher-layer-count data upload was not removed.
+TEST_P(MipmapTestES3, TextureArrayUseThenRedefineThenGenerateMipmap)
+{
+ int px = getWindowWidth() / 2;
+ int py = getWindowHeight() / 2;
+
+ glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture);
+
+ // Fill the whole texture with red.
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsRed.data());
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ EXPECT_GL_NO_ERROR();
+
+ // Generate mipmap
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
+ EXPECT_GL_NO_ERROR();
+
+ glUseProgram(mArrayProgram);
+ EXPECT_GL_NO_ERROR();
+
+ // Draw the first slice
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
+ drawQuad(mArrayProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
+
+ // Draw the fourth slice
+ glUniform1i(mTextureArraySliceUniformLocation, 3);
+ drawQuad(mArrayProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
+
+ // Redefine the image and fill with green
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsGreen.data());
+
+ // Generate mipmap
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
+ EXPECT_GL_NO_ERROR();
+
+ // Draw the first slice
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
+ drawQuad(mArrayProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+
+ // Draw the second slice
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
+ drawQuad(mArrayProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+}
+
// Create a 2D texture with levels 0-2, call GenerateMipmap with base level 1 so that level 0 stays
// the same, and then sample levels 0 and 2.
// GLES 3.0.4 section 3.8.10:
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index 56bef0186234f59d370669c21f588ea9c5c356fc..772fe27daac3ac0b5f54b8319cef6aa9c980208a 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -1028,31 +1028,37 @@ class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest
class Texture2DArrayTestES3 : public TexCoordDrawTest
{
protected:
- Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {}
+ Texture2DArrayTestES3()
+ : TexCoordDrawTest(),
+ m2DArrayTexture(0),
+ mTextureArrayLocation(-1),
+ mTextureArraySliceUniformLocation(-1)
+ {}
const char *getVertexShaderSource() override
{
- return "#version 300 es\n"
- "out vec2 texcoord;\n"
- "in vec4 position;\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
- " texcoord = (position.xy * 0.5) + 0.5;\n"
- "}\n";
+ return R"(#version 300 es
+out vec2 texcoord;
+in vec4 position;
+void main()
+{
+ gl_Position = vec4(position.xy, 0.0, 1.0);
+ texcoord = (position.xy * 0.5) + 0.5;
+})";
}
const char *getFragmentShaderSource() override
{
- return "#version 300 es\n"
- "precision highp float;\n"
- "uniform highp sampler2DArray tex2DArray;\n"
- "in vec2 texcoord;\n"
- "out vec4 fragColor;\n"
- "void main()\n"
- "{\n"
- " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n"
- "}\n";
+ return R"(#version 300 es
+precision highp float;
+uniform highp sampler2DArray tex2DArray;
+uniform int slice;
+in vec2 texcoord;
+out vec4 fragColor;
+void main()
+{
+ fragColor = texture(tex2DArray, vec3(texcoord, float(slice)));
+})";
}
void testSetUp() override
@@ -1064,6 +1070,9 @@ class Texture2DArrayTestES3 : public TexCoordDrawTest
mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray");
ASSERT_NE(-1, mTextureArrayLocation);
+ mTextureArraySliceUniformLocation = glGetUniformLocation(mProgram, "slice");
+ ASSERT_NE(-1, mTextureArraySliceUniformLocation);
+
glGenTextures(1, &m2DArrayTexture);
ASSERT_GL_NO_ERROR();
}
@@ -1076,6 +1085,7 @@ class Texture2DArrayTestES3 : public TexCoordDrawTest
GLuint m2DArrayTexture;
GLint mTextureArrayLocation;
+ GLint mTextureArraySliceUniformLocation;
};
class TextureSizeTextureArrayTest : public TexCoordDrawTest
@@ -1718,28 +1728,28 @@ class Texture2DArrayIntegerTestES3 : public Texture2DArrayTestES3
const char *getVertexShaderSource() override
{
- return "#version 300 es\n"
- "out vec2 texcoord;\n"
- "in vec4 position;\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
- " texcoord = (position.xy * 0.5) + 0.5;\n"
- "}\n";
+ return R"(#version 300 es
+out vec2 texcoord;
+in vec4 position;
+void main()
+{
+ gl_Position = vec4(position.xy, 0.0, 1.0);
+ texcoord = (position.xy * 0.5) + 0.5;
+})";
}
const char *getFragmentShaderSource() override
{
- return "#version 300 es\n"
- "precision highp float;\n"
- "uniform highp usampler2DArray tex2DArray;\n"
- "in vec2 texcoord;\n"
- "out vec4 fragColor;\n"
- "void main()\n"
- "{\n"
- " fragColor = vec4(texture(tex2DArray, vec3(texcoord.x, texcoord.y, "
- "0.0)))/255.0;\n"
- "}\n";
+ return R"(#version 300 es
+precision highp float;
+uniform highp usampler2DArray tex2DArray;
+uniform int slice;
+in vec2 texcoord;
+out vec4 fragColor;
+void main()
+{
+ fragColor = vec4(texture(tex2DArray, vec3(texcoord, slice)))/255.0;
+})";
}
};
@@ -5112,6 +5122,94 @@ TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensio
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
}
+// Create a 2D array, then immediately redefine it to have fewer layers. Regression test for a bug
+// in the Vulkan backend where the old higher-layer-count data upload was not removed.
+TEST_P(Texture2DArrayTestES3, TextureArrayRedefineThenUse)
+{
+ int px = getWindowWidth() / 2;
+ int py = getWindowHeight() / 2;
+
+ glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+
+ // Fill the whole texture with red, then redefine it and fill with green
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsRed.data());
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsGreen.data());
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ EXPECT_GL_NO_ERROR();
+
+ glUseProgram(mProgram);
+ EXPECT_GL_NO_ERROR();
+
+ // Draw the first slice
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
+ drawQuad(mProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+
+ // Draw the second slice
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
+ drawQuad(mProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+}
+
+// Create a 2D array, use it, then redefine it to have fewer layers. Regression test for a bug in
+// the Vulkan backend where the old higher-layer-count data upload was not removed.
+TEST_P(Texture2DArrayTestES3, TextureArrayUseThenRedefineThenUse)
+{
+ int px = getWindowWidth() / 2;
+ int py = getWindowHeight() / 2;
+
+ glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture);
+
+ // Fill the whole texture with red.
+ std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsRed.data());
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ EXPECT_GL_NO_ERROR();
+
+ glUseProgram(mProgram);
+ EXPECT_GL_NO_ERROR();
+
+ // Draw the first slice
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
+ drawQuad(mProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
+
+ // Draw the fourth slice
+ glUniform1i(mTextureArraySliceUniformLocation, 3);
+ drawQuad(mProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red);
+
+ // Redefine the image and fill with green
+ std::vector<GLColor> pixelsGreen(2 * 2 * 2, GLColor::green);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixelsGreen.data());
+
+ // Draw the first slice
+ glUniform1i(mTextureArraySliceUniformLocation, 0);
+ drawQuad(mProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+
+ // Draw the second slice
+ glUniform1i(mTextureArraySliceUniformLocation, 1);
+ drawQuad(mProgram, "position", 0.5f);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green);
+}
+
// Test that texture completeness is updated if texture max level changes.
// GLES 3.0.4 section 3.8.13 Texture completeness
TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel)

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 182709c348f7490e1ee990a05570c13d7e9d0dd7..dc2b1728e3a7ab494e616940565f08692a9ff028 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -2115,10 +2115,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 15243f0c5a42949c2ce94dbd415089b77a7e39bc..2ff2fd75a73b50e3bce5d72e64d5d3064f30bd66 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -954,6 +954,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_PERF_WARNING(getDebug(), GL_DEBUG_SEVERITY_LOW,
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 93378c4b24495872405fc06ea01e15254229ab63..035c80a5ba95492247bd87e4189de602ffb47da1 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -492,6 +492,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,
@@ -516,9 +527,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 1523cd5f0093b7b4b03bf0cd5432ee0a15f17dab..5f42d4b418fe6ae2f8c7473ef7a8954ef128ff99 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -4286,6 +4286,13 @@ bool ValidateUniformBlockBinding(const Context *context,
return false;
}
+ if (!ValidateProgramExecutableXFBBuffersPresent(context,
+ context->getState().getProgramExecutable()))
+ {
+ context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
+ return false;
+ }
+
return true;
}

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 9802a3385d5f042df8b643b9b452de29b41ba868..e0add8edaac527fac374afefbebce216d21182e9 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -3779,7 +3779,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 b3e70c797ace1fbcaf0002fe7d63e4b4ac418e97..bad538962d262f81b3e6e78c820a28e114ea75fa 100644
--- a/src/tests/gl_tests/BufferDataTest.cpp
+++ b/src/tests/gl_tests/BufferDataTest.cpp
@@ -746,6 +746,19 @@ void main()
EXPECT_PIXEL_COLOR_EQ(3, 3, GLColor::green);
}
+// 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,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 d5732741dff989b8b8f6f669511bf7bc001c4eaa..eb571bb2de3c4568810026e0364bf069bd8ca681 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -3949,7 +3949,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 63dd230829716b7a95b7917b47fb1fc278c1098a..e6ed494e89c0a0c48af4789be91d240df769281f 100644
--- a/src/tests/gl_tests/TransformFeedbackTest.cpp
+++ b/src/tests/gl_tests/TransformFeedbackTest.cpp
@@ -3660,6 +3660,25 @@ void main() {
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
+// 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

@@ -0,0 +1,94 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Tue, 1 Mar 2022 15:40:38 -0500
Subject: Vulkan: Fix issue with redefining a layered attachment.
The fix ensures we complete level redefinition before we get the
layer render target in TextureVk::getAttachmentRenderTarget.
Bug: chromium:1296866
Change-Id: Id7fa8e9fed5e766c30580b09336713c675c4e4f0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3498283
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 348ece42552a99cff88f79c80652b9dd3155ab22)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3513754
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 610f720b68d37aaddf142b0dca538749386cef7e..569118e7137e8ea6dc02cc6247980c2198bf92db 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -2174,6 +2174,15 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
ContextVk *contextVk = vk::GetImpl(context);
+ if (mRedefinedLevels.any())
+ {
+ // If we have redefined levels, we must flush those out to fix the render targets.
+ ANGLE_TRY(respecifyImageStorage(contextVk));
+ }
+
+ // Otherwise, don't flush staged updates here. We'll handle that in FramebufferVk so we can
+ // defer clears.
+
if (!mImage->valid())
{
// Immutable texture must already have a valid image
@@ -2217,8 +2226,6 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
mState.getType(), samples, *mImage, useRobustInit));
}
- // Don't flush staged updates here. We'll handle that in FramebufferVk so it can defer clears.
-
GLuint layerIndex = 0, layerCount = 0, imageLayerCount = 0;
GetRenderTargetLayerCountAndIndex(mImage, imageIndex, &layerIndex, &layerCount,
&imageLayerCount);
@@ -2229,10 +2236,14 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
gl::LevelIndex(imageIndex.getLevelIndex()),
renderToTextureIndex);
- ASSERT(imageIndex.getLevelIndex() <
- static_cast<int32_t>(mSingleLayerRenderTargets[renderToTextureIndex].size()));
- *rtOut = &mSingleLayerRenderTargets[renderToTextureIndex][imageIndex.getLevelIndex()]
- [layerIndex];
+ std::vector<RenderTargetVector> &levelRenderTargets =
+ mSingleLayerRenderTargets[renderToTextureIndex];
+ ASSERT(imageIndex.getLevelIndex() < static_cast<int32_t>(levelRenderTargets.size()));
+
+ RenderTargetVector &layerRenderTargets = levelRenderTargets[imageIndex.getLevelIndex()];
+ ASSERT(imageIndex.getLayerIndex() < static_cast<int32_t>(layerRenderTargets.size()));
+
+ *rtOut = &layerRenderTargets[layerIndex];
}
else
{
diff --git a/src/tests/gl_tests/FramebufferTest.cpp b/src/tests/gl_tests/FramebufferTest.cpp
index cd733be3ae5c179860d882e305ec84d093a283ed..c0b745978ae5d28d97bb833f7fe6278872d8d620 100644
--- a/src/tests/gl_tests/FramebufferTest.cpp
+++ b/src/tests/gl_tests/FramebufferTest.cpp
@@ -3427,6 +3427,25 @@ TEST_P(FramebufferTest_ES3, BindRenderbufferThenModifySize)
ASSERT_GL_NO_ERROR();
}
+// Tests redefining a layered framebuffer attachment.
+TEST_P(FramebufferTest_ES3, RedefineLayerAttachment)
+{
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_3D, texture);
+ std::vector<uint8_t> imgData(20480, 0);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, 8, 8, 8, 0, GL_RED, GL_UNSIGNED_BYTE, imgData.data());
+
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, 8);
+ glGenerateMipmap(GL_TEXTURE_3D);
+
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_R8UI, 16, 16, 16, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE,
+ imgData.data());
+ glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 2, 2, 15, 16, 16);
+ ASSERT_GL_NO_ERROR();
+}
+
ANGLE_INSTANTIATE_TEST_ES2(AddMockTextureNoRenderTargetTest);
ANGLE_INSTANTIATE_TEST_ES2(FramebufferTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferFormatsTest);

View File

@@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lingfeng Yang <lfy@google.com>
Date: Wed, 1 Dec 2021 17:08:01 -0800
Subject: M96: Validate SamplerFormat
We weren't validating sampler formats in ProgramExecutable validation.
Bug: chromium:1273661
Change-Id: Ida0c67c0c7169ea3f47ceb2d433bee17012a7e5e
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3312717
Reviewed-by: Charlie Lao <cclao@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Lingfeng Yang <lfy@google.com>
(cherry picked from commit 6d3435fddd7abd67699c3f020d6b4fa21445d9b3)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3335173
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/ProgramExecutable.cpp b/src/libANGLE/ProgramExecutable.cpp
index baf63ecec6f82fda9dd79a1c398b8e95ec70e321..14e5abdfab36a95f39839fc171e6e0bc3a5dc6e9 100644
--- a/src/libANGLE/ProgramExecutable.cpp
+++ b/src/libANGLE/ProgramExecutable.cpp
@@ -1132,6 +1132,19 @@ bool ProgramExecutable::validateSamplersImpl(InfoLog *infoLog, const Caps &caps)
mCachedValidateSamplersResult = false;
return false;
}
+
+ if (mActiveSamplerFormats[textureUnit] == SamplerFormat::InvalidEnum)
+ {
+ if (infoLog)
+ {
+ (*infoLog) << "Samplers of conflicting formats refer to the same texture "
+ "image unit ("
+ << textureUnit << ").";
+ }
+
+ mCachedValidateSamplersResult = false;
+ return false;
+ }
}
mCachedValidateSamplersResult = true;
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index ba512a11cb023d9caae666ab2634d1e66057d12c..56bef0186234f59d370669c21f588ea9c5c356fc 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -9796,8 +9796,6 @@ class TextureChangeStorageUploadTest : public ANGLETest
FAIL() << "shader compilation failed.";
}
- mColorLocation = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
-
glUseProgram(mProgram);
glClearColor(0, 0, 0, 0);
@@ -9842,6 +9840,53 @@ TEST_P(TextureChangeStorageUploadTest, Basic)
EXPECT_GL_NO_ERROR();
}
+class ExtraSamplerCubeShadowUseTest : public ANGLETest
+{
+ protected:
+ ExtraSamplerCubeShadowUseTest() : ANGLETest() {}
+
+ const char *getVertexShaderSource() { return "#version 300 es\nvoid main() {}"; }
+
+ const char *getFragmentShaderSource()
+ {
+ return R"(#version 300 es
+precision mediump float;
+
+uniform mediump samplerCube var_0002; // this has to be there
+uniform highp samplerCubeShadow var_0004; // this has to be a cube shadow sampler
+out vec4 color;
+void main() {
+
+ vec4 var_0031 = texture(var_0002, vec3(1,1,1));
+ ivec2 size = textureSize(var_0004, 0) ;
+ var_0031.x += float(size.y);
+
+ color = var_0031;
+})";
+ }
+
+ void testSetUp() override
+ {
+ mProgram = CompileProgram(getVertexShaderSource(), getFragmentShaderSource());
+ if (mProgram == 0)
+ {
+ FAIL() << "shader compilation failed.";
+ }
+ glUseProgram(mProgram);
+ ASSERT_GL_NO_ERROR();
+ }
+
+ void testTearDown() override { glDeleteProgram(mProgram); }
+
+ GLuint mProgram;
+};
+
+TEST_P(ExtraSamplerCubeShadowUseTest, Basic)
+{
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
#define ES2_EMULATE_COPY_TEX_IMAGE() \
@@ -9957,4 +10002,6 @@ ANGLE_INSTANTIATE_TEST_ES31_AND(CopyImageTestES31, WithDirectSPIRVGeneration(ES3
ANGLE_INSTANTIATE_TEST_ES3(TextureChangeStorageUploadTest);
+ANGLE_INSTANTIATE_TEST_ES3(ExtraSamplerCubeShadowUseTest);
+
} // anonymous namespace

View File

@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Tue, 1 Mar 2022 16:14:47 -0500
Subject: Protect against deleting a current XFB buffer.
Bug: chromium:1295411
Change-Id: I097f272c38e444e0af71aa55c0dc508a07aa0bd3
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3498262
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit d9002eef2a5f27fc5d6b65d01d02afcfb9a35db1)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3514175
Reviewed-by: Ian Elliott <ianelliott@google.com>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 8ec1eca3f4bc70da39c838a0f81664043276bc80..182709c348f7490e1ee990a05570c13d7e9d0dd7 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -2115,6 +2115,10 @@ angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
if (curTransformFeedback)
{
ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID));
+ if (isTransformFeedbackActiveUnpaused())
+ {
+ context->getStateCache().onActiveTransformFeedbackChange(context);
+ }
}
if (getVertexArray()->detachBuffer(context, bufferID))
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 4c1ec1fc73746e2aba97ea83da5e8bcbd0b41ba5..d5732741dff989b8b8f6f669511bf7bc001c4eaa 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -3948,6 +3948,14 @@ const char *ValidateDrawStates(const Context *context)
return kTessellationShaderRequiresBothControlAndEvaluation;
}
}
+
+ if (state.isTransformFeedbackActiveUnpaused())
+ {
+ if (!ValidateProgramExecutableXFBBuffersPresent(context, executable))
+ {
+ return kTransformFeedbackBufferMissing;
+ }
+ }
}
if (programIsYUVOutput != framebufferIsYUV)
@@ -8055,4 +8063,21 @@ bool ValidateInvalidateTextureANGLE(const Context *context, TextureType target)
return true;
}
+bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
+ const ProgramExecutable *programExecutable)
+{
+ size_t programXfbCount = programExecutable->getTransformFeedbackBufferCount();
+ const TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ for (size_t programXfbIndex = 0; programXfbIndex < programXfbCount; ++programXfbIndex)
+ {
+ const OffsetBindingPointer<Buffer> &buffer =
+ transformFeedback->getIndexedBuffer(programXfbIndex);
+ if (!buffer.get())
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
} // namespace gl
diff --git a/src/libANGLE/validationES.h b/src/libANGLE/validationES.h
index f7daadb3de4d0a28f1896bad54bdc59f31a45cd3..934a35f6557462fd8da52fd7de7aba0ee5186dff 100644
--- a/src/libANGLE/validationES.h
+++ b/src/libANGLE/validationES.h
@@ -755,6 +755,9 @@ bool ValidateGetMultisamplefvBase(const Context *context,
const GLfloat *val);
bool ValidateSampleMaskiBase(const Context *context, GLuint maskNumber, GLbitfield mask);
+bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
+ const ProgramExecutable *programExecutable);
+
// We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
// implementation format info for incomplete framebuffers. It seems like these queries are
// incongruent with the other errors.
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index f385ef623cc56658dc5f840ddd3f3c3bf9bf3e05..1523cd5f0093b7b4b03bf0cd5432ee0a15f17dab 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -2786,16 +2786,10 @@ bool ValidateBeginTransformFeedback(const Context *context, PrimitiveMode primit
return false;
}
- size_t programXfbCount = programExecutable->getTransformFeedbackBufferCount();
- for (size_t programXfbIndex = 0; programXfbIndex < programXfbCount; ++programXfbIndex)
+ if (!ValidateProgramExecutableXFBBuffersPresent(context, programExecutable))
{
- const OffsetBindingPointer<Buffer> &buffer =
- transformFeedback->getIndexedBuffer(programXfbIndex);
- if (!buffer.get())
- {
- context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
- return false;
- }
+ context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
+ return false;
}
return true;

View File

@@ -0,0 +1,112 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Mon, 31 Jan 2022 12:07:43 -0500
Subject: M98: Vulkan: Fix vkCmdResolveImage extents
The source framebuffer's extents were accidentally used instead of the
blit area extents.
Bug: chromium:1288020
Change-Id: I5c6128a191deeea2f972dc7f010be9d40c674ce6
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3457022
Reviewed-by: Tim Van Patten <timvp@google.com>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 4f7428217a130482dbbee760d32f183cee2255f6..ac4c4086c28be29a65386ef06cc103d14dfb0d48 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -1459,8 +1459,8 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
resolveRegion.dstOffset.x = params.destOffset[0];
resolveRegion.dstOffset.y = params.destOffset[1];
resolveRegion.dstOffset.z = 0;
- resolveRegion.extent.width = params.srcExtents[0];
- resolveRegion.extent.height = params.srcExtents[1];
+ resolveRegion.extent.width = params.blitArea.width;
+ resolveRegion.extent.height = params.blitArea.height;
resolveRegion.extent.depth = 1;
vk::PerfCounters &perfCounters = contextVk->getPerfCounters();
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index 5712456966c3a77ba73295c083888ad0ab821a78..b9a0423345ba3a19e425a0b7ba7985ca191fdae7 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -70,6 +70,7 @@
// the test says. The test also fails on Intel/Vulkan/Windows.
6068 INTEL VULKAN : MultiviewRenderPrimitiveTest.LineLoop/* = SKIP
6068 INTEL VULKAN : MultiviewRenderPrimitiveTest.LineStrip/* = SKIP
+6962 WIN INTEL VULKAN : BlitFramebufferTestES31.PartialResolve/* = SKIP
// Mac
6025 MAC AMD OPENGL : IndexBufferOffsetTestES3.UseAsUBOThenUpdateThenUInt8Index/* = SKIP
diff --git a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
index affed96be99a8e0b819919ce971968168c546ca1..22356a7c65339fe8b1e601f54a3491ea77237432 100644
--- a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
+++ b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
@@ -2637,6 +2637,67 @@ TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)
EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);
}
+// Regression test for a bug in the Vulkan backend where vkCmdResolveImage was using the src extents
+// as the resolve area instead of the area passed to glBlitFramebuffer.
+TEST_P(BlitFramebufferTestES31, PartialResolve)
+{
+ constexpr GLint kWidth = 16;
+ constexpr GLint kHeight = 32;
+
+ // Read framebuffer is multisampled.
+ GLTexture readTexture;
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
+ glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
+
+ GLFramebuffer readFbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
+ readTexture, 0);
+ ASSERT_GL_NO_ERROR();
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ glClearColor(1, 0, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // Draw framebuffer is single sampled. It's bound to a texture with base level the same size as
+ // the read framebuffer, but it's bound to mip 1.
+ GLTexture drawTexture;
+ glBindTexture(GL_TEXTURE_2D, drawTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ GLFramebuffer drawFbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 1);
+ ASSERT_GL_NO_ERROR();
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ glClearColor(0, 1, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kHeight / 2, GLColor::green);
+
+ constexpr GLint kResolveX0 = 1;
+ constexpr GLint kResolveY0 = 2;
+ constexpr GLint kResolveX1 = 4;
+ constexpr GLint kResolveY1 = 6;
+
+ // Resolve only a portion of the read framebuffer.
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
+ glBlitFramebuffer(kResolveX0, kResolveY0, kResolveX1, kResolveY1, kResolveX0, kResolveY0,
+ kResolveX1, kResolveY1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kResolveY0, GLColor::green);
+ EXPECT_PIXEL_RECT_EQ(0, 0, kResolveX0, kHeight / 2, GLColor::green);
+ EXPECT_PIXEL_RECT_EQ(kResolveX1, 0, kWidth / 2 - kResolveX1, kHeight / 2, GLColor::green);
+ EXPECT_PIXEL_RECT_EQ(0, kResolveY1, kWidth / 2, kHeight / 2 - kResolveY1, GLColor::green);
+
+ EXPECT_PIXEL_RECT_EQ(kResolveX0, kResolveY0, kResolveX1 - kResolveX0, kResolveY1 - kResolveY0,
+ GLColor::red);
+}
+
// Test that a draw call to a small FBO followed by a resolve of a large FBO works.
TEST_P(BlitFramebufferTestES31, DrawToSmallFBOThenResolveLargeFBO)
{

View File

@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Mon, 7 Feb 2022 13:46:46 -0500
Subject: M98: Vulkan: Fix vkCmdResolveImage offsets
glBlitFramebuffer takes identical regions for src and dst when
resolving. vkCmdResolveImage should use the clipped area instead of
using the actual offsets passed to this function.
Bug: chromium:1292537
Change-Id: If283a8acbca3249b771facbc30bd9f8080a03656
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3457023
Reviewed-by: Tim Van Patten <timvp@google.com>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index ac4c4086c28be29a65386ef06cc103d14dfb0d48..45308e0261b48eed17d144169b698165b04422f9 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -1451,13 +1451,13 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
resolveRegion.srcSubresource.mipLevel = 0;
resolveRegion.srcSubresource.baseArrayLayer = params.srcLayer;
resolveRegion.srcSubresource.layerCount = 1;
- resolveRegion.srcOffset.x = params.srcOffset[0];
- resolveRegion.srcOffset.y = params.srcOffset[1];
+ resolveRegion.srcOffset.x = params.blitArea.x;
+ resolveRegion.srcOffset.y = params.blitArea.y;
resolveRegion.srcOffset.z = 0;
resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
resolveRegion.dstSubresource.layerCount = 1;
- resolveRegion.dstOffset.x = params.destOffset[0];
- resolveRegion.dstOffset.y = params.destOffset[1];
+ resolveRegion.dstOffset.x = params.blitArea.x;
+ resolveRegion.dstOffset.y = params.blitArea.y;
resolveRegion.dstOffset.z = 0;
resolveRegion.extent.width = params.blitArea.width;
resolveRegion.extent.height = params.blitArea.height;
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index b9a0423345ba3a19e425a0b7ba7985ca191fdae7..0646a12afacc16fd7df938e615976a28b6da6ab0 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -15,6 +15,8 @@
6142 VULKAN : BlitFramebufferTest.BlitDepthStencilPixelByPixel/* = SKIP
6153 VULKAN WIN INTEL : GLSLTest_ES31.StructAndArrayEqualOperator/ES3_1_Vulkan_DirectSPIRVGen = SKIP
6153 VULKAN PIXEL4ORXL : GLSLTest_ES31.StructAndArrayEqualOperator/ES3_1_Vulkan_DirectSPIRVGen = SKIP
+6989 OPENGL : BlitFramebufferTestES31.OOBResolve/* = SKIP
+6989 GLES : BlitFramebufferTestES31.OOBResolve/* = SKIP
// Direct SPIR-V generation. The following tests pass on some platforms but not others. Need to investigate.
4889 VULKAN : GeometryShaderTest.LayeredFramebufferPreRenderClear2DArrayColor/ES3_1_Vulkan_DirectSPIRVGen = SKIP
diff --git a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
index 22356a7c65339fe8b1e601f54a3491ea77237432..697cfcc8e10db571a407c0e44da36583614f2cb8 100644
--- a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
+++ b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
@@ -2637,6 +2637,55 @@ TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)
EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);
}
+// Regression test for a bug in the Vulkan backend where vkCmdResolveImage was used with
+// out-of-bounds regions.
+TEST_P(BlitFramebufferTestES31, OOBResolve)
+{
+ constexpr GLint kWidth = 16;
+ constexpr GLint kHeight = 32;
+
+ // Read framebuffer is multisampled.
+ GLTexture readTexture;
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
+ glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
+
+ GLFramebuffer readFbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
+ readTexture, 0);
+ ASSERT_GL_NO_ERROR();
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ glClearColor(1, 0, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // Draw framebuffer is single sampled.
+ GLTexture drawTexture;
+ glBindTexture(GL_TEXTURE_2D, drawTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ GLFramebuffer drawFbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 0);
+ ASSERT_GL_NO_ERROR();
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ glClearColor(0, 1, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
+
+ // Resolve the read framebuffer, using bounds that are outside the size of the image.
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
+ glBlitFramebuffer(-kWidth * 2, -kHeight * 3, kWidth * 11, kHeight * 8, -kWidth * 2,
+ -kHeight * 3, kWidth * 11, kHeight * 8, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
+ EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
+}
+
// Regression test for a bug in the Vulkan backend where vkCmdResolveImage was using the src extents
// as the resolve area instead of the area passed to glBlitFramebuffer.
TEST_P(BlitFramebufferTestES31, PartialResolve)

View File

@@ -0,0 +1,303 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Roman Lavrov <romanl@google.com>
Date: Tue, 18 Jan 2022 20:05:55 +0000
Subject: M99: Vulkan: Prevent out of bounds read in divisor emulation path.
Split the replicated part of StreamVertexData out to
StreamVertexDataWithDivisor, there is only a partial argument
overlap between the two.
Bug: chromium:1285885
Change-Id: Ibf6ab3efc6b12b430b1d391c6ae61bd9668b4407
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3398816
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Roman Lavrov <romanl@google.com>
(cherry picked from commit 5f0badf4541ba52659c937cfe9190d3735a76c10)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3461414
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index ed416508cab06797a8c4d52e7ab982d538f57e3c..1ca486af3ff004e11aea82c391b4c504b569096c 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -81,34 +81,62 @@ angle::Result StreamVertexData(ContextVk *contextVk,
size_t destOffset,
size_t vertexCount,
size_t sourceStride,
- size_t destStride,
VertexCopyFunction vertexLoadFunction,
vk::BufferHelper **bufferOut,
- VkDeviceSize *bufferOffsetOut,
- uint32_t replicateCount)
+ VkDeviceSize *bufferOffsetOut)
{
uint8_t *dst = nullptr;
ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, nullptr, bufferOffsetOut,
nullptr));
*bufferOut = dynamicBuffer->getCurrentBuffer();
dst += destOffset;
- if (replicateCount == 1)
+ vertexLoadFunction(sourceData, sourceStride, vertexCount, dst);
+
+ ANGLE_TRY(dynamicBuffer->flush(contextVk));
+ return angle::Result::Continue;
+}
+
+angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
+ vk::DynamicBuffer *dynamicBuffer,
+ const uint8_t *sourceData,
+ size_t bytesToAllocate,
+ size_t sourceStride,
+ size_t destStride,
+ VertexCopyFunction vertexLoadFunction,
+ vk::BufferHelper **bufferOut,
+ VkDeviceSize *bufferOffsetOut,
+ uint32_t divisor,
+ size_t numSrcVertices)
+{
+ uint8_t *dst = nullptr;
+ ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, nullptr, bufferOffsetOut,
+ nullptr));
+ *bufferOut = dynamicBuffer->getCurrentBuffer();
+
+ // Each source vertex is used `divisor` times before advancing. Clamp to avoid OOB reads.
+ size_t clampedSize = std::min(numSrcVertices * destStride * divisor, bytesToAllocate);
+
+ ASSERT(clampedSize % destStride == 0);
+ ASSERT(divisor > 0);
+
+ uint32_t sourceVertexUseCount = 0;
+ for (size_t dataCopied = 0; dataCopied < clampedSize; dataCopied += destStride, dst += destStride)
{
- vertexLoadFunction(sourceData, sourceStride, vertexCount, dst);
+ vertexLoadFunction(sourceData, sourceStride, 1, dst);
+ sourceVertexUseCount++;
+ if (sourceVertexUseCount == divisor)
+ {
+ sourceData += sourceStride;
+ sourceVertexUseCount = 0;
+ }
}
- else
+
+ // Satisfy robustness constraints (only if extension enabled)
+ if (contextVk->getExtensions().robustness)
{
- ASSERT(replicateCount > 1);
- uint32_t sourceRemainingCount = replicateCount - 1;
- for (size_t dataCopied = 0; dataCopied < bytesToAllocate;
- dataCopied += destStride, dst += destStride, sourceRemainingCount--)
+ if (clampedSize < bytesToAllocate)
{
- vertexLoadFunction(sourceData, sourceStride, 1, dst);
- if (sourceRemainingCount == 0)
- {
- sourceData += sourceStride;
- sourceRemainingCount = replicateCount;
- }
+ memset(dst + clampedSize, 0, bytesToAllocate - clampedSize);
}
}
@@ -124,6 +152,7 @@ size_t GetVertexCount(BufferVk *srcBuffer, const gl::VertexBinding &binding, uin
return 0;
// Count the last vertex. It may occupy less than a full stride.
+ // This is also correct if stride happens to be less than srcFormatSize.
size_t numVertices = 1;
bytes -= srcFormatSize;
@@ -452,8 +481,8 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
ASSERT(GetVertexInputAlignment(vertexFormat, compressed) <= vk::kVertexBufferAlignment);
ANGLE_TRY(StreamVertexData(
contextVk, &conversion->data, srcBytes, numVertices * dstFormatSize, 0, numVertices,
- binding.getStride(), srcFormatSize, vertexFormat.getVertexLoadFunction(compressed),
- &mCurrentArrayBuffers[attribIndex], &conversion->lastAllocationOffset, 1));
+ binding.getStride(), vertexFormat.getVertexLoadFunction(compressed),
+ &mCurrentArrayBuffers[attribIndex], &conversion->lastAllocationOffset));
ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
ASSERT(conversion->dirty);
@@ -808,28 +837,41 @@ angle::Result VertexArrayVk::updateStreamedAttribs(const gl::Context *context,
// Instanced attrib
if (divisor > renderer->getMaxVertexAttribDivisor())
{
- // Emulated attrib
- BufferVk *bufferVk = nullptr;
+ // Divisor will be set to 1 & so update buffer to have 1 attrib per instance
+ size_t bytesToAllocate = instanceCount * stride;
+
if (binding.getBuffer().get() != nullptr)
{
// Map buffer to expand attribs for divisor emulation
- bufferVk = vk::GetImpl(binding.getBuffer().get());
- void *buffSrc = nullptr;
+ BufferVk *bufferVk = vk::GetImpl(binding.getBuffer().get());
+ void *buffSrc = nullptr;
ANGLE_TRY(bufferVk->mapImpl(contextVk, &buffSrc));
src = reinterpret_cast<const uint8_t *>(buffSrc) + binding.getOffset();
- }
- // Divisor will be set to 1 & so update buffer to have 1 attrib per instance
- size_t bytesToAllocate = instanceCount * stride;
- ANGLE_TRY(StreamVertexData(contextVk, &mDynamicVertexData, src, bytesToAllocate, 0,
- instanceCount, binding.getStride(), stride,
- vertexFormat.vertexLoadFunction,
- &mCurrentArrayBuffers[attribIndex],
- &mCurrentArrayBufferOffsets[attribIndex], divisor));
- if (bufferVk)
- {
+ uint32_t srcAttributeSize =
+ static_cast<uint32_t>(ComputeVertexAttributeTypeSize(attrib));
+
+ size_t numVertices = GetVertexCount(bufferVk, binding, srcAttributeSize);
+
+ ANGLE_TRY(StreamVertexDataWithDivisor(
+ contextVk, &mDynamicVertexData, src, bytesToAllocate, binding.getStride(),
+ stride, vertexFormat.vertexLoadFunction,
+ &mCurrentArrayBuffers[attribIndex],
+ &mCurrentArrayBufferOffsets[attribIndex], divisor,
+ numVertices));
+
ANGLE_TRY(bufferVk->unmapImpl(contextVk));
}
+ else
+ {
+ size_t numVertices = instanceCount;
+ ANGLE_TRY(StreamVertexDataWithDivisor(
+ contextVk, &mDynamicVertexData, src, bytesToAllocate, binding.getStride(),
+ stride, vertexFormat.vertexLoadFunction,
+ &mCurrentArrayBuffers[attribIndex],
+ &mCurrentArrayBufferOffsets[attribIndex], divisor,
+ numVertices));
+ }
}
else
{
@@ -838,10 +880,10 @@ angle::Result VertexArrayVk::updateStreamedAttribs(const gl::Context *context,
size_t bytesToAllocate = count * stride;
ANGLE_TRY(StreamVertexData(contextVk, &mDynamicVertexData, src, bytesToAllocate, 0,
- count, binding.getStride(), stride,
+ count, binding.getStride(),
vertexFormat.vertexLoadFunction,
&mCurrentArrayBuffers[attribIndex],
- &mCurrentArrayBufferOffsets[attribIndex], 1));
+ &mCurrentArrayBufferOffsets[attribIndex]));
}
}
else
@@ -856,8 +898,8 @@ angle::Result VertexArrayVk::updateStreamedAttribs(const gl::Context *context,
ANGLE_TRY(StreamVertexData(
contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
- binding.getStride(), stride, vertexFormat.vertexLoadFunction,
- &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex], 1));
+ binding.getStride(), vertexFormat.vertexLoadFunction,
+ &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
}
mCurrentArrayBufferHandles[attribIndex] =
diff --git a/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp b/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp
index 08917a2de3385eb853bced1dd576aff46f34f709..db708b0a2a3ce90a370b43786af6884b2f992bef 100644
--- a/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp
+++ b/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp
@@ -564,6 +564,98 @@ TEST_P(RobustBufferAccessBehaviorTest, DynamicBuffer)
}
}
+// Tests out of bounds read by divisor emulation due to a user-provided offset.
+// Adapted from https://crbug.com/1285885.
+TEST_P(RobustBufferAccessBehaviorTest, IndexOutOfBounds)
+{
+ ANGLE_SKIP_TEST_IF(!initExtension());
+
+ constexpr char kVS[] = R"(precision highp float;
+attribute vec4 a_position;
+void main(void) {
+ gl_Position = a_position;
+})";
+
+ constexpr char kFS[] = R"(precision highp float;
+uniform sampler2D oTexture;
+uniform float oColor[3];
+void main(void) {
+ gl_FragData[0] = texture2DProj(oTexture, vec3(0.1,0.1,0.1));
+})";
+
+ GLfloat singleFloat = 1.0f;
+
+ GLBuffer buf;
+ glBindBuffer(GL_ARRAY_BUFFER, buf);
+ glBufferData(GL_ARRAY_BUFFER, 4, &singleFloat, GL_STATIC_DRAW);
+
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
+ glBindAttribLocation(program, 0, "a_position");
+ glLinkProgram(program);
+ ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
+
+ glEnableVertexAttribArray(0);
+
+ // Trying to exceed renderer->getMaxVertexAttribDivisor()
+ GLuint constexpr kDivisor = 4096;
+ glVertexAttribDivisor(0, kDivisor);
+
+ size_t outOfBoundsOffset = 0x50000000;
+ glVertexAttribPointer(0, 1, GL_FLOAT, false, 8, reinterpret_cast<void *>(outOfBoundsOffset));
+
+ glUseProgram(program);
+
+ glDrawArrays(GL_TRIANGLES, 0, 32);
+
+ // No assertions, just checking for crashes.
+}
+
+// Similar to the test above but index is first within bounds then goes out of bounds.
+TEST_P(RobustBufferAccessBehaviorTest, IndexGoingOutOfBounds)
+{
+ ANGLE_SKIP_TEST_IF(!initExtension());
+
+ constexpr char kVS[] = R"(precision highp float;
+attribute vec4 a_position;
+void main(void) {
+ gl_Position = a_position;
+})";
+
+ constexpr char kFS[] = R"(precision highp float;
+uniform sampler2D oTexture;
+uniform float oColor[3];
+void main(void) {
+ gl_FragData[0] = texture2DProj(oTexture, vec3(0.1,0.1,0.1));
+})";
+
+ GLBuffer buf;
+ glBindBuffer(GL_ARRAY_BUFFER, buf);
+ std::array<GLfloat, 2> buffer = {{0.2f, 0.2f}};
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * buffer.size(), buffer.data(), GL_STATIC_DRAW);
+
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
+ glBindAttribLocation(program, 0, "a_position");
+ glLinkProgram(program);
+ ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
+
+ glEnableVertexAttribArray(0);
+
+ // Trying to exceed renderer->getMaxVertexAttribDivisor()
+ GLuint constexpr kDivisor = 4096;
+ glVertexAttribDivisor(0, kDivisor);
+
+ // 6 bytes remaining in the buffer from offset so only a single vertex can be read
+ glVertexAttribPointer(0, 1, GL_FLOAT, false, 8, reinterpret_cast<void *>(2));
+
+ glUseProgram(program);
+
+ // Each vertex is read `kDivisor` times so the last read goes out of bounds
+ GLsizei instanceCount = kDivisor + 1;
+ glDrawArraysInstanced(GL_TRIANGLES, 0, 32, instanceCount);
+
+ // No assertions, just checking for crashes.
+}
+
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31(RobustBufferAccessBehaviorTest);
} // namespace

View File

@@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charlie Lao <cclao@google.com>
Date: Mon, 7 Feb 2022 15:08:15 -0800
Subject: M99: Vulkan: StreamVertexDataWithDivisor write beyond buffer boundary
StreamVertexDataWithDivisor() function is advancing dst with dstStride,
but then later on it is treating dst as if it never advanced, thus
result in write out of buffer boundary. This was hidden by VMA's memory
suballocation, which means it may result in some rendering artifacts.
Bug: angleproject:6990
Change-Id: Ic91e917cedd247dfe85b12a69ae26b21b7a4e67a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3445528
Reviewed-by: Roman Lavrov <romanl@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Charlie Lao <cclao@google.com>
(cherry picked from commit 5204587698099207ce8ae70779ef44ffae877996)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3461417
Reviewed-by: Charlie Lao <cclao@google.com>
Commit-Queue: Roman Lavrov <romanl@google.com>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 1ca486af3ff004e11aea82c391b4c504b569096c..93378c4b24495872405fc06ea01e15254229ab63 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -120,7 +120,7 @@ angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
ASSERT(divisor > 0);
uint32_t sourceVertexUseCount = 0;
- for (size_t dataCopied = 0; dataCopied < clampedSize; dataCopied += destStride, dst += destStride)
+ for (size_t dataCopied = 0; dataCopied < clampedSize; dataCopied += destStride)
{
vertexLoadFunction(sourceData, sourceStride, 1, dst);
sourceVertexUseCount++;
@@ -129,6 +129,7 @@ angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
sourceData += sourceStride;
sourceVertexUseCount = 0;
}
+ dst += destStride;
}
// Satisfy robustness constraints (only if extension enabled)
@@ -136,7 +137,7 @@ angle::Result StreamVertexDataWithDivisor(ContextVk *contextVk,
{
if (clampedSize < bytesToAllocate)
{
- memset(dst + clampedSize, 0, bytesToAllocate - clampedSize);
+ memset(dst, 0, bytesToAllocate - clampedSize);
}
}

View File

@@ -0,0 +1,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peng Huang <penghuang@chromium.org>
Date: Mon, 25 Oct 2021 15:45:36 -0400
Subject: VANGLE: change the default vulkan device choose logic
To match the vulkan device choose logic in chrome, ANGLE will choose
the default device based on the order of (discret GPU > integrated GPU
> other GPU)
TODO: for long term, ANGLE should provide a way to let chrome specify
the physical device.
Bug: chromium:1260869
Change-Id: Id023138485eb65fcc1d2758103d59a4e6cb2a51d
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3242963
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
diff --git a/src/common/vulkan/vulkan_icd.cpp b/src/common/vulkan/vulkan_icd.cpp
index 0ed7ae2aa058792b700503dfdb6fd91b05bf68fb..df14f5f674b37c49332e43ccba8f1782cb13f495 100644
--- a/src/common/vulkan/vulkan_icd.cpp
+++ b/src/common/vulkan/vulkan_icd.cpp
@@ -11,6 +11,7 @@
#include <functional>
#include <vector>
+#include "common/Optional.h"
#include "common/bitset_utils.h"
#include "common/debug.h"
#include "common/system_utils.h"
@@ -94,8 +95,7 @@ ICDFilterFunc GetFilterForICD(vk::ICD preferredICD)
const std::string anglePreferredDevice =
angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
return [anglePreferredDevice](const VkPhysicalDeviceProperties &deviceProperties) {
- return (anglePreferredDevice.empty() ||
- anglePreferredDevice == deviceProperties.deviceName);
+ return (anglePreferredDevice == deviceProperties.deviceName);
};
}
}
@@ -262,9 +262,37 @@ void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
return;
}
}
- WARN() << "Preferred device ICD not found. Using default physicalDevice instead.";
- // Fall back to first device.
+ Optional<VkPhysicalDevice> integratedDevice;
+ VkPhysicalDeviceProperties integratedDeviceProperties;
+ for (const VkPhysicalDevice &physicalDevice : physicalDevices)
+ {
+ vkGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
+ // If discrete GPU exists, uses it by default.
+ if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
+ {
+ *physicalDeviceOut = physicalDevice;
+ return;
+ }
+ if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
+ !integratedDevice.valid())
+ {
+ integratedDevice = physicalDevice;
+ integratedDeviceProperties = *physicalDevicePropertiesOut;
+ continue;
+ }
+ }
+
+ // If only integrated GPU exists, use it by default.
+ if (integratedDevice.valid())
+ {
+ *physicalDeviceOut = integratedDevice.value();
+ *physicalDevicePropertiesOut = integratedDeviceProperties;
+ return;
+ }
+
+ WARN() << "Preferred device ICD not found. Using default physicalDevice instead.";
+ // Fallback to the first device.
*physicalDeviceOut = physicalDevices[0];
vkGetPhysicalDeviceProperties(*physicalDeviceOut, physicalDevicePropertiesOut);
}

View File

@@ -132,3 +132,53 @@ m96_fileapi_move_origin_checks_in_bloburlstore_sooner.patch
cherry-pick-f781748dcb3c.patch
cherry-pick-c5571653d932.patch
fix_crash_when_saving_edited_pdf_files.patch
use_axnodeid_rather_than_axnode_in_axeventgenerator_tree_events.patch
mojo_reject_addbrokerclient_on_non-broker_nodes.patch
cherry-pick-1277917.patch
cherry-pick-1281979.patch
cherry-pick-1282354.patch
cherry-pick-1283198.patch
cherry-pick-1283375.patch
cherry-pick-1283371.patch
cherry-pick-9db9911e1242.patch
cherry-pick-1284367.patch
m97_webcodecs_various_decodertemplate_shutdown_cleanups.patch
96_take_local_copy_of_ump_local_sources_to_iterate.patch
pin_scrolltop_to_0_during_autofill_preview.patch
fix_preview_state_detection.patch
do_not_select_vulkan_device_based_on_the_passed_in_gpu_info_on_linux.patch
handle_potentiallydanglingmarkup_for_cssimagevalue.patch
fire_iframe_onload_for_cross-origin-initiated_same-document.patch
merge_m-97_serial_check_for_detached_buffers_when_writing.patch
cleanup_pausablecriptexecutor_usage.patch
m98_fs_fix_fileutil_lifetime_issue.patch
cherry-pick-be50c60b4225.patch
cherry-pick-ebc188ad769e.patch
cherry-pick-e3805f29fed7.patch
cherry-pick-0081bb347e67.patch
cherry-pick-62142d222a80.patch
cherry-pick-1887414c016d.patch
cherry-pick-6b2643846ae3.patch
cherry-pick-905302eb3a2b.patch
cherry-pick-246c10dede97.patch
fix_imagebitmaprenderingcontext_interaction_with_software_compositor.patch
remove_incorrect_width_height_adjustments.patch
fix_non-client_mouse_tracking_and_message_bubbling_on_windows.patch
fixed_terminate_caused_by_binding_to_wrong_version.patch
follow_wayland_specification_regarding_xkb_keymap.patch
cherry-pick-1665a1d16d46.patch
cherry-pick-4d26949260aa.patch
use-after-free_of_id_and_idref_attributes.patch
fix_--without-valid_build.patch
usb_fix_oob_access_with_non-sequential_interfaces.patch
skia_renderer_-_don_t_explicitly_clip_scissor_for_large_transforms.patch
skia_renderer_use_rectf_intersect_in_applyscissor.patch
cherry-pick-1a31e2110440.patch
m100_change_ownership_of_blobbytesprovider.patch
cherry-pick-5be8e065f43e.patch
m96-lts_add_bounds_check_to_webgpudecoderimpl_dorequestdevice.patch
cherry-pick-5ff02e4d7368.patch
cherry-pick-12ba78f3fa7a.patch
reland_fix_noopener_case_for_user_activation_consumption.patch
cherry-pick-99c3f3bfd507.patch
cherry-pick-ec0cce63f47d.patch

View File

@@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tony Herre <toprice@chromium.org>
Date: Tue, 14 Dec 2021 16:35:05 +0000
Subject: Take local copy of UMP::local_sources to iterate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Take a local copy of UserMediaProcessor::local_sources_ when iterating
over it in UserMediaProcessor::DetermineExistingAudioSessionId, as the
list can be effectively concurrently modified during destruction of
MediaStreamTracks triggered by GC during this loop. Without the copy
this leads to a container overflow.
(cherry picked from commit fb6232ffb1fec14d64ec8815f7dfc2cea0887588)
Bug: 1238209
Change-Id: I048387a51a58eacff87d220e6b67d2d09f610c1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3320283
Reviewed-by: Henrik Boström <hbos@chromium.org>
Commit-Queue: Tony Herre <toprice@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#950499}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3337896
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/branch-heads/4664@{#1303}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
index d42b3d7309ce40e74ebf386f4d38eb8cce008ec0..b0b8b15657210174b000a02f711a76fa16e5948d 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -725,6 +725,7 @@ void UserMediaProcessor::SelectAudioSettings(
absl::optional<base::UnguessableToken>
UserMediaProcessor::DetermineExistingAudioSessionId() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_->request()->Audio());
auto settings = current_request_info_->audio_capture_settings();
@@ -733,7 +734,12 @@ UserMediaProcessor::DetermineExistingAudioSessionId() {
// Create a copy of the MediaStreamSource objects that are
// associated to the same audio device capture based on its device ID.
HeapVector<Member<MediaStreamSource>> matching_sources;
- for (const auto& source : local_sources_) {
+
+ // Take a defensive copy, as local_sources_ can be modified during
+ // destructions in GC runs triggered by the push_back allocation in this loop.
+ // crbug.com/1238209
+ HeapVector<Member<MediaStreamSource>> local_sources_copy = local_sources_;
+ for (const auto& source : local_sources_copy) {
MediaStreamSource* source_copy = source;
if (source_copy->GetType() == MediaStreamSource::kTypeAudio &&
source_copy->Id().Utf8() == device_id) {

View File

@@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matt Reynolds <mattreynolds@google.com>
Date: Wed, 19 Jan 2022 21:03:08 +0000
Subject: gamepad: Return an invalid handle after ReportBadMessage
Bug: 1285449
Change-Id: I746c539577f7bdf69cbe4212ac380e0c92a5c771
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3373944
Auto-Submit: Matt Reynolds <mattreynolds@chromium.org>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#961125}
diff --git a/device/gamepad/gamepad_monitor.cc b/device/gamepad/gamepad_monitor.cc
index ce8ba1ef7551e52f8ae4d9a112a08308ab2ce51c..28082924e632a895fc5bc4725bc6de3d6ca120ac 100644
--- a/device/gamepad/gamepad_monitor.cc
+++ b/device/gamepad/gamepad_monitor.cc
@@ -53,6 +53,8 @@ void GamepadMonitor::GamepadStartPolling(GamepadStartPollingCallback callback) {
GamepadService* service = GamepadService::GetInstance();
if (!service->ConsumerBecameActive(this)) {
mojo::ReportBadMessage("GamepadMonitor::GamepadStartPolling failed");
+ std::move(callback).Run(base::ReadOnlySharedMemoryRegion());
+ return;
}
std::move(callback).Run(service->DuplicateSharedMemoryRegion());
}

View File

@@ -0,0 +1,176 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Simon Pelchat <spelchat@chromium.org>
Date: Fri, 7 Jan 2022 20:00:37 +0000
Subject: Avoid UAF on StreamingSearchPrefetchURLLoader.
StreamingSearchPrefetchURLLoader::OnDataAvailable used to "delete this",
which results in deleting the DataPipeDrainer, which will then be used
once OnDataAvailable returns. Instead, we post a task to delete the
URL loader later on.
Bug: 1277917
Change-Id: I8d78c73a01fff0315b96ccb0e7fe605884b99823
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3365387
Reviewed-by: Max Curran <curranmax@chromium.org>
Reviewed-by: Robert Ogden <robertogden@chromium.org>
Commit-Queue: Simon Pelchat <spelchat@chromium.org>
Cr-Commit-Position: refs/heads/main@{#956628}
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc
index 1d3d1ea93c026d371a6ad5678e8ff37dc58f8423..e3eaad96fbada18211f295988c07d218ab67921f 100644
--- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc
+++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h"
#include "chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h"
+#include "streaming_search_prefetch_request.h"
StreamingSearchPrefetchRequest::StreamingSearchPrefetchRequest(
const GURL& prefetch_url,
@@ -19,7 +20,9 @@ void StreamingSearchPrefetchRequest::StartPrefetchRequestInternal(
std::unique_ptr<network::ResourceRequest> resource_request,
const net::NetworkTrafficAnnotationTag& network_traffic_annotation) {
streaming_url_loader_ = std::make_unique<StreamingSearchPrefetchURLLoader>(
- this, profile, std::move(resource_request), network_traffic_annotation);
+ this, profile, std::move(resource_request), network_traffic_annotation,
+ base::BindOnce(&StreamingSearchPrefetchRequest::StopPrefetch,
+ weak_factory_.GetWeakPtr()));
}
std::unique_ptr<SearchPrefetchURLLoader>
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h
index ff051c61e9cbed67d5cffbcac007d6c12a26cc76..ad75d404abe9e743d079725ffd8b01d3a49ae017 100644
--- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h
+++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_request.h
@@ -47,6 +47,8 @@ class StreamingSearchPrefetchRequest : public BaseSearchPrefetchRequest {
private:
// The ongoing prefetch request. Null before and after the fetch.
std::unique_ptr<StreamingSearchPrefetchURLLoader> streaming_url_loader_;
+
+ base::WeakPtrFactory<StreamingSearchPrefetchRequest> weak_factory_{this};
};
#endif // CHROME_BROWSER_PREFETCH_SEARCH_PREFETCH_STREAMING_SEARCH_PREFETCH_REQUEST_H_
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
index 07f4e5cd7f0adde63861962a78cdac0de43591b0..8d9009c42cdde766e105b02827a539a4477ea58e 100644
--- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
+++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
@@ -26,15 +26,18 @@
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
+#include "streaming_search_prefetch_url_loader.h"
#include "url/gurl.h"
StreamingSearchPrefetchURLLoader::StreamingSearchPrefetchURLLoader(
StreamingSearchPrefetchRequest* streaming_prefetch_request,
Profile* profile,
std::unique_ptr<network::ResourceRequest> resource_request,
- const net::NetworkTrafficAnnotationTag& network_traffic_annotation)
+ const net::NetworkTrafficAnnotationTag& network_traffic_annotation,
+ base::OnceClosure stop_prefetch_closure)
: resource_request_(std::move(resource_request)),
- streaming_prefetch_request_(streaming_prefetch_request) {
+ streaming_prefetch_request_(streaming_prefetch_request),
+ stop_prefetch_closure_(std::move(stop_prefetch_closure)) {
DCHECK(streaming_prefetch_request_);
auto url_loader_factory = profile->GetDefaultStoragePartition()
->GetURLLoaderFactoryForBrowserProcess();
@@ -126,7 +129,7 @@ void StreamingSearchPrefetchURLLoader::OnReceiveRedirect(
if (streaming_prefetch_request_) {
streaming_prefetch_request_->ErrorEncountered();
} else {
- delete this;
+ PostTaskToStopPrefetchAndDeleteSelf();
}
}
@@ -209,7 +212,7 @@ void StreamingSearchPrefetchURLLoader::OnStartLoadingResponseBodyFromData() {
mojo::CreateDataPipe(&options, producer_handle_, consumer_handle);
if (rv != MOJO_RESULT_OK) {
- delete this;
+ PostTaskToStopPrefetchAndDeleteSelf();
return;
}
@@ -231,7 +234,7 @@ void StreamingSearchPrefetchURLLoader::OnHandleReady(
MojoResult result,
const mojo::HandleSignalsState& state) {
if (result != MOJO_RESULT_OK) {
- delete this;
+ PostTaskToStopPrefetchAndDeleteSelf();
return;
}
PushData();
@@ -257,7 +260,7 @@ void StreamingSearchPrefetchURLLoader::PushData() {
}
if (result != MOJO_RESULT_OK) {
- delete this;
+ PostTaskToStopPrefetchAndDeleteSelf();
return;
}
@@ -344,16 +347,24 @@ void StreamingSearchPrefetchURLLoader::OnURLLoaderMojoDisconnect() {
DCHECK(streaming_prefetch_request_);
streaming_prefetch_request_->ErrorEncountered();
} else {
- delete this;
+ PostTaskToStopPrefetchAndDeleteSelf();
}
}
void StreamingSearchPrefetchURLLoader::OnURLLoaderClientMojoDisconnect() {
DCHECK(forwarding_client_);
DCHECK(!streaming_prefetch_request_);
- delete this;
+ PostTaskToStopPrefetchAndDeleteSelf();
}
void StreamingSearchPrefetchURLLoader::ClearOwnerPointer() {
streaming_prefetch_request_ = nullptr;
}
+
+void StreamingSearchPrefetchURLLoader::PostTaskToStopPrefetchAndDeleteSelf() {
+ // To avoid UAF bugs, post a separate task to delete this object.
+ if (stop_prefetch_closure_) {
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, std::move(stop_prefetch_closure_));
+ }
+}
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h
index 2213fb079e3f29566d67030dd2fa399ce11024e2..ed225db0b4d2b0d24aae967f320a7010c1a45044 100644
--- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h
+++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h
@@ -39,7 +39,8 @@ class StreamingSearchPrefetchURLLoader : public network::mojom::URLLoader,
StreamingSearchPrefetchRequest* streaming_prefetch_request,
Profile* profile,
std::unique_ptr<network::ResourceRequest> resource_request,
- const net::NetworkTrafficAnnotationTag& network_traffic_annotation);
+ const net::NetworkTrafficAnnotationTag& network_traffic_annotation,
+ base::OnceClosure stop_prefetch_closure);
~StreamingSearchPrefetchURLLoader() override;
@@ -105,6 +106,9 @@ class StreamingSearchPrefetchURLLoader : public network::mojom::URLLoader,
// Clears |producer_handle_| and |handle_watcher_|.
void Finish();
+ // Post a task to delete this object by running stop_prefetch_closure_.
+ void PostTaskToStopPrefetchAndDeleteSelf();
+
// Sets up mojo forwarding to the navigation path. Resumes
// |network_url_loader_| calls. Serves the start of the response to the
// navigation path. After this method is called, |this| manages its own
@@ -164,6 +168,9 @@ class StreamingSearchPrefetchURLLoader : public network::mojom::URLLoader,
mojo::ScopedDataPipeProducerHandle producer_handle_;
std::unique_ptr<mojo::SimpleWatcher> handle_watcher_;
+ // Closure to cancel this prefetch. Running this callback will destroy |this|.
+ base::OnceClosure stop_prefetch_closure_;
+
base::WeakPtrFactory<StreamingSearchPrefetchURLLoader> weak_factory_{this};
};

View File

@@ -0,0 +1,157 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etienne Bergeron <etienneb@chromium.org>
Date: Wed, 5 Jan 2022 23:37:26 +0000
Subject: Fix race condition while initializing GPU Watchdog
This CL is fixing a race condition detected by TSAN.
see: crbug/1281979
The race condition is between these two functions:
base::PowerMonitor::IsInitialized() and
base::PowerMonitor::Initialize(...)
The power monitor doesn't need to be initialized to add
observers. In fact, the power monitor initialization
is for plugging a power monitor source. Observers can be
safely added/removed.
R=fdoray@chromium.org
Bug: 1281979
Change-Id: Icaecd877d4b0cf5e79d7fe6a096f9d76d932b076
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3367395
Reviewed-by: Maggie Chen <magchen@chromium.org>
Commit-Queue: Etienne Bergeron <etienneb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#955944}
diff --git a/gpu/ipc/service/gpu_watchdog_thread.cc b/gpu/ipc/service/gpu_watchdog_thread.cc
index ecf8e17ce4183bfe2f22a9a6d666a60828f078a2..c518f978e602eda3cfa150bd8e9e07f7f7fc749b 100644
--- a/gpu/ipc/service/gpu_watchdog_thread.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread.cc
@@ -36,9 +36,6 @@
#endif
namespace gpu {
-namespace {
-constexpr int64_t kDelayForAddPowerObserverInMs = 50;
-}
base::TimeDelta GetGpuWatchdogTimeout() {
std::string timeout_str =
@@ -176,14 +173,11 @@ void GpuWatchdogThread::OnInitComplete() {
base::Unretained(this)));
Disarm();
- // Use a delayed task for AddPowerObserver. The PowerMonitor is initialized in
- // ChildThreadImpl::Init right after GpuInit::InitializeAndStartSandbox which
- // calls OnInitComplete() at the end if no errors.
- task_runner()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&GpuWatchdogThread::AddPowerObserver,
- base::Unretained(this)),
- base::TimeDelta::FromMilliseconds(kDelayForAddPowerObserverInMs));
+ // The PowerMonitorObserver needs to be register on the watchdog thread so the
+ // notifications are delivered on that thread.
+ task_runner()->PostTask(FROM_HERE,
+ base::BindOnce(&GpuWatchdogThread::AddPowerObserver,
+ base::Unretained(this)));
}
// Called from the gpu thread in viz::GpuServiceImpl::~GpuServiceImpl().
@@ -296,26 +290,12 @@ void GpuWatchdogThread::OnResume() {
void GpuWatchdogThread::AddPowerObserver() {
DCHECK(watchdog_thread_task_runner_->BelongsToCurrentThread());
- // The Observer can only be added after the power monitor is initialized.
- // When this function is called, PowerMonitor is probably ready.
- if (base::PowerMonitor::IsInitialized()) {
- bool is_system_suspended =
- base::PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(
- this);
- if (is_system_suspended) {
- StopWatchdogTimeoutTask(kPowerSuspendResume);
- }
-
- is_power_observer_added_ = true;
- } else {
- // Just in case PowerMonitor is not ready.
- // It usually takes hundreds of milliseconds to finish the whole GPU
- // initialization. Try again in 100 ms.
- task_runner()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&GpuWatchdogThread::AddPowerObserver, weak_ptr_),
- base::TimeDelta::FromMilliseconds(100));
- }
+ // Adding the Observer to the power monitor is safe even if power monitor is
+ // not yet initialized.
+ bool is_system_suspended =
+ base::PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(this);
+ if (is_system_suspended)
+ StopWatchdogTimeoutTask(kPowerSuspendResume);
}
// Running on the watchdog thread.
@@ -638,7 +618,6 @@ void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() {
base::debug::Alias(&in_power_suspension_);
base::debug::Alias(&in_gpu_process_teardown_);
base::debug::Alias(&is_backgrounded_);
- base::debug::Alias(&is_power_observer_added_);
base::debug::Alias(&last_on_watchdog_timeout_timeticks_);
base::TimeDelta timeticks_elapses =
function_begin_timeticks - last_on_watchdog_timeout_timeticks_;
@@ -843,17 +822,4 @@ bool GpuWatchdogThread::IsGpuHangDetectedForTesting() {
return test_result_timeout_and_gpu_hang_.IsSet();
}
-// This should be called on the test main thread only. It will wait until the
-// power observer is added on the watchdog thread.
-void GpuWatchdogThread::WaitForPowerObserverAddedForTesting() {
- DCHECK(watched_gpu_task_runner_->BelongsToCurrentThread());
-
- base::WaitableEvent event;
- task_runner()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)),
- base::TimeDelta::FromMilliseconds(kDelayForAddPowerObserverInMs));
- event.Wait();
-}
-
} // namespace gpu
diff --git a/gpu/ipc/service/gpu_watchdog_thread.h b/gpu/ipc/service/gpu_watchdog_thread.h
index d0d20dfc7c9fd7e13896e212673519ec5233c562..622647a68ee2bc2e3d18e58bbcfb3c7f90b3102c 100644
--- a/gpu/ipc/service/gpu_watchdog_thread.h
+++ b/gpu/ipc/service/gpu_watchdog_thread.h
@@ -121,8 +121,6 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread
// For gpu testing only. Return status for the watchdog tests
bool IsGpuHangDetectedForTesting();
- void WaitForPowerObserverAddedForTesting();
-
// Implements base::Thread.
void Init() override;
void CleanUp() override;
@@ -291,10 +289,6 @@ class GPU_IPC_SERVICE_EXPORT GpuWatchdogThread
// The GPU watchdog is paused. The timeout task is temporarily stopped.
bool is_paused_ = false;
- // Whether the watchdog thread has added the power monitor observer.
- // Read/Write by the watchdog thread only.
- bool is_power_observer_added_ = false;
-
// whether GpuWatchdogThreadEvent::kGpuWatchdogStart has been recorded.
bool is_watchdog_start_histogram_recorded = false;
diff --git a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
index ca2006a45dd87bad106b0f75bfe8475fa1090038..b44cdd7e22686ab37c57461291676f01512fd623 100644
--- a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
@@ -81,9 +81,6 @@ void GpuWatchdogPowerTest::SetUp() {
// Report GPU init complete.
watchdog_thread_->OnInitComplete();
-
- // Wait until the power observer is added on the watchdog thread
- watchdog_thread_->WaitForPowerObserverAddedForTesting();
}
void GpuWatchdogPowerTest::TearDown() {

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Bookholt <bookholt@chromium.org>
Date: Tue, 11 Jan 2022 00:33:53 +0000
Subject: ServiceWorkerContainerHost::EnsureFileAccess: abort request
processing if the requesting process lacks file access
Bug: 1282354
Change-Id: Ia37ef5b97eedb0d2ad25ffe2869844a40e5be862
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3379268
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Commit-Queue: Chris Bookholt <bookholt@chromium.org>
Cr-Commit-Position: refs/heads/main@{#957344}
diff --git a/content/browser/service_worker/service_worker_container_host.cc b/content/browser/service_worker/service_worker_container_host.cc
index 82498632c53883b5d84fb0a2e5246c98e71ef00d..f13416b0cd611ddcf18053f7a543a9a423635227 100644
--- a/content/browser/service_worker/service_worker_container_host.cc
+++ b/content/browser/service_worker/service_worker_container_host.cc
@@ -379,10 +379,12 @@ void ServiceWorkerContainerHost::EnsureFileAccess(
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
for (const auto& file : file_paths) {
- if (!policy->CanReadFile(process_id_, file))
+ if (!policy->CanReadFile(process_id_, file)) {
mojo::ReportBadMessage(
"The renderer doesn't have access to the file "
"but it tried to grant access to the controller.");
+ return;
+ }
if (!policy->CanReadFile(controller_process_id, file))
policy->GrantReadFile(controller_process_id, file);

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Hosseinian <dhoss@chromium.org>
Date: Thu, 30 Dec 2021 05:08:29 +0000
Subject: CHECK page on thumbnail requests
Elevate DCHECK to CHECK.
Fixed: 1283198
Change-Id: Iacb3da961cfb44f94f7a377e225270a57809ef9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3361538
Auto-Submit: Daniel Hosseinian <dhoss@chromium.org>
Reviewed-by: K. Moon <kmoon@chromium.org>
Commit-Queue: K. Moon <kmoon@chromium.org>
Cr-Commit-Position: refs/heads/main@{#954552}
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index 341b183948b15f72edca6f8620c5039593d16a90..2b128d8fdde8048c1f8b92ec2e38f485feca2bf4 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -4273,7 +4273,7 @@ void PDFiumEngine::SetLinkUnderCursorForAnnotation(FPDF_ANNOTATION annot,
void PDFiumEngine::RequestThumbnail(int page_index,
float device_pixel_ratio,
SendThumbnailCallback send_callback) {
- DCHECK(PageIndexInBounds(page_index));
+ CHECK(PageIndexInBounds(page_index));
// Thumbnails cannot be generated in the middle of a progressive paint of a
// page. Generate the thumbnail immediately only if the page is not currently

View File

@@ -0,0 +1,138 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Clark DuVall <cduvall@chromium.org>
Date: Thu, 6 Jan 2022 01:21:21 +0000
Subject: Fix lifetime bug in PrefetchURLLoader
PrefetchURLLoader is now owned by PrefetchURLLoaderService, which is no
longer refcounted. This makes the lifetime much easier to reason about.
Bug: 1283371
Change-Id: Iaa58c1f44cc9f066459ce344012f57faca533197
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3361198
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Reviewed-by: Kunihiko Sakamoto <ksakamoto@chromium.org>
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/heads/main@{#955986}
diff --git a/content/browser/loader/prefetch_url_loader_service.cc b/content/browser/loader/prefetch_url_loader_service.cc
index 5211d5552d6b2e1c1967d7dd6c6079001fef6895..345bf021541a121ea183ba16fa7ed76373f0dfd1 100644
--- a/content/browser/loader/prefetch_url_loader_service.cc
+++ b/content/browser/loader/prefetch_url_loader_service.cc
@@ -202,29 +202,25 @@ void PrefetchURLLoaderService::CreateLoaderAndStart(
->prefetched_signed_exchange_cache;
}
- // For now we make self owned receiver for the loader to the request, while we
- // can also possibly make the new loader owned by the factory so that they can
- // live longer than the client (i.e. run in detached mode).
- // TODO(kinuko): Revisit this.
- mojo::MakeSelfOwnedReceiver(
- std::make_unique<PrefetchURLLoader>(
- request_id, options, current_context.frame_tree_node_id,
- resource_request,
- resource_request.trusted_params
- ? resource_request.trusted_params->isolation_info
- .network_isolation_key()
- : current_context.render_frame_host->GetNetworkIsolationKey(),
- std::move(client), traffic_annotation,
- std::move(network_loader_factory_to_use),
- base::BindRepeating(
- &PrefetchURLLoaderService::CreateURLLoaderThrottles, this,
- resource_request, current_context.frame_tree_node_id),
- browser_context_, signed_exchange_prefetch_metric_recorder_,
- std::move(prefetched_signed_exchange_cache), accept_langs_,
- base::BindOnce(
- &PrefetchURLLoaderService::GenerateRecursivePrefetchToken, this,
- current_context.weak_ptr_factory.GetWeakPtr())),
- std::move(receiver));
+ // base::Unretained is safe here since |this| owns the loader.
+ auto loader = std::make_unique<PrefetchURLLoader>(
+ request_id, options, current_context.frame_tree_node_id, resource_request,
+ resource_request.trusted_params
+ ? resource_request.trusted_params->isolation_info
+ .network_isolation_key()
+ : current_context.render_frame_host->GetNetworkIsolationKey(),
+ std::move(client), traffic_annotation,
+ std::move(network_loader_factory_to_use),
+ base::BindRepeating(&PrefetchURLLoaderService::CreateURLLoaderThrottles,
+ base::Unretained(this), resource_request,
+ current_context.frame_tree_node_id),
+ browser_context_, signed_exchange_prefetch_metric_recorder_,
+ std::move(prefetched_signed_exchange_cache), accept_langs_,
+ base::BindOnce(&PrefetchURLLoaderService::GenerateRecursivePrefetchToken,
+ base::Unretained(this),
+ current_context.weak_ptr_factory.GetWeakPtr()));
+ auto* raw_loader = loader.get();
+ prefetch_receivers_.Add(raw_loader, std::move(receiver), std::move(loader));
}
PrefetchURLLoaderService::~PrefetchURLLoaderService() = default;
diff --git a/content/browser/loader/prefetch_url_loader_service.h b/content/browser/loader/prefetch_url_loader_service.h
index 210794966c8d25947f3e6b490538c1f851d80d52..c5fff844f73deaf2912716de9cf97547c498e4e5 100644
--- a/content/browser/loader/prefetch_url_loader_service.h
+++ b/content/browser/loader/prefetch_url_loader_service.h
@@ -35,13 +35,11 @@ class URLLoaderFactoryGetter;
// prefetches. The renderer uses it for prefetch requests including <link
// rel="prefetch">.
class CONTENT_EXPORT PrefetchURLLoaderService final
- : public base::RefCountedThreadSafe<
- PrefetchURLLoaderService,
- content::BrowserThread::DeleteOnUIThread>,
- public blink::mojom::RendererPreferenceWatcher,
+ : public blink::mojom::RendererPreferenceWatcher,
public network::mojom::URLLoaderFactory {
public:
explicit PrefetchURLLoaderService(BrowserContext* browser_context);
+ ~PrefetchURLLoaderService() override;
void GetFactory(
mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
@@ -67,12 +65,8 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
}
private:
- friend class base::DeleteHelper<content::PrefetchURLLoaderService>;
- friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
struct BindContext;
- ~PrefetchURLLoaderService() override;
-
// network::mojom::URLLoaderFactory:
void CreateLoaderAndStart(
mojo::PendingReceiver<network::mojom::URLLoader> receiver,
@@ -114,6 +108,9 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
mojo::ReceiverSet<network::mojom::URLLoaderFactory,
std::unique_ptr<BindContext>>
loader_factory_receivers_;
+ mojo::ReceiverSet<network::mojom::URLLoader,
+ std::unique_ptr<network::mojom::URLLoader>>
+ prefetch_receivers_;
// Used in the IO thread.
mojo::Receiver<blink::mojom::RendererPreferenceWatcher>
preference_watcher_receiver_{this};
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index ae284e031a6e051bda49258d54a2e62332773c70..e9af32dd2dc6ae75ded55b1ffd3fe7881408eefc 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -1321,7 +1321,7 @@ void StoragePartitionImpl::Initialize(
blob_context, filesystem_context_, fallback_blob_registry);
prefetch_url_loader_service_ =
- base::MakeRefCounted<PrefetchURLLoaderService>(browser_context_);
+ std::make_unique<PrefetchURLLoaderService>(browser_context_);
cookie_store_manager_ =
std::make_unique<CookieStoreManager>(service_worker_context_);
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 6f3a482ae16e88271768a3f91c633201f435e271..02209f615202a987d83e72895b0782cac8a8fccd 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -552,7 +552,7 @@ class CONTENT_EXPORT StoragePartitionImpl
std::unique_ptr<BroadcastChannelProvider> broadcast_channel_provider_;
std::unique_ptr<BluetoothAllowedDevicesMap> bluetooth_allowed_devices_map_;
scoped_refptr<BlobRegistryWrapper> blob_registry_;
- scoped_refptr<PrefetchURLLoaderService> prefetch_url_loader_service_;
+ std::unique_ptr<PrefetchURLLoaderService> prefetch_url_loader_service_;
std::unique_ptr<CookieStoreManager> cookie_store_manager_;
scoped_refptr<BucketContext> bucket_context_;
scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context_;

View File

@@ -0,0 +1,74 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alan Screen <awscreen@chromium.org>
Date: Fri, 7 Jan 2022 09:38:01 +0000
Subject: Ensure valid print render host before proceeding to print.
Bug: 1283375
Change-Id: I5691fc2a9d09040e777aafd0061b957025643b8a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3369086
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Alan Screen <awscreen@chromium.org>
Cr-Commit-Position: refs/heads/main@{#956443}
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc
index 4662db344afb08574b7ac7d96cb72c71edc802af..c7535ddd5b54ae33fe6f6aea09b6b313ba38b840 100644
--- a/chrome/browser/printing/print_view_manager.cc
+++ b/chrome/browser/printing/print_view_manager.cc
@@ -111,6 +111,11 @@ bool PrintViewManager::PrintForSystemDialogNow(
on_print_dialog_shown_callback_ = std::move(dialog_shown_callback);
is_switching_to_system_dialog_ = true;
+ // Remember the ID for `print_preview_rfh_`, to enable checking that the
+ // `RenderFrameHost` is still valid after a possible inner message loop runs
+ // in `DisconnectFromCurrentPrintJob()`.
+ content::GlobalRenderFrameHostId rfh_id = print_preview_rfh_->GetGlobalId();
+
auto weak_this = weak_factory_.GetWeakPtr();
DisconnectFromCurrentPrintJob();
if (!weak_this)
@@ -120,6 +125,10 @@ bool PrintViewManager::PrintForSystemDialogNow(
if (IsCrashed())
return false;
+ // Don't print if `print_preview_rfh_` is no longer live.
+ if (!content::RenderFrameHost::FromID(rfh_id))
+ return false;
+
// TODO(crbug.com/809738) Register with `PrintBackendServiceManager` when
// system print is enabled out-of-process.
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 143ee383668965ba04da092e3445fc9f4a33a433..055d97cb63cb5a1b64ee0a113ec27b664113aba9 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -39,6 +39,7 @@
#include "components/services/print_compositor/public/cpp/print_service_mojo_types.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
@@ -365,6 +366,11 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
bool silent,
base::Value settings,
CompletionCallback callback) {
+ // Remember the ID for `rfh`, to enable checking that the `RenderFrameHost`
+ // is still valid after a possible inner message loop runs in
+ // `DisconnectFromCurrentPrintJob()`.
+ content::GlobalRenderFrameHostId rfh_id = rfh->GetGlobalId();
+
auto weak_this = weak_ptr_factory_.GetWeakPtr();
DisconnectFromCurrentPrintJob();
if (!weak_this)
@@ -374,6 +380,10 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
if (IsCrashed())
return false;
+ // Don't print if `rfh` is no longer live.
+ if (!content::RenderFrameHost::FromID(rfh_id))
+ return false;
+
// TODO(crbug.com/809738) Register with `PrintBackendServiceManager` when
// system print is enabled out-of-process. A corresponding unregister should
// go in `ReleasePrintJob()`.

View File

@@ -0,0 +1,188 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xinghui Lu <xinghuilu@chromium.org>
Date: Thu, 6 Jan 2022 08:36:45 +0000
Subject: Use RFH global id to ensure the RFH is valid.
Observing via RenderFrameDeleted and RenderFrameHostChanged is not
sufficient for validating the RFH is still valid, because the frames
can belong to inner WebContents. As suggested in
https://crrev.com/c/2449389, storing a GlobalFrameRoutingId is the
preferred method of keeping a reference to a RFH.
Bug: 1284367
Change-Id: I3afb40e394d6e2e7fd19b2704e0dd68fa23c7bb2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3367466
Reviewed-by: Daniel Rubery <drubery@chromium.org>
Commit-Queue: Xinghui Lu <xinghuilu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#956061}
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc
index ab395a814221a900976fb5f1cdfd79946ea1b742..4bf428b1a7fc8c331d0644c0785f4e57a31c0884 100644
--- a/chrome/browser/safe_browsing/threat_details_unittest.cc
+++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -601,7 +601,8 @@ TEST_F(ThreatDetailsTest, ThreatDOMDetails) {
parent_node->children.push_back(GURL(kDOMChildURL));
params.push_back(std::move(parent_node));
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(), std::move(params));
+ main_rfh()->GetGlobalId(),
+ std::move(params));
std::string serialized = WaitForThreatDetailsDone(
report.get(), false /* did_proceed*/, 0 /* num_visit */);
@@ -820,10 +821,11 @@ TEST_F(ThreatDetailsTest, ThreatDOMDetails_MultipleFrames) {
// Send both sets of nodes from different render frames.
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(),
+ main_rfh()->GetGlobalId(),
std::move(outer_params_copy));
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- child_rfh, std::move(inner_params_copy));
+ child_rfh->GetGlobalId(),
+ std::move(inner_params_copy));
std::string serialized = WaitForThreatDetailsDone(
report.get(), false /* did_proceed*/, 0 /* num_visit */);
@@ -869,9 +871,11 @@ TEST_F(ThreatDetailsTest, ThreatDOMDetails_MultipleFrames) {
// Send both sets of nodes from different render frames.
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- child_rfh, std::move(inner_params));
+ child_rfh->GetGlobalId(),
+ std::move(inner_params));
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(), std::move(outer_params));
+ main_rfh()->GetGlobalId(),
+ std::move(outer_params));
std::string serialized = WaitForThreatDetailsDone(
report.get(), false /* did_proceed*/, 0 /* num_visit */);
@@ -995,9 +999,11 @@ TEST_F(ThreatDetailsTest, ThreatDOMDetails_AmbiguousDOM) {
// Send both sets of nodes from different render frames.
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(), std::move(outer_params));
+ main_rfh()->GetGlobalId(),
+ std::move(outer_params));
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- child_rfh, std::move(inner_params));
+ child_rfh->GetGlobalId(),
+ std::move(inner_params));
std::string serialized = WaitForThreatDetailsDone(
report.get(), false /* did_proceed*/, 0 /* num_visit */);
ClientSafeBrowsingReportRequest actual;
@@ -1262,10 +1268,10 @@ TEST_F(ThreatDetailsTest, ThreatDOMDetails_TrimToAdTags) {
// Send both sets of nodes from different render frames.
trimmed_report->OnReceivedThreatDOMDetails(
- mojo::Remote<mojom::ThreatReporter>(), child_rfh,
+ mojo::Remote<mojom::ThreatReporter>(), child_rfh->GetGlobalId(),
std::move(inner_params));
trimmed_report->OnReceivedThreatDOMDetails(
- mojo::Remote<mojom::ThreatReporter>(), main_rfh(),
+ mojo::Remote<mojom::ThreatReporter>(), main_rfh()->GetGlobalId(),
std::move(outer_params));
std::string serialized = WaitForThreatDetailsDone(
@@ -1338,10 +1344,10 @@ TEST_F(ThreatDetailsTest, ThreatDOMDetails_EmptyReportNotSent) {
// Send both sets of nodes from different render frames.
trimmed_report->OnReceivedThreatDOMDetails(
- mojo::Remote<mojom::ThreatReporter>(), child_rfh,
+ mojo::Remote<mojom::ThreatReporter>(), child_rfh->GetGlobalId(),
std::move(inner_params));
trimmed_report->OnReceivedThreatDOMDetails(
- mojo::Remote<mojom::ThreatReporter>(), main_rfh(),
+ mojo::Remote<mojom::ThreatReporter>(), main_rfh()->GetGlobalId(),
std::move(outer_params));
std::string serialized = WaitForThreatDetailsDone(
@@ -1598,7 +1604,8 @@ TEST_F(ThreatDetailsTest, HTTPCache) {
// The cache collection starts after the IPC from the DOM is fired.
std::vector<mojom::ThreatDOMDetailsNodePtr> params;
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(), std::move(params));
+ main_rfh()->GetGlobalId(),
+ std::move(params));
// Let the cache callbacks complete.
base::RunLoop().RunUntilIdle();
@@ -1678,7 +1685,8 @@ TEST_F(ThreatDetailsTest, HttpsResourceSanitization) {
// The cache collection starts after the IPC from the DOM is fired.
std::vector<mojom::ThreatDOMDetailsNodePtr> params;
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(), std::move(params));
+ main_rfh()->GetGlobalId(),
+ std::move(params));
// Let the cache callbacks complete.
base::RunLoop().RunUntilIdle();
@@ -1761,7 +1769,8 @@ TEST_F(ThreatDetailsTest, HTTPCacheNoEntries) {
// The cache collection starts after the IPC from the DOM is fired.
std::vector<mojom::ThreatDOMDetailsNodePtr> params;
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(), std::move(params));
+ main_rfh()->GetGlobalId(),
+ std::move(params));
// Let the cache callbacks complete.
base::RunLoop().RunUntilIdle();
@@ -1820,7 +1829,8 @@ TEST_F(ThreatDetailsTest, HistoryServiceUrls) {
// The redirects collection starts after the IPC from the DOM is fired.
std::vector<mojom::ThreatDOMDetailsNodePtr> params;
report->OnReceivedThreatDOMDetails(mojo::Remote<mojom::ThreatReporter>(),
- main_rfh(), std::move(params));
+ main_rfh()->GetGlobalId(),
+ std::move(params));
// Let the redirects callbacks complete.
base::RunLoop().RunUntilIdle();
diff --git a/components/safe_browsing/content/browser/threat_details.cc b/components/safe_browsing/content/browser/threat_details.cc
index f3fe647b5d443c2a2f284289ae66d81782c5f6e8..361830189b0ab6324fe87719f36f2fa0bc948224 100644
--- a/components/safe_browsing/content/browser/threat_details.cc
+++ b/components/safe_browsing/content/browser/threat_details.cc
@@ -664,16 +664,20 @@ void ThreatDetails::RequestThreatDOMDetails(content::RenderFrameHost* frame) {
pending_render_frame_hosts_.push_back(frame);
raw_threat_report->GetThreatDOMDetails(
base::BindOnce(&ThreatDetails::OnReceivedThreatDOMDetails, GetWeakPtr(),
- std::move(threat_reporter), frame));
+ std::move(threat_reporter), frame->GetGlobalId()));
}
// When the renderer is done, this is called.
void ThreatDetails::OnReceivedThreatDOMDetails(
mojo::Remote<mojom::ThreatReporter> threat_reporter,
- content::RenderFrameHost* sender,
+ content::GlobalRenderFrameHostId sender_id,
std::vector<mojom::ThreatDOMDetailsNodePtr> params) {
// If the RenderFrameHost was closed between sending the IPC and this callback
// running, |sender| will be invalid.
+ auto* sender = content::RenderFrameHost::FromID(sender_id);
+ if (!sender) {
+ return;
+ }
const auto sender_it = std::find(pending_render_frame_hosts_.begin(),
pending_render_frame_hosts_.end(), sender);
if (sender_it == pending_render_frame_hosts_.end()) {
diff --git a/components/safe_browsing/content/browser/threat_details.h b/components/safe_browsing/content/browser/threat_details.h
index 8cb89700141561aab49edc474799c9e7148b8ae8..61dcb8d9c772d223661236d99aebd1d3ebe01d3a 100644
--- a/components/safe_browsing/content/browser/threat_details.h
+++ b/components/safe_browsing/content/browser/threat_details.h
@@ -24,6 +24,7 @@
#include "components/safe_browsing/core/common/proto/csd.pb.h"
#include "components/security_interstitials/core/unsafe_resource.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents_observer.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -169,7 +170,7 @@ class ThreatDetails : public content::WebContentsObserver {
void OnReceivedThreatDOMDetails(
mojo::Remote<mojom::ThreatReporter> threat_reporter,
- content::RenderFrameHost* sender,
+ content::GlobalRenderFrameHostId sender_id,
std::vector<mojom::ThreatDOMDetailsNodePtr> params);
void AddRedirectUrlList(const std::vector<GURL>& urls);

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 d5ace3a879ab5ab00557ba380d9470d9eb937286..36ad9f68d3a79fe3d7d948276a654aacf5db019b 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 530f0e2cc0e7255fb120ebdef45c57d01c0f2b5f..b948e52da81d2d12543d76575c49bfa8a09288c4 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,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Muyao Xu <muyaoxu@google.com>
Date: Thu, 17 Feb 2022 16:23:29 +0000
Subject: Replace WidgetObserver::OnWidgetClosing() with OnWidgetDestroying()
In some cases, OnWidgetClosing() is not called when the widget is
closed, resulting an invalid pointer |widget_| stored in
WebContentsDisplayObserverView.
This CL replaces OnWidgetClosing() with OnWidgetDestroying(), which
is recommended in crbug.com/1240365
(cherry picked from commit 4535fe2334d0713535adb52b641a8cb34e11333c)
Bug: 1291728
Change-Id: I64fef8b30930f60220008809ee00f4385d6c3520
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3425473
Auto-Submit: Muyao Xu <muyaoxu@google.com>
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#965431}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3435985
Reviewed-by: Michael Ershov <miersh@google.com>
Owners-Override: Michael Ershov <miersh@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1480}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc
index 80d33b238cd7455ec5b44d5fd966f42f690946bf..2061c2ecb476cd33ed999f180c0293641f7ac23a 100644
--- a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc
+++ b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.cc
@@ -65,7 +65,7 @@ void WebContentsDisplayObserverView::OnBrowserSetLastActive(Browser* browser) {
}
}
-void WebContentsDisplayObserverView::OnWidgetClosing(views::Widget* widget) {
+void WebContentsDisplayObserverView::OnWidgetDestroying(views::Widget* widget) {
if (widget_)
widget_->RemoveObserver(this);
widget_ = nullptr;
diff --git a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h
index 17a8ca48b1c836a82e2be5e5c605bc1837150cba..b63cf4505318a44c65585b06ec13960bad5d9e32 100644
--- a/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h
+++ b/chrome/browser/ui/views/media_router/web_contents_display_observer_view.h
@@ -28,7 +28,7 @@ class WebContentsDisplayObserverView : public WebContentsDisplayObserver,
void OnBrowserSetLastActive(Browser* browser) override;
// views::WidgetObserver overrides:
- void OnWidgetClosing(views::Widget* widget) override;
+ void OnWidgetDestroying(views::Widget* widget) override;
void OnWidgetBoundsChanged(views::Widget* widget,
const gfx::Rect& new_bounds) override;

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 87caef2cf5cf56b7bf72752410648ef1d7bb9f9a..59c505707216362d3a3b662a6a531398b8f5009e 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
@@ -21,8 +21,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,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tony Herre <toprice@chromium.org>
Date: Fri, 18 Feb 2022 13:52:01 +0000
Subject: Switch to new RequestPermissionsFromCurrentDocument API method for
Media Stream Devices
Switch away from the deprecated RequestPermissions() API, as a part of removing a bug where the previously provided request.security_origin param might get destroyed during the method execution.
(cherry picked from commit cb6778fb965e2b010922f157c68480de863c252e)
Bug: 1283402
Change-Id: I512ce910146ec60d4d35fa1a86a71a3b0983a5d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3417436
Reviewed-by: Florent Castelli <orphis@chromium.org>
Commit-Queue: Tony Herre <toprice@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#964535}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3473365
Cr-Commit-Position: refs/branch-heads/4844@{#655}
Cr-Branched-From: 007241ce2e6c8e5a7b306cc36c730cd07cd38825-refs/heads/main@{#961656}
diff --git a/components/webrtc/media_stream_devices_controller.cc b/components/webrtc/media_stream_devices_controller.cc
index 8eb0e01815f6a5f2f0241554b3e5b93017564242..33468f9f2b1bcc2cda8d98748902984ae82e147d 100644
--- a/components/webrtc/media_stream_devices_controller.cc
+++ b/components/webrtc/media_stream_devices_controller.cc
@@ -139,9 +139,8 @@ void MediaStreamDevicesController::RequestPermissions(
}
}
- permission_manager->RequestPermissions(
- content_settings_types, rfh, request.security_origin,
- request.user_gesture,
+ permission_manager->RequestPermissionsFromCurrentDocument(
+ content_settings_types, rfh, request.user_gesture,
base::BindOnce(
&MediaStreamDevicesController::RequestAndroidPermissionsIfNeeded,
web_contents, std::move(controller), will_prompt_for_audio,

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 8fe9a4e507aa5b081af4b48fe80ee38275dee84e..8ec7bbc1ed065b84afd22a4223e2359344876c47 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -1013,15 +1013,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 0a415338f3396e1fce75b691911aa77c28d8bdf9..ff0e1508326c92ecd46546755c030a906c6eac28 100644
--- a/net/http/http_stream_parser.h
+++ b/net/http/http_stream_parser.h
@@ -271,6 +271,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 545b9f11b43b37456ccab54a63eeb76034c934ef..07f94e6bb6aefe3777a71afed80b22eedea2999e 100644
--- a/net/http/http_stream_parser_unittest.cc
+++ b/net/http/http_stream_parser_unittest.cc
@@ -1395,6 +1395,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,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 16babfa9bcf98d640bc32be99fc8641e3f459a4b..767b477d50d79b2bca8dcb09d21d3c474d825fca 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,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,151 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Thu, 24 Feb 2022 15:13:13 +0000
Subject: Validate message headers sooner
M96 merge issues:
- multiplex_router.h: conflict in removed lines because of
differences in comments above header_validator_
- connector.h: conflicting includes
Message header validation has been tied to interface message dispatch,
but not all mojo::Message consumers are interface bindings.
mojo::Connector is a more general-purpose entry point through which
incoming messages are received and transformed into mojo::Message
objects. Blink's MessagePort implementation uses Connector directly to
transmit and receive raw serialized object data.
This change moves MessageHeaderValidator ownership into Connector and
always applies its validation immediately after reading a message from
the pipe, thereby ensuring that all mojo::Message objects used in
production have validated headers before use.
(cherry picked from commit 8d5bc69146505785ce299c490e35e3f3ef19f69c)
Fixed: 1281908
Change-Id: Ie0e251ab04681a4fd4b849d82c247e0ed800dc04
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3462461
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#971263}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3483815
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1505}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/mojo/public/cpp/bindings/connector.h b/mojo/public/cpp/bindings/connector.h
index 3975d01a434d6caf229c6d8eaedfe5e2acf684f8..ff17af9b378a1992dbd681e80e957826ebfd83dd 100644
--- a/mojo/public/cpp/bindings/connector.h
+++ b/mojo/public/cpp/bindings/connector.h
@@ -18,6 +18,7 @@
#include "base/sequenced_task_runner.h"
#include "mojo/public/cpp/bindings/connection_group.h"
#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/message_header_validator.h"
#include "mojo/public/cpp/bindings/sync_handle_watcher.h"
#include "mojo/public/cpp/system/core.h"
#include "mojo/public/cpp/system/handle_signal_tracker.h"
@@ -345,6 +346,8 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) Connector : public MessageReceiver {
// The number of pending tasks for |CallDispatchNextMessageFromPipe|.
size_t num_pending_dispatch_tasks_ = 0;
+ MessageHeaderValidator header_validator_;
+
#if defined(ENABLE_IPC_FUZZER)
std::unique_ptr<MessageReceiver> message_dumper_;
#endif
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc
index 92a9756cbaebe12377e9c9b81467260c73528311..cb08f13b1bfa13a1a79f7f39005f826e51c12a69 100644
--- a/mojo/public/cpp/bindings/lib/connector.cc
+++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -19,6 +19,7 @@
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
+#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
#include "base/task/current_thread.h"
#include "base/threading/sequence_local_storage_slot.h"
@@ -152,7 +153,11 @@ Connector::Connector(ScopedMessagePipeHandle message_pipe,
force_immediate_dispatch_(!EnableTaskPerMessage()),
outgoing_serialization_mode_(g_default_outgoing_serialization_mode),
incoming_serialization_mode_(g_default_incoming_serialization_mode),
- interface_name_(interface_name) {
+ interface_name_(interface_name),
+ header_validator_(
+ base::JoinString({interface_name ? interface_name : "Generic",
+ "MessageHeaderValidator"},
+ "")) {
if (config == MULTI_THREADED_SEND)
lock_.emplace();
@@ -492,6 +497,7 @@ MojoResult Connector::ReadMessage(Message* message) {
return result;
*message = Message::CreateFromMessageHandle(&handle);
+
if (message->IsNull()) {
// Even if the read was successful, the Message may still be null if there
// was a problem extracting handles from it. We treat this essentially as
@@ -507,6 +513,10 @@ MojoResult Connector::ReadMessage(Message* message) {
return MOJO_RESULT_ABORTED;
}
+ if (!header_validator_.Accept(message)) {
+ return MOJO_RESULT_ABORTED;
+ }
+
return MOJO_RESULT_OK;
}
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
index 605e51344d64eb5ede3ab475bc8833b37a458535..23e3970089e33d07b18d734d4f599c9c9f9e4bc8 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -23,7 +23,6 @@
#include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
#include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
#include "mojo/public/cpp/bindings/lib/message_quota_checker.h"
-#include "mojo/public/cpp/bindings/message_header_validator.h"
#include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h"
namespace mojo {
@@ -389,14 +388,7 @@ MultiplexRouter::MultiplexRouter(
if (quota_checker)
connector_.SetMessageQuotaChecker(std::move(quota_checker));
- std::unique_ptr<MessageHeaderValidator> header_validator =
- std::make_unique<MessageHeaderValidator>();
- header_validator_ = header_validator.get();
- dispatcher_.SetValidator(std::move(header_validator));
-
if (primary_interface_name) {
- header_validator_->SetDescription(base::JoinString(
- {primary_interface_name, "[primary] MessageHeaderValidator"}, " "));
control_message_handler_.SetDescription(base::JoinString(
{primary_interface_name, "[primary] PipeControlMessageHandler"}, " "));
}
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.h b/mojo/public/cpp/bindings/lib/multiplex_router.h
index 3d3bbb16e25b1adc678e536bd977fa22fc478920..3a9f76a57e301aa89d1bdc5aa1000f815793e238 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.h
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.h
@@ -38,7 +38,6 @@ class SequencedTaskRunner;
namespace mojo {
class AsyncFlusher;
-class MessageHeaderValidator;
class PendingFlush;
namespace internal {
@@ -301,9 +300,6 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) MultiplexRouter
scoped_refptr<base::SequencedTaskRunner> task_runner_;
- // Owned by |dispatcher_| below.
- MessageHeaderValidator* header_validator_ = nullptr;
-
MessageDispatcher dispatcher_;
Connector connector_;

View File

@@ -0,0 +1,150 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ted Meyer <tmathmeyer@chromium.org>
Date: Thu, 24 Feb 2022 17:39:53 +0000
Subject: Guard BatchingMediaLog::event_handlers_ with lock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It seems that despite MediaLog::OnWebMediaPlayerDestroyed and
MediaLog::AddLogRecord both grabbing a lock,
BatchingMediaLog::AddLogRecordLocked can escape the lock handle by
posting BatchingMediaLog::SendQueuedMediaEvents, causing a race.
When the addition of an event is interrupted by the deletion of a player
due to player culling in MediaInspectorContextImpl, a UAF can occur.
R=dalecurtis
(cherry picked from commit 34526c3d0a857a22618e4d77c7f63b5ca6f8d3d2)
Bug: 1295786
Change-Id: I77df94988f806e4d98924669d27860e50455299d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3451494
Commit-Queue: Ted (Chromium) Meyer <tmathmeyer@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#970815}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3483655
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1508}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/content/renderer/media/batching_media_log.cc b/content/renderer/media/batching_media_log.cc
index 8d8c5cb28b9bb0fcebcceb9e56db98fdace13c88..2d12a5eb42b930acac74a5ea2b2961e6c7e32fcf 100644
--- a/content/renderer/media/batching_media_log.cc
+++ b/content/renderer/media/batching_media_log.cc
@@ -52,9 +52,9 @@ BatchingMediaLog::BatchingMediaLog(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
std::vector<std::unique_ptr<EventHandler>> event_handlers)
: task_runner_(std::move(task_runner)),
- event_handlers_(std::move(event_handlers)),
tick_clock_(base::DefaultTickClock::GetInstance()),
last_ipc_send_time_(tick_clock_->NowTicks()),
+ event_handlers_(std::move(event_handlers)),
ipc_send_pending_(false),
logged_rate_limit_warning_(false) {
// Pre-bind the WeakPtr on the right thread since we'll receive calls from
@@ -76,6 +76,7 @@ BatchingMediaLog::~BatchingMediaLog() {
}
void BatchingMediaLog::OnWebMediaPlayerDestroyedLocked() {
+ base::AutoLock lock(lock_);
for (const auto& handler : event_handlers_)
handler->OnWebMediaPlayerDestroyed();
}
@@ -198,32 +199,30 @@ std::string BatchingMediaLog::MediaEventToMessageString(
void BatchingMediaLog::SendQueuedMediaEvents() {
DCHECK(task_runner_->BelongsToCurrentThread());
+ base::AutoLock auto_lock(lock_);
- std::vector<media::MediaLogRecord> events_to_send;
- {
- base::AutoLock auto_lock(lock_);
- DCHECK(ipc_send_pending_);
- ipc_send_pending_ = false;
-
- if (last_duration_changed_event_) {
- queued_media_events_.push_back(*last_duration_changed_event_);
- last_duration_changed_event_.reset();
- }
+ DCHECK(ipc_send_pending_);
+ ipc_send_pending_ = false;
- if (last_buffering_state_event_) {
- queued_media_events_.push_back(*last_buffering_state_event_);
- last_buffering_state_event_.reset();
- }
+ if (last_duration_changed_event_) {
+ queued_media_events_.push_back(*last_duration_changed_event_);
+ last_duration_changed_event_.reset();
+ }
- queued_media_events_.swap(events_to_send);
- last_ipc_send_time_ = tick_clock_->NowTicks();
+ if (last_buffering_state_event_) {
+ queued_media_events_.push_back(*last_buffering_state_event_);
+ last_buffering_state_event_.reset();
}
- if (events_to_send.empty())
+ last_ipc_send_time_ = tick_clock_->NowTicks();
+
+ if (queued_media_events_.empty())
return;
for (const auto& handler : event_handlers_)
- handler->SendQueuedMediaEvents(events_to_send);
+ handler->SendQueuedMediaEvents(queued_media_events_);
+
+ queued_media_events_.clear();
}
void BatchingMediaLog::SetTickClockForTesting(
diff --git a/content/renderer/media/batching_media_log.h b/content/renderer/media/batching_media_log.h
index 5810efdf0a75b809b94fb5abcd5f3dfbde7b019d..c59dbf2a2b980a89b41c45818476c77e9096339b 100644
--- a/content/renderer/media/batching_media_log.h
+++ b/content/renderer/media/batching_media_log.h
@@ -63,9 +63,6 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- // impl for sending queued events.
- std::vector<std::unique_ptr<EventHandler>> event_handlers_;
-
// |lock_| protects access to all of the following member variables. It
// allows any render process thread to AddEvent(), while preserving their
// sequence for throttled send on |task_runner_| and coherent retrieval by
@@ -73,19 +70,24 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
// guarantees provided by MediaLog, since SendQueuedMediaEvents must also
// be synchronized with respect to AddEvent.
mutable base::Lock lock_;
- const base::TickClock* tick_clock_;
- base::TimeTicks last_ipc_send_time_;
- std::vector<media::MediaLogRecord> queued_media_events_;
+ const base::TickClock* tick_clock_ GUARDED_BY(lock_);
+ base::TimeTicks last_ipc_send_time_ GUARDED_BY(lock_);
+ std::vector<media::MediaLogRecord> queued_media_events_ GUARDED_BY(lock_);
+
+ // impl for sending queued events.
+ std::vector<std::unique_ptr<EventHandler>> event_handlers_ GUARDED_BY(lock_);
// For enforcing max 1 pending send.
- bool ipc_send_pending_;
+ bool ipc_send_pending_ GUARDED_BY(lock_);
// True if we've logged a warning message about exceeding rate limits.
- bool logged_rate_limit_warning_;
+ bool logged_rate_limit_warning_ GUARDED_BY(lock_);
// Limits the number of events we send over IPC to one.
- absl::optional<media::MediaLogRecord> last_duration_changed_event_;
- absl::optional<media::MediaLogRecord> last_buffering_state_event_;
+ absl::optional<media::MediaLogRecord> last_duration_changed_event_
+ GUARDED_BY(lock_);
+ absl::optional<media::MediaLogRecord> last_buffering_state_event_
+ GUARDED_BY(lock_);
// Holds the earliest MEDIA_ERROR_LOG_ENTRY event added to this log. This is
// most likely to contain the most specific information available describing

File diff suppressed because it is too large Load Diff

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 8a49e706890a173a3e09ae16b8e88500aefb0499..39384b426a38f2210040cb3f2cbba85893496a7b 100644
--- a/media/gpu/mac/vt_video_encode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_encode_accelerator_mac.cc
@@ -120,13 +120,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;
@@ -505,10 +505,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)
@@ -544,6 +542,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,151 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stephen Roettger <sroettger@google.com>
Date: Fri, 7 Jan 2022 09:36:31 +0000
Subject: Keep a set of previously dropped peers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Test that a given node name hasn't been seen before.
A side effect of this fix is that re-invitation will not work anymore.
BUG=chromium:1274113
Change-Id: Ibdc50291efa1f6298614b163b544ad980615a981
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3341553
Reviewed-by: Ken Rockot <rockot@google.com>
Commit-Queue: Stephen Röttger <sroettger@google.com>
Cr-Commit-Position: refs/heads/main@{#956441}
diff --git a/mojo/core/invitation_unittest.cc b/mojo/core/invitation_unittest.cc
index 2c8eeef9feefc6be689f1ca2052af316b4b7db68..0687a58ee2b294580d1165e872ec5855e5de2b53 100644
--- a/mojo/core/invitation_unittest.cc
+++ b/mojo/core/invitation_unittest.cc
@@ -693,7 +693,8 @@ DEFINE_TEST_CLIENT(ProcessErrorsClient) {
EXPECT_EQ(kDisconnectMessage, ReadMessage(pipe));
}
-TEST_F(InvitationTest, Reinvitation) {
+// Temporary removed support for reinvitation for non-isolated connections.
+TEST_F(InvitationTest, DISABLED_Reinvitation) {
// The gist of this test is that a process should be able to accept an
// invitation, lose its connection to the process network, and then accept a
// new invitation to re-establish communication.
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
index b34753b2dc0c58e5a80e1d0678ee178e2589e8e3..1a343929127e748b78fdb2107ec7a91f71c846a7 100644
--- a/mojo/core/node_controller.cc
+++ b/mojo/core/node_controller.cc
@@ -543,7 +543,8 @@ scoped_refptr<NodeChannel> NodeController::GetBrokerChannel() {
void NodeController::AddPeer(const ports::NodeName& name,
scoped_refptr<NodeChannel> channel,
- bool start_channel) {
+ bool start_channel,
+ bool allow_name_reuse) {
DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
DCHECK(name != ports::kInvalidNodeName);
@@ -562,6 +563,11 @@ void NodeController::AddPeer(const ports::NodeName& name,
return;
}
+ if (dropped_peers_.Contains(name) && !allow_name_reuse) {
+ LOG(ERROR) << "Trying to re-add dropped peer " << name;
+ return;
+ }
+
auto result = peers_.insert(std::make_pair(name, channel));
DCHECK(result.second);
@@ -602,6 +608,7 @@ void NodeController::DropPeer(const ports::NodeName& node_name,
if (it != peers_.end()) {
ports::NodeName peer = it->first;
peers_.erase(it);
+ dropped_peers_.Insert(peer);
DVLOG(1) << "Dropped peer " << peer;
}
@@ -1270,7 +1277,8 @@ void NodeController::OnAcceptPeer(const ports::NodeName& from_node,
// Note that we explicitly drop any prior connection to the same peer so
// that new isolated connections can replace old ones.
DropPeer(peer_name, nullptr);
- AddPeer(peer_name, channel, false /* start_channel */);
+ AddPeer(peer_name, channel, false /* start_channel */,
+ true /* allow_name_reuse */);
DVLOG(1) << "Node " << name_ << " accepted peer " << peer_name;
}
@@ -1386,5 +1394,24 @@ NodeController::IsolatedConnection&
NodeController::IsolatedConnection::operator=(IsolatedConnection&& other) =
default;
+BoundedPeerSet::BoundedPeerSet() = default;
+BoundedPeerSet::~BoundedPeerSet() = default;
+
+void BoundedPeerSet::Insert(const ports::NodeName& name) {
+ if (new_set_.size() == kHalfSize) {
+ old_set_.clear();
+ std::swap(old_set_, new_set_);
+ }
+ new_set_.insert(name);
+}
+
+bool BoundedPeerSet::Contains(const ports::NodeName& name) {
+ if (old_set_.find(name) != old_set_.end())
+ return true;
+ if (new_set_.find(name) != new_set_.end())
+ return true;
+ return false;
+}
+
} // namespace core
} // namespace mojo
diff --git a/mojo/core/node_controller.h b/mojo/core/node_controller.h
index 040eeab79f72efcdb2823cf62e7dbaefa8b9233f..571e578da4950135456bb97c8ea7a30ceabca7cc 100644
--- a/mojo/core/node_controller.h
+++ b/mojo/core/node_controller.h
@@ -38,6 +38,26 @@ namespace core {
class Broker;
class Core;
+// A set of NodeNames that is bounded by a maximum size.
+// If the max size is reached, it will delete the older half of stored names.
+class BoundedPeerSet {
+ public:
+ BoundedPeerSet();
+ BoundedPeerSet(const BoundedPeerSet&) = delete;
+ BoundedPeerSet& operator=(const BoundedPeerSet&) = delete;
+
+ ~BoundedPeerSet();
+
+ void Insert(const ports::NodeName& name);
+ bool Contains(const ports::NodeName& name);
+
+ private:
+ static constexpr int kHalfSize = 50000;
+
+ std::unordered_set<ports::NodeName> old_set_;
+ std::unordered_set<ports::NodeName> new_set_;
+};
+
// The owner of ports::Node which facilitates core EDK implementation. All
// public interface methods are safe to call from any thread.
class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
@@ -180,7 +200,8 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
void AddPeer(const ports::NodeName& name,
scoped_refptr<NodeChannel> channel,
- bool start_channel);
+ bool start_channel,
+ bool allow_name_reuse = false);
void DropPeer(const ports::NodeName& name, NodeChannel* channel);
void SendPeerEvent(const ports::NodeName& name, ports::ScopedEvent event);
void DropAllPeers();
@@ -265,6 +286,7 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
// Channels to known peers, including inviter and invitees, if any.
NodeMap peers_;
+ BoundedPeerSet dropped_peers_;
// Outgoing message queues for peers we've heard of but can't yet talk to.
std::unordered_map<ports::NodeName, OutgoingMessageQueue>

View File

@@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Wed, 2 Feb 2022 05:45:44 +0000
Subject: Viz: Fix UAF on context loss
(cherry picked from commit 98d246cabe677e1d8287e4d42ce02825417be9e2)
Fixed: 1250655
Change-Id: I2898316635d370fa36b94e0ae2564ed357745b2c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3413372
Auto-Submit: Ken Rockot <rockot@google.com>
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#963012}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3430523
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/branch-heads/4758@{#1050}
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
index a31c10c610000415b5a88a0824eea63b45a435cc..1b323f142d934afea0215dea190efaa197cec554 100644
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
@@ -478,9 +478,13 @@ const gpu::GpuFeatureInfo& ContextProviderCommandBuffer::GetGpuFeatureInfo()
void ContextProviderCommandBuffer::OnLostContext() {
CheckValidThreadOrLockAcquired();
- // Ensure |this| isn't destroyed in the middle of OnLostContext() if observers
- // drop all references to it.
- scoped_refptr<ContextProviderCommandBuffer> ref(this);
+ // Observers may drop the last persistent references to `this`, but there may
+ // be weak references in use further up the stack. This task is posted to
+ // ensure that destruction is deferred until it's safe.
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce([](scoped_refptr<ContextProviderCommandBuffer>) {},
+ base::WrapRefCounted(this)));
for (auto& observer : observers_)
observer.OnContextLost();

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kevin Ellis <kevers@google.com>
Date: Fri, 11 Feb 2022 01:36:04 +0000
Subject: Code health cleanup: replacing animations.
Animation::Update performed a synchronous processing of the finish
microtask to ensure that finished events where dispatched ahead of
replace events. This step does not align with the spec. Instead we
should be queuing the replace event. Microtasks will be processed in
the correct order.
Spec link: https://www.w3.org/TR/web-animations-1/#timelines
Change-Id: Ibe7753e792fb6cf905bbe6815a080a8cc51c2803
(cherry picked from commit d4fb69ff0fe343fe8a171014785a88eabfe2b1c2)
Bug: 1290858
Change-Id: Ibe7753e792fb6cf905bbe6815a080a8cc51c2803
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3414765
Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#964223}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3453925
Reviewed-by: Adrian Taylor <adetaylor@google.com>
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/4758@{#1134}
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc
index f11b55b34cdaa57f4ccfbe44c40c4d03d485210d..acb59f356d43e368e6e5cfe2f649ae60483ab978 100644
--- a/third_party/blink/renderer/core/animation/animation.cc
+++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -2275,10 +2275,6 @@ bool Animation::Update(TimingUpdateReason reason) {
if (reason == kTimingUpdateForAnimationFrame) {
if (idle || CalculateAnimationPlayState() == kFinished) {
- // TODO(crbug.com/1029348): Per spec, we should have a microtask
- // checkpoint right after the update cycle. Once this is fixed we should
- // no longer need to force a synchronous resolution here.
- AsyncFinishMicrotask();
finished_ = true;
}
}
diff --git a/third_party/blink/renderer/core/animation/document_animations.cc b/third_party/blink/renderer/core/animation/document_animations.cc
index 6e5b4f970387929b6b940b18e14e997d2baa339c..f8090e41f8b0aa2e138738f5a3ba7c434d85535b 100644
--- a/third_party/blink/renderer/core/animation/document_animations.cc
+++ b/third_party/blink/renderer/core/animation/document_animations.cc
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/page_animator.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
@@ -286,10 +287,13 @@ void DocumentAnimations::RemoveReplacedAnimations(
// The list of animations for removal is constructed in reverse composite
// ordering for efficiency. Flip the ordering to ensure that events are
- // dispatched in composite order.
+ // dispatched in composite order. Queue as a microtask so that the finished
+ // event is dispatched ahead of the remove event.
for (auto it = animations_to_remove.rbegin();
it != animations_to_remove.rend(); it++) {
- (*it)->RemoveReplacedAnimation();
+ Animation* animation = *it;
+ Microtask::EnqueueMicrotask(WTF::Bind(&Animation::RemoveReplacedAnimation,
+ WrapWeakPersistent(animation)));
}
}

View File

@@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Sat, 5 Feb 2022 13:41:47 +0000
Subject: Fix potential handle reuse in Mojo
(cherry picked from commit 76eca90d0e9c09bfbb8c3e8999f36e6da6842a39)
(cherry picked from commit e1432faf5e101b3a516037a26818c03c759d2fdd)
Fixed: 1270333
Change-Id: Ife188d519092e4e634355fd53d97c85009771b76
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3414063
Auto-Submit: Ken Rockot <rockot@google.com>
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/main@{#962946}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3421488
Commit-Queue: Ken Rockot <rockot@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Original-Commit-Position: refs/branch-heads/4844@{#87}
Cr-Original-Branched-From: 007241ce2e6c8e5a7b306cc36c730cd07cd38825-refs/heads/main@{#961656}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3427544
Reviewed-by: Jana Grill <janagrill@google.com>
Owners-Override: Jana Grill <janagrill@google.com>
Commit-Queue: Zakhar Voit <voit@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1455}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/mojo/core/handle_table.cc b/mojo/core/handle_table.cc
index 9426281d73f050598bd5f88b38aac39c4b994ff3..a044f1c8e38f0affe269a87a10c70b49fe6d353c 100644
--- a/mojo/core/handle_table.cc
+++ b/mojo/core/handle_table.cc
@@ -65,13 +65,19 @@ bool HandleTable::AddDispatchersFromTransit(
const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
MojoHandle* handles) {
// Oops, we're out of handles.
- if (next_available_handle_ == MOJO_HANDLE_INVALID)
+ if (next_available_handle_ == MOJO_HANDLE_INVALID) {
return false;
+ }
+
+ // MOJO_HANDLE_INVALID is zero.
+ DCHECK_GE(next_available_handle_, 1u);
- DCHECK_LE(dispatchers.size(), std::numeric_limits<uint32_t>::max());
// If this insertion would cause handle overflow, we're out of handles.
- if (next_available_handle_ + dispatchers.size() < next_available_handle_)
+ const uint32_t num_handles_available =
+ std::numeric_limits<uint32_t>::max() - next_available_handle_ + 1;
+ if (num_handles_available < dispatchers.size()) {
return false;
+ }
for (size_t i = 0; i < dispatchers.size(); ++i) {
MojoHandle handle = MOJO_HANDLE_INVALID;

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 090068ee1dc22a0c823a4817e6c6e748fcec354b..466e4f76fce71787b78c2d24624e60184f1d1f36 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 d673d0d6ec63a042a6b08149ba7c2b3fc505e221..8c27d41b160876e0347186958f0e9f08efd41e01 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 fadab535bc3f8de7173e329e4d514e648e0f5817..1879523e9f18c41b448957d906c1684c024814da 100644
--- a/third_party/blink/renderer/core/timing/profiler_group_test.cc
+++ b/third_party/blink/renderer/core/timing/profiler_group_test.cc
@@ -268,4 +268,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,138 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dave Tapuska <dtapuska@chromium.org>
Date: Tue, 8 Feb 2022 15:58:40 +0000
Subject: Cleanup PausablecriptExecutor usage.
Improve performance of API so we don't have to go from
WTF::String->WebString->WTF::String for execution.
Ensure the Executor is traced via the PausableScriptExecutor.
BUG=1289384
(cherry picked from commit c8231f9a89460fd8336e6c0d8e10347f52f540ec)
Change-Id: If9badab91222c49c08a983c60132ce71b183e951
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3407654
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#963010}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3443262
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4758@{#1109}
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
index 71653584749ef80143f3312a85a9537edd35f014..60377e12f05d298aa512a2eda5358c8bea49d114 100644
--- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -211,15 +211,16 @@ v8::MaybeLocal<v8::Value> CallMethodOnFrame(LocalFrame* local_frame,
// A wrapper class used as the callback for JavaScript executed
// in an isolated world.
-class JavaScriptIsolatedWorldRequest
- : public GarbageCollected<JavaScriptIsolatedWorldRequest>,
- public WebScriptExecutionCallback {
+class JavaScriptIsolatedWorldRequest : public PausableScriptExecutor::Executor,
+ public WebScriptExecutionCallback {
using JavaScriptExecuteRequestInIsolatedWorldCallback =
mojom::blink::LocalFrame::JavaScriptExecuteRequestInIsolatedWorldCallback;
public:
JavaScriptIsolatedWorldRequest(
LocalFrame* local_frame,
+ int32_t world_id,
+ const String& script,
bool wants_result,
mojom::blink::LocalFrame::JavaScriptExecuteRequestInIsolatedWorldCallback
callback);
@@ -229,27 +230,53 @@ class JavaScriptIsolatedWorldRequest
const JavaScriptIsolatedWorldRequest&) = delete;
~JavaScriptIsolatedWorldRequest() override;
- // WebScriptExecutionCallback:
- void Completed(const WebVector<v8::Local<v8::Value>>& result) override;
+ // PausableScriptExecutor::Executor overrides.
+ Vector<v8::Local<v8::Value>> Execute(LocalDOMWindow*) override;
+
+ void Trace(Visitor* visitor) const override;
- void Trace(Visitor* visitor) const { visitor->Trace(local_frame_); }
+ // WebScriptExecutionCallback overrides.
+ void Completed(const WebVector<v8::Local<v8::Value>>& result) override;
private:
Member<LocalFrame> local_frame_;
+ int32_t world_id_;
+ String script_;
bool wants_result_;
JavaScriptExecuteRequestInIsolatedWorldCallback callback_;
};
JavaScriptIsolatedWorldRequest::JavaScriptIsolatedWorldRequest(
LocalFrame* local_frame,
+ int32_t world_id,
+ const String& script,
bool wants_result,
JavaScriptExecuteRequestInIsolatedWorldCallback callback)
: local_frame_(local_frame),
+ world_id_(world_id),
+ script_(script),
wants_result_(wants_result),
- callback_(std::move(callback)) {}
+ callback_(std::move(callback)) {
+ DCHECK_GT(world_id, DOMWrapperWorld::kMainWorldId);
+}
JavaScriptIsolatedWorldRequest::~JavaScriptIsolatedWorldRequest() = default;
+void JavaScriptIsolatedWorldRequest::Trace(Visitor* visitor) const {
+ PausableScriptExecutor::Executor::Trace(visitor);
+ visitor->Trace(local_frame_);
+}
+
+Vector<v8::Local<v8::Value>> JavaScriptIsolatedWorldRequest::Execute(
+ LocalDOMWindow* window) {
+ // Note: An error event in an isolated world will never be dispatched to
+ // a foreign world.
+ ClassicScript* classic_script = ClassicScript::CreateUnspecifiedScript(
+ script_, SanitizeScriptErrors::kDoNotSanitize);
+ return {classic_script->RunScriptInIsolatedWorldAndReturnValue(window,
+ world_id_)};
+}
+
void JavaScriptIsolatedWorldRequest::Completed(
const WebVector<v8::Local<v8::Value>>& result) {
base::Value value;
@@ -269,7 +296,6 @@ void JavaScriptIsolatedWorldRequest::Completed(
if (new_value)
value = base::Value::FromUniquePtrValue(std::move(new_value));
}
-
std::move(callback_).Run(std::move(value));
}
@@ -927,13 +953,16 @@ void LocalFrameMojoHandler::JavaScriptExecuteRequestInIsolatedWorld(
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
scoped_refptr<DOMWrapperWorld> isolated_world =
DOMWrapperWorld::EnsureIsolatedWorld(ToIsolate(frame_), world_id);
- ScriptSourceCode source_code = ScriptSourceCode(javascript);
- HeapVector<ScriptSourceCode> sources;
- sources.Append(&source_code, 1);
- auto* executor = MakeGarbageCollected<PausableScriptExecutor>(
- DomWindow(), std::move(isolated_world), sources, false /* user_gesture */,
+
+ // This member will be traced as the |executor| on the PausableScriptExector.
+ auto* execution_request =
MakeGarbageCollected<JavaScriptIsolatedWorldRequest>(
- frame_, wants_result, std::move(callback)));
+ frame_, world_id, javascript, wants_result, std::move(callback));
+
+ auto* executor = MakeGarbageCollected<PausableScriptExecutor>(
+ DomWindow(), ToScriptState(frame_, *isolated_world),
+ /*callback=*/execution_request,
+ /*executor=*/execution_request);
executor->Run();
}

View File

@@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peng Huang <penghuang@chromium.org>
Date: Mon, 25 Oct 2021 21:10:55 +0000
Subject: Do not select vulkan device based on the passed in gpu_info on Linux
On linux dual GPU setup, we cannot detect the active GPU correctly.
It causes problems for GL and Vulkan interop. So we would to use
ANGLE vulkan backend when vulkan is enabled. So we can choose the same
GPU for both vulkan and GL. So for this CL, we will not create vulkan
device based on passed in gpu_info anymore, instead GPU device will be
selected by the order of
(discrete GPU > integrated GPU > virtual GPU > CPU simulated GPU).
And we will use the same logic in ANGLE vulkan backend as well.
Bug: 1260869
Change-Id: I6fb79a4e6ce1710e4809cd63a0f7738955a8e2d2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3242785
Commit-Queue: Peng Huang <penghuang@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Auto-Submit: Peng Huang <penghuang@chromium.org>
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/main@{#934696}
diff --git a/gpu/vulkan/vulkan_device_queue.cc b/gpu/vulkan/vulkan_device_queue.cc
index e4fe73f613dfe27b2ac6ccd7d31448e0f16ff459..22abed4db134647699d5622c4b92c3a861274f7c 100644
--- a/gpu/vulkan/vulkan_device_queue.cc
+++ b/gpu/vulkan/vulkan_device_queue.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "gpu/config/gpu_info.h" // nogncheck
#include "gpu/config/vulkan_info.h"
#include "gpu/vulkan/vulkan_command_pool.h"
@@ -77,11 +78,15 @@ bool VulkanDeviceQueue::Initialize(
if (device_properties.apiVersion < info.used_api_version)
continue;
+ // In dual-CPU cases, we cannot detect the active GPU correctly on Linux,
+ // so don't select GPU device based on the |gpu_info|.
+#if !defined(OS_LINUX)
// If gpu_info is provided, the device should match it.
if (gpu_info && (device_properties.vendorID != gpu_info->gpu.vendor_id ||
device_properties.deviceID != gpu_info->gpu.device_id)) {
continue;
}
+#endif
if (device_properties.deviceType < 0 ||
device_properties.deviceType > VK_PHYSICAL_DEVICE_TYPE_CPU) {
@@ -112,7 +117,7 @@ bool VulkanDeviceQueue::Initialize(
break;
}
}
-
+
if (!found)
continue;

View File

@@ -33,10 +33,10 @@ index 0ccfe130f00ec3b6c75cd8ee04d5a2777e1fd00c..653829457d58bf92057cc36aa8a28970
DISALLOW_COPY_AND_ASSIGN(StaticHttpUserAgentSettings);
};
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 00af87f13c9f819e4d56a3c2ecbac9337be88dec..b48f88f20f54bdd5521528882158fe1864becbbe 100644
index 24298fa4c35fec195e0e1b15422b97e2cf89daa8..8f20984763357a95c3d86be228e9bbf5e17bc9e9 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1195,6 +1195,13 @@ void NetworkContext::SetNetworkConditions(
@@ -1207,6 +1207,13 @@ void NetworkContext::SetNetworkConditions(
std::move(network_conditions));
}

View File

@@ -0,0 +1,191 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nate Chapin <japhet@chromium.org>
Date: Thu, 14 Oct 2021 20:24:32 +0000
Subject: Fire iframe onload for cross-origin-initiated same-document
navigations
A cross-origin initiator can check whether or not onload fired to
guess the url of a target frame. Always firing onload makes it
appear to be a cross-document navigation, even when it wasn't.
Bug: 1248444
Change-Id: I79249cb441f61ac6cab65ab9e5dd4a44b291bc4a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3193885
Commit-Queue: Nate Chapin <japhet@chromium.org>
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/main@{#931681}
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 5f0be38667a04a3a47f190099b81778cc8b02757..ae8baa6ab44f83e114646247f99bd0b95710f249 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1429,7 +1429,25 @@ void DocumentLoader::CommitSameDocumentNavigationInternal(
initial_scroll_state_.was_scrolled_by_user = false;
- frame_->GetDocument()->CheckCompleted();
+ if (frame_->GetDocument()->LoadEventStillNeeded()) {
+ frame_->GetDocument()->CheckCompleted();
+ } else if (frame_->Owner() && initiator_origin &&
+ !initiator_origin->CanAccess(
+ frame_->DomWindow()->GetSecurityOrigin()) &&
+ frame_->Tree()
+ .Parent()
+ ->GetSecurityContext()
+ ->GetSecurityOrigin()) {
+ // If this same-document navigation was initiated by a cross-origin iframe
+ // and is cross-origin to its parent, fire onload on the owner iframe.
+ // Normally, the owner iframe's onload fires if and only if the window's
+ // onload fires (i.e., when a navigation to a different document completes).
+ // However, a cross-origin initiator can use the presence or absence of a
+ // load event to detect whether the navigation was same- or cross-document,
+ // and can therefore try to guess the url of a cross-origin iframe. Fire the
+ // iframe's onload to prevent this technique. https://crbug.com/1251790
+ frame_->Owner()->DispatchLoad();
+ }
// If the item sequence number didn't change, there's no need to trigger
// popstate, restore scroll positions, or scroll to fragments for this
diff --git a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt
index 850c54970953c62eae282e177949f9082f22a03c..09122d9c3f39f042116d197276420cc1841c5ea8 100644
--- a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt
+++ b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async-expected.txt
@@ -1,4 +1,6 @@
+ALERT: iframe onload fired
ALERT: PASS: url fragment is changing asynchronously
ALERT: PASS: scheduled postMessage() before hashchange triggered.
+ALERT: iframe onload fired
ALERT: PASS: hashchange triggered after postMessage().
-This tests that cross-origin fragment navigations are asynchronous. It does so by scheduling a postMessage before scheduling the navigation. If the navigation is synchronous, the internals API will be able to report the presence of an url fragment immediately.
+This tests that cross-origin-initiated fragment navigations are asynchronous and always fire the load event at their embedding iframe element if it's cross-origin. It does so by scheduling a postMessage before scheduling the navigation. If the navigation is synchronous, the internals API will be able to report the presence of an url fragment immediately.
diff --git a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html
index 3d74de086c1a7f8a5fedff72d7c6bb970fca57ed..a1fc3bc87ccd2319f2dff3c5d8729a1a62875ec8 100644
--- a/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html
+++ b/third_party/blink/web_tests/http/tests/navigation/cross-origin-fragment-navigation-is-async.html
@@ -1,48 +1,51 @@
<!DOCTYPE html>
<html>
-<head>
- <script>
- if (window.testRunner) {
- testRunner.dumpAsText();
- testRunner.waitUntilDone();
- }
+<body>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
- function testFragmentNavigation() {
- window.postMessage("postmessage", "*");
- document.querySelector('iframe').src = "http://localhost:8000/navigation/resources/postmessage-on-hashchange.html#anchor1";
- if (window.internals) {
- if (internals.doesWindowHaveUrlFragment(document.querySelector('iframe').contentWindow))
- alert("FAIL: url fragment should change asynchronously");
- else
- alert("PASS: url fragment is changing asynchronously");
- }
- }
+window.onload = function() {
+ window.postMessage("postmessage", "*");
+ document.querySelector('iframe').src = "http://localhost:8000/navigation/resources/postmessage-on-hashchange.html#anchor1";
+ if (window.internals) {
+ if (internals.doesWindowHaveUrlFragment(document.querySelector('iframe').contentWindow))
+ alert("FAIL: url fragment should change asynchronously");
+ else
+ alert("PASS: url fragment is changing asynchronously");
+ }
+}
- var receivedScheduledPostMessage = false;
- var receivedHashchangeMessage = false;
- window.addEventListener('message', function (e) {
- if (e.data === 'postmessage') {
- receivedScheduledPostMessage = true;
- if (receivedHashchangeMessage)
- alert('FAIL: hashchange already triggered!');
- else
- alert('PASS: scheduled postMessage() before hashchange triggered.');
- } else {
- receivedHashchangeMessage = true;
- if (receivedScheduledPostMessage)
- alert('PASS: hashchange triggered after postMessage().');
- else
- alert('FAIL: hashchange triggered before postMessage().');
- testRunner.notifyDone();
- }
- });
- </script>
-</head>
-<body>
- <p>This tests that cross-origin fragment navigations are asynchronous. It does
- so by scheduling a postMessage before scheduling the navigation. If the
- navigation is synchronous, the internals API will be able to report the presence
- of an url fragment immediately.</p>
- <iframe src="http://localhost:8000/navigation/resources/postmessage-on-hashchange.html" onload='testFragmentNavigation()'></iframe>
+var receivedScheduledPostMessage = false;
+var receivedHashchangeMessage = false;
+window.addEventListener('message', function (e) {
+ if (e.data === 'postmessage') {
+ receivedScheduledPostMessage = true;
+ if (receivedHashchangeMessage)
+ alert('FAIL: hashchange already triggered!');
+ else
+ alert('PASS: scheduled postMessage() before hashchange triggered.');
+ } else {
+ receivedHashchangeMessage = true;
+ if (receivedScheduledPostMessage)
+ alert('PASS: hashchange triggered after postMessage().');
+ else
+ alert('FAIL: hashchange triggered before postMessage().');
+ testRunner.notifyDone();
+ }
+});
+
+function onloadFired() {
+ alert("iframe onload fired");
+}
+</script>
+<p>This tests that cross-origin-initiated fragment navigations are asynchronous
+and always fire the load event at their embedding iframe element if it's cross-origin. It does
+so by scheduling a postMessage before scheduling the navigation. If the
+navigation is synchronous, the internals API will be able to report the presence
+of an url fragment immediately.</p>
+<iframe src="http://localhost:8000/navigation/resources/postmessage-on-hashchange.html" onload="onloadFired()"></iframe>
</body>
</html>
diff --git a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt
index c1c1143026cad5cfe51829a8c34d61c01a63ffbf..5a6ccc855e14417df8039f18dba7aa0474ff552d 100644
--- a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt
+++ b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync-expected.txt
@@ -1,3 +1,4 @@
+ALERT: iframe onload fired
ALERT: PASS: url fragment has changed synchronously
ALERT: PASS: scheduled postMessage() before hashchange triggered.
ALERT: PASS: hashchange triggered after postMessage().
diff --git a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html
index 0ffe3cc8759e8e0ff4df7cad66c93cd5e2cbbe69..2cb9143bfce9a28d8803b49cf6afa7403554cdf4 100644
--- a/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html
+++ b/third_party/blink/web_tests/http/tests/navigation/same-origin-fragment-navigation-is-sync.html
@@ -36,6 +36,11 @@
testRunner.notifyDone();
}
});
+
+ function onloadFired() {
+ alert("iframe onload fired");
+ testFragmentNavigation();
+ }
</script>
</head>
<body>
@@ -43,6 +48,6 @@
so by scheduling a postMessage before scheduling the navigation. If the
navigation is synchronous, the internals API will be able to report the presence
of an url fragment immediately.</p>
- <iframe src="http://127.0.0.1:8000/navigation/resources/postmessage-on-hashchange.html" onload='testFragmentNavigation()'></iframe>
+ <iframe src="http://127.0.0.1:8000/navigation/resources/postmessage-on-hashchange.html" onload='onloadFired()'></iframe>
</body>
</html>

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,127 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Justin Novosad <junov@chromium.org>
Date: Fri, 14 Jan 2022 15:26:55 +0000
Subject: Fix ImageBitmapRenderingContext interaction with software compositor.
Before this CL, there was an early exit condition that prevented
texture-backed resources from being presented to the software compositor
even when the texture backing is swiftshader. This meant that in some
cases, ImageBitmaps that were created by webGL contexts would fail to
render. Once the early exit removed, there were other bugs due to the
fact that bitmaps were not being converted to N32 format before being
dispatched to the software compositor. This could cause several types
of rendering artifacts, including leaking bitmap data between contexts.
BUG=1283434
Change-Id: I6f353bc6301b79d7a4124445c85956125135f539
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3387268
Reviewed-by: Juanmi Huertas <juanmihd@chromium.org>
Commit-Queue: Justin Novosad <junov@chromium.org>
Cr-Commit-Position: refs/heads/main@{#959192}
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
index 722c88e5704fc21fb711ffdd3c4179449de9303b..2b126c41c5e231b6b88f058eef564b9388c67267 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -137,13 +137,9 @@ bool ImageLayerBridge::PrepareTransferableResource(
has_presented_since_last_set_image_ = true;
- bool gpu_compositing = SharedGpuContext::IsGpuCompositingEnabled();
+ const bool gpu_compositing = SharedGpuContext::IsGpuCompositingEnabled();
bool gpu_image = image_->IsTextureBacked();
- // Expect software images for software compositing.
- if (!gpu_compositing && gpu_image)
- return false;
-
// If the texture comes from a software image then it does not need to be
// flipped.
layer_->SetFlipped(gpu_image);
@@ -210,14 +206,17 @@ bool ImageLayerBridge::PrepareTransferableResource(
return false;
const gfx::Size size(image_->width(), image_->height());
- viz::ResourceFormat resource_format = viz::RGBA_8888;
- if (sk_image->colorType() == SkColorType::kRGBA_F16_SkColorType)
- resource_format = viz::RGBA_F16;
+
+ // Always convert to N32 format. This is a constraint of the software
+ // compositor.
+ constexpr SkColorType dst_color_type = kN32_SkColorType;
+ viz::ResourceFormat resource_format =
+ viz::SkColorTypeToResourceFormat(dst_color_type);
RegisteredBitmap registered =
CreateOrRecycleBitmap(size, resource_format, bitmap_registrar);
SkImageInfo dst_info =
- SkImageInfo::Make(size.width(), size.height(), sk_image->colorType(),
+ SkImageInfo::Make(size.width(), size.height(), dst_color_type,
kPremul_SkAlphaType, sk_image->refColorSpace());
void* pixels = registered.bitmap->memory();
@@ -246,8 +245,8 @@ ImageLayerBridge::RegisteredBitmap ImageLayerBridge::CreateOrRecycleBitmap(
recycled_bitmaps_.begin(), recycled_bitmaps_.end(),
[&size, &format](const RegisteredBitmap& registered) {
unsigned src_bytes_per_pixel =
- (registered.bitmap->format() == viz::RGBA_8888) ? 4 : 8;
- unsigned target_bytes_per_pixel = (format == viz::RGBA_8888) ? 4 : 8;
+ viz::BitsPerPixel(registered.bitmap->format()) / 8;
+ unsigned target_bytes_per_pixel = viz::BitsPerPixel(format) / 8;
return (registered.bitmap->size().GetArea() * src_bytes_per_pixel !=
size.GetArea() * target_bytes_per_pixel);
});
diff --git a/third_party/blink/web_tests/fast/canvas/bug1283434-expected.html b/third_party/blink/web_tests/fast/canvas/bug1283434-expected.html
new file mode 100644
index 0000000000000000000000000000000000000000..d0046a6c5ede6804497107318650f5f452b0d5e2
--- /dev/null
+++ b/third_party/blink/web_tests/fast/canvas/bug1283434-expected.html
@@ -0,0 +1,11 @@
+
+<!doctype html>
+<html>
+<head>
+</head>
+<body>
+<p>The two squares below should be filled in blue.</p>
+<canvas id="c" width="100" height="100" style="background-color: #00f;"></canvas>
+<canvas id="c2" width="100" height="100" style="background-color: #00f;"></canvas>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/fast/canvas/bug1283434.html b/third_party/blink/web_tests/fast/canvas/bug1283434.html
new file mode 100644
index 0000000000000000000000000000000000000000..b07298cbcb356b7fb34e3923259c3365e3a976fb
--- /dev/null
+++ b/third_party/blink/web_tests/fast/canvas/bug1283434.html
@@ -0,0 +1,28 @@
+
+<!doctype html>
+<html>
+<head>
+</head>
+<body>
+<p>The two squares below should be filled in blue.</p>
+<canvas id="c" width="100" height="100" style="background-color: red;"></canvas>
+<canvas id="c2" width="100" height="100" style="background-color: red;"></canvas>
+<script>
+ const canvas = document.getElementById('c');
+ const canvas2 = document.getElementById('c2');
+ const renderer = canvas.getContext('bitmaprenderer');
+ const renderer2 = canvas2.getContext('2d');
+
+ const temp_canvas = new OffscreenCanvas(640, 480);
+ const gl = temp_canvas.getContext('webgl');
+
+ gl.clearColor(0.0, 0.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ const bitmap = temp_canvas.transferToImageBitmap();
+
+ renderer2.drawImage(bitmap, 0, 0);
+ renderer.transferFromImageBitmap(bitmap);
+</script>
+</body>
+</html>
\ No newline at end of file

View File

@@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: clavin <cwatford@slack-corp.com>
Date: Fri, 11 Feb 2022 15:05:42 -0700
Subject: fix: non-client mouse tracking and message bubbling on windows
It is not known why, but for some reason calling |DefWindowProc| on the parent
window handle causes a WM_NCMOUSELEAVE (non-client mouse exit) message to be
sent to the parent window, even though |TrackMouseEvent| is never called on it.
This patch also adds some boilerplate for properly tracking non-client mouse
messages in the legacy window handle layer.
These conditions are regularly hit with WCO-enabled windows on Windows.
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc
index 8b196e1a10c96443a912eaaeb9327982618efa41..2f6939a6af34b901a8d1743a8559d5c3bfdb2d04 100644
--- a/content/browser/renderer_host/legacy_render_widget_host_win.cc
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -288,12 +288,12 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
WPARAM w_param,
LPARAM l_param,
BOOL& handled) {
- if (message == WM_MOUSEMOVE) {
+ if (message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE) {
if (!mouse_tracking_enabled_) {
mouse_tracking_enabled_ = true;
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
- tme.dwFlags = TME_LEAVE;
+ tme.dwFlags = message == WM_NCMOUSEMOVE ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE;
tme.hwndTrack = hwnd();
tme.dwHoverTime = 0;
TrackMouseEvent(&tme);
@@ -324,7 +324,10 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
// out of the picture.
if (!handled &&
(message >= WM_NCMOUSEMOVE && message <= WM_NCXBUTTONDBLCLK)) {
- ret = ::DefWindowProc(GetParent(), message, w_param, l_param);
+ // Send WM_NCMOUSEMOVE messages using the LegacyRenderWidgetHostHWND's
+ // handle so mouse tracking on non-client areas doesn't break.
+ HWND target = message == WM_NCMOUSEMOVE ? hwnd() : GetParent();
+ ret = ::DefWindowProc(target, message, w_param, l_param);
handled = TRUE;
}
}
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.h b/content/browser/renderer_host/legacy_render_widget_host_win.h
index 026e8b93602766e8d8e4a04f467b68ce3cea92de..83ca674adb6c6bf5e16d38b12aa33dddbf685bd8 100644
--- a/content/browser/renderer_host/legacy_render_widget_host_win.h
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.h
@@ -100,6 +100,7 @@ class CONTENT_EXPORT LegacyRenderWidgetHostHWND
MESSAGE_HANDLER_EX(WM_NCHITTEST, OnNCHitTest)
MESSAGE_RANGE_HANDLER(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK,
OnMouseRange)
+ MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseLeave)
MESSAGE_HANDLER_EX(WM_NCCALCSIZE, OnNCCalcSize)
MESSAGE_HANDLER_EX(WM_SIZE, OnSize)
MESSAGE_HANDLER_EX(WM_DESTROY, OnDestroy)

View File

@@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dominic Battre <battre@chromium.org>
Date: Wed, 22 Dec 2021 16:25:16 +0000
Subject: Fix preview state detection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This CL fixes the preview state detection in some edge cases. See
crbug.com/1261689#c23.
(cherry picked from commit e3aeadcf584ebb5d7f61cd141f9af317cb60cf21)
Fixed: 1261689
Change-Id: Iefe27e2748acb4b524e8a0811973bdceda46089a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3335637
Reviewed-by: Mason Freed <masonf@chromium.org>
Commit-Queue: Dominic Battré <battre@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#951313}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3348406
Auto-Submit: Dominic Battré <battre@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/branch-heads/4758@{#186}
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index daa9e25f645f9d554dd85ed4199bc80bf3a7e049..4bf8054f5b6382bbef85b83996dbb6b48dfc2f74 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -36,6 +36,7 @@
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
+#include "third_party/blink/public/web/web_autofill_state.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_get_inner_html_options.h"
@@ -1560,7 +1561,7 @@ double Element::scrollTop() {
// Don't disclose scroll position in preview state. See crbug.com/1261689.
auto* select_element = DynamicTo<HTMLSelectElement>(this);
if (select_element && !select_element->UsesMenuList() &&
- !select_element->SuggestedValue().IsEmpty()) {
+ select_element->GetAutofillState() == WebAutofillState::kPreviewed) {
return 0;
}

View File

@@ -0,0 +1,553 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robin Ebert <ebertrobin2002@gmail.com>
Date: Tue, 22 Feb 2022 12:49:55 +0100
Subject: Fixed terminate caused by binding to wrong version.
The Ozone/Wayland implementation had a few places where the Wayland
objects were bound without proper checking for their versions. That was
part of the technical debt not addressed before, and ended up causing
the issue explained in the linked crbug: the compositor terminates the
client that binds to the protocol that it does not actually support.
This patch fixes the issue by adding the necessary checks in all places
where they were missing. Also a convenience macro for validating the
version is proposed.
Backport of dd4c3ddadbb9869f59cee201a38e9ca3b9154f4d from chromium
diff --git a/ui/ozone/platform/wayland/common/wayland_object.cc b/ui/ozone/platform/wayland/common/wayland_object.cc
index 0f21da447e43125c85b15a4254d7e047409e2e57..109fea03294a9bcbcc335d4c7d3250179f13f9bd 100644
--- a/ui/ozone/platform/wayland/common/wayland_object.cc
+++ b/ui/ozone/platform/wayland/common/wayland_object.cc
@@ -29,6 +29,8 @@
#include <xdg-shell-client-protocol.h>
#include <xdg-shell-unstable-v6-client-protocol.h>
+#include "base/logging.h"
+
namespace wl {
namespace {
@@ -71,6 +73,19 @@ void delete_touch(wl_touch* touch) {
} // namespace
+bool CanBind(uint32_t available_version,
+ uint32_t min_version,
+ uint32_t max_version) {
+ if (available_version < min_version) {
+ LOG(WARNING) << "Error in binding wayland interface."
+ << available_version << ". The minimum supported version is "
+ << min_version << ".";
+ return false;
+ }
+
+ return true;
+}
+
void (*ObjectTraits<wl_cursor_theme>::deleter)(wl_cursor_theme*) =
&wl_cursor_theme_destroy;
diff --git a/ui/ozone/platform/wayland/common/wayland_object.h b/ui/ozone/platform/wayland/common/wayland_object.h
index 88a5c0551402131357168c788787a0fddb24d747..465ac9633841b297ecdfe31df4b569773fdf2918 100644
--- a/ui/ozone/platform/wayland/common/wayland_object.h
+++ b/ui/ozone/platform/wayland/common/wayland_object.h
@@ -86,6 +86,16 @@ struct ObjectTraits<wl_proxy> {
static void (*deleter)(void*);
};
+// Checks the given |available_version| exposed by the server against
+// |min_version| and |max_version| supported by the client.
+// Returns false (with rendering a warning) if |available_version| is less than
+// the minimum supported version.
+// Returns true otherwise, renders an info message if |available_version| is
+// greater than the maximum supported one.
+bool CanBind(uint32_t available_version,
+ uint32_t min_version,
+ uint32_t max_version);
+
} // namespace wl
// Puts the forward declaration for struct TYPE and declares the template
diff --git a/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc b/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc
index 8822c0a57ebd5cdc5044c3746e6b17abd6898621..3dcb157031df12e36109bda1048cd0c57de23a41 100644
--- a/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc
+++ b/ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.cc
@@ -16,7 +16,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxGtkPrimarySelectionDeviceManagerVersion = 1;
+constexpr uint32_t kMinVersion = 1;
}
// static
@@ -32,12 +32,13 @@ void GtkPrimarySelectionDeviceManager::Instantiate(
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->gtk_primary_selection_device_manager())
- return;
+ if (connection->gtk_primary_selection_device_manager() ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
+ return;
+ }
- auto manager = wl::Bind<gtk_primary_selection_device_manager>(
- registry, name,
- std::min(version, kMaxGtkPrimarySelectionDeviceManagerVersion));
+ auto manager = wl::Bind<gtk_primary_selection_device_manager>(registry, name,
+ kMinVersion);
if (!manager) {
LOG(ERROR) << "Failed to bind gtk_primary_selection_device_manager";
return;
diff --git a/ui/ozone/platform/wayland/host/gtk_shell1.cc b/ui/ozone/platform/wayland/host/gtk_shell1.cc
index 88126d9dd6e6770747059b77fb68f96b051176a7..20afad639e26d63c1e4c039f25a833deb9595425 100644
--- a/ui/ozone/platform/wayland/host/gtk_shell1.cc
+++ b/ui/ozone/platform/wayland/host/gtk_shell1.cc
@@ -17,8 +17,8 @@ namespace {
// gtk_shell1 exposes request_focus() since version 3. Below that, it is not
// interesting for us, although it provides some shell integration that might be
// useful.
-constexpr uint32_t kMinGtkShell1Version = 3;
-constexpr uint32_t kMaxGtkShell1Version = 4;
+constexpr uint32_t kMinVersion = 3;
+constexpr uint32_t kMaxVersion = 4;
} // namespace
// static
@@ -32,11 +32,13 @@ void GtkShell1::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->gtk_shell1_ || version < kMinGtkShell1Version)
- return;
+ if (connection->gtk_shell1_ ||
+ !wl::CanBind(version, kMinVersion, kMaxVersion)) {
+ return;
+ }
auto gtk_shell1 = wl::Bind<::gtk_shell1>(
- registry, name, std::min(version, kMaxGtkShell1Version));
+ registry, name, std::min(version, kMaxVersion));
if (!gtk_shell1) {
LOG(ERROR) << "Failed to bind gtk_shell1";
return;
diff --git a/ui/ozone/platform/wayland/host/org_kde_kwin_idle.cc b/ui/ozone/platform/wayland/host/org_kde_kwin_idle.cc
index d990c810be430462cfe1a66460350fe1c548fbb8..ec225d49ecfbf0c349f15663d5acd3bc0620584f 100644
--- a/ui/ozone/platform/wayland/host/org_kde_kwin_idle.cc
+++ b/ui/ozone/platform/wayland/host/org_kde_kwin_idle.cc
@@ -13,7 +13,7 @@ namespace ui {
namespace {
-constexpr uint32_t kMaxOrgKdeKwinIdleVersion = 1;
+constexpr uint32_t kMinVersion = 1;
// After the system has gone idle, it will wait for this time before notifying
// us. This reduces "jitter" of the idle/active state, but also adds some lag
@@ -58,11 +58,13 @@ void OrgKdeKwinIdle::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->org_kde_kwin_idle_)
- return;
+ if (connection->org_kde_kwin_idle_ ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
+ return;
+ }
auto idle = wl::Bind<struct org_kde_kwin_idle>(
- registry, name, std::min(version, kMaxOrgKdeKwinIdleVersion));
+ registry, name, kMinVersion);
if (!idle) {
LOG(ERROR) << "Failed to bind to org_kde_kwin_idle global";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device_manager.cc b/ui/ozone/platform/wayland/host/wayland_data_device_manager.cc
index 036512a39fa776d3c76c8dc6e29163224838c30b..6acc02f8348e5aaf1b20c1064bb10d31c32da26d 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_device_manager.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_device_manager.cc
@@ -14,7 +14,8 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxDeviceManagerVersion = 3;
+constexpr uint32_t kMinVersion = 1;
+constexpr uint32_t kMaxVersion = 3;
}
// static
@@ -28,11 +29,13 @@ void WaylandDataDeviceManager::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->data_device_manager_)
- return;
+ if (connection->data_device_manager_ ||
+ !wl::CanBind(version, kMinVersion, kMaxVersion)) {
+ return;
+ }
auto data_device_manager = wl::Bind<wl_data_device_manager>(
- registry, name, std::min(version, kMaxDeviceManagerVersion));
+ registry, name, std::min(version, kMaxVersion));
if (!data_device_manager) {
LOG(ERROR) << "Failed to bind to wl_data_device_manager global";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_drm.cc b/ui/ozone/platform/wayland/host/wayland_drm.cc
index cb1062d47d035672e1b730fc7011185daaa162c2..852b516e1b8f86ef4e741d1a70f67541cba7def3 100644
--- a/ui/ozone/platform/wayland/host/wayland_drm.cc
+++ b/ui/ozone/platform/wayland/host/wayland_drm.cc
@@ -17,7 +17,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMinWlDrmVersion = 2;
+constexpr uint32_t kMinVersion = 2;
}
// static
@@ -30,10 +30,12 @@ void WaylandDrm::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->drm_ || version < kMinWlDrmVersion)
- return;
+ if (connection->drm_ ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
+ return;
+ }
- auto wl_drm = wl::Bind<struct wl_drm>(registry, name, version);
+ auto wl_drm = wl::Bind<struct wl_drm>(registry, name, kMinVersion);
if (!wl_drm) {
LOG(ERROR) << "Failed to bind wl_drm";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_output.cc b/ui/ozone/platform/wayland/host/wayland_output.cc
index 0316abe49f9f6c289cfbac2ed94e47b93a7b1f1f..344974d33af6b97120e8143b1931ee59a08111f5 100644
--- a/ui/ozone/platform/wayland/host/wayland_output.cc
+++ b/ui/ozone/platform/wayland/host/wayland_output.cc
@@ -13,7 +13,8 @@
namespace ui {
namespace {
-constexpr uint32_t kMinWlOutputVersion = 2;
+// TODO(crbug.com/1279681): support newer versions.
+constexpr uint32_t kMinVersion = 2;
}
// static
@@ -27,14 +28,11 @@ void WaylandOutput::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (version < kMinWlOutputVersion) {
- LOG(ERROR)
- << "Unable to bind to the unsupported wl_output object with version= "
- << version << ". Minimum supported version is " << kMinWlOutputVersion;
+ if (!wl::CanBind(version, kMinVersion, kMinVersion)) {
return;
}
- auto output = wl::Bind<wl_output>(registry, name, version);
+ auto output = wl::Bind<wl_output>(registry, name, kMinVersion);
if (!output) {
LOG(ERROR) << "Failed to bind to wl_output global";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_shm.cc b/ui/ozone/platform/wayland/host/wayland_shm.cc
index 27afbcfb25d9c73d4d832bd4ac9e57629451e35a..8f05786d7beb6a8f7458bf37cf0417d6a76b682a 100644
--- a/ui/ozone/platform/wayland/host/wayland_shm.cc
+++ b/ui/ozone/platform/wayland/host/wayland_shm.cc
@@ -10,7 +10,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxShmVersion = 1;
+constexpr uint32_t kMinVersion = 1;
constexpr uint32_t kShmFormat = WL_SHM_FORMAT_ARGB8888;
} // namespace
@@ -24,11 +24,13 @@ void WaylandShm::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->shm_)
+ if (connection->shm_ ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
return;
+ }
auto shm =
- wl::Bind<wl_shm>(registry, name, std::min(version, kMaxShmVersion));
+ wl::Bind<wl_shm>(registry, name, kMinVersion);
if (!shm) {
LOG(ERROR) << "Failed to bind to wl_shm global";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc b/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc
index 9bc924f6baaf41288bfd616bb4f3eb4d37492c5f..29e32ed739233a91d57838e33f2fe3a7f5ecdaed 100644
--- a/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc
@@ -18,7 +18,8 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxAuraShellVersion = 22;
+constexpr uint32_t kMinVersion = 1;
+constexpr uint32_t kMaxVersion = 22;
}
// static
@@ -32,11 +33,13 @@ void WaylandZAuraShell::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->zaura_shell_)
- return;
+ if (connection->zaura_shell_ ||
+ !wl::CanBind(version, kMinVersion, kMaxVersion)) {
+ return;
+ }
auto zaura_shell = wl::Bind<struct zaura_shell>(
- registry, name, std::min(version, kMaxAuraShellVersion));
+ registry, name, std::min(version, kMaxVersion));
if (!zaura_shell) {
LOG(ERROR) << "Failed to bind zaura_shell";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_zcr_cursor_shapes.cc b/ui/ozone/platform/wayland/host/wayland_zcr_cursor_shapes.cc
index 651e4f8154e47aeaac8860bf8ec58583cdb64862..28c43f2fc43be89b92496c5a5d084455c80c0cbd 100644
--- a/ui/ozone/platform/wayland/host/wayland_zcr_cursor_shapes.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zcr_cursor_shapes.cc
@@ -16,7 +16,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxCursorShapesVersion = 1;
+constexpr uint32_t kMinVersion = 1;
}
using mojom::CursorType;
@@ -32,11 +32,13 @@ void WaylandZcrCursorShapes::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->zcr_cursor_shapes_)
- return;
+ if (connection->zcr_cursor_shapes_ ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
+ return;
+ }
auto zcr_cursor_shapes = wl::Bind<zcr_cursor_shapes_v1>(
- registry, name, std::min(version, kMaxCursorShapesVersion));
+ registry, name, kMinVersion);
if (!zcr_cursor_shapes) {
LOG(ERROR) << "Failed to bind zcr_cursor_shapes_v1";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc
index edc00fc587f1c6011171460e0c055191e642befb..34f93335267ba082a013e694e870bfe03e698fc1 100644
--- a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc
@@ -14,7 +14,8 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxLinuxDmabufVersion = 3;
+constexpr uint32_t kMinVersion = 1;
+constexpr uint32_t kMaxVersion = 3;
}
// static
@@ -28,11 +29,13 @@ void WaylandZwpLinuxDmabuf::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->zwp_dmabuf())
- return;
+ if (connection->zwp_dmabuf() ||
+ !wl::CanBind(version, kMinVersion, kMaxVersion)) {
+ return;
+ }
auto zwp_linux_dmabuf = wl::Bind<zwp_linux_dmabuf_v1>(
- registry, name, std::min(version, kMaxLinuxDmabufVersion));
+ registry, name, std::min(version, kMaxVersion));
if (!zwp_linux_dmabuf) {
LOG(ERROR) << "Failed to bind zwp_linux_dmabuf_v1";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_constraints.cc b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_constraints.cc
index b0c35447917eea2c9031e24e7e03efd0999afba7..25f497db50fe1161e8bb7d162b711f583e6c482e 100644
--- a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_constraints.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_constraints.cc
@@ -15,7 +15,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMinZwpPointerConstraintsVersion = 1;
+constexpr uint32_t kMinVersion = 1;
}
// static
@@ -30,12 +30,12 @@ void WaylandZwpPointerConstraints::Instantiate(WaylandConnection* connection,
uint32_t name,
uint32_t version) {
if (connection->wayland_zwp_pointer_constraints_ ||
- version < kMinZwpPointerConstraintsVersion) {
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
return;
}
auto zwp_pointer_constraints_v1 =
- wl::Bind<struct zwp_pointer_constraints_v1>(registry, name, version);
+ wl::Bind<struct zwp_pointer_constraints_v1>(registry, name, kMinVersion);
if (!zwp_pointer_constraints_v1) {
LOG(ERROR) << "Failed to bind wp_pointer_constraints_v1";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc
index 86a0d3aabdf23f43463c5cc2c72b31fc31da8f04..ceac0b99d4534b64a67eff04c2ab10611656a0e8 100644
--- a/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.cc
@@ -19,7 +19,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMinZwpPointerGesturesVersion = 1;
+constexpr uint32_t kMinVersion = 1;
}
// static
@@ -34,11 +34,12 @@ void WaylandZwpPointerGestures::Instantiate(WaylandConnection* connection,
uint32_t name,
uint32_t version) {
if (connection->wayland_zwp_pointer_gestures_ ||
- version < kMinZwpPointerGesturesVersion)
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
return;
+ }
auto zwp_pointer_gestures_v1 =
- wl::Bind<struct zwp_pointer_gestures_v1>(registry, name, version);
+ wl::Bind<struct zwp_pointer_gestures_v1>(registry, name, kMinVersion);
if (!zwp_pointer_gestures_v1) {
LOG(ERROR) << "Failed to bind wp_pointer_gestures_v1";
return;
diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_relative_pointer_manager.cc b/ui/ozone/platform/wayland/host/wayland_zwp_relative_pointer_manager.cc
index 26c9cc387ae085d1bee35baab7a53e82be499799..0283b3630866fc4f32e16dc47a16fee5ac93e5a7 100644
--- a/ui/ozone/platform/wayland/host/wayland_zwp_relative_pointer_manager.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zwp_relative_pointer_manager.cc
@@ -14,7 +14,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMinZwpRelativePointerManagerVersion = 1;
+constexpr uint32_t kMinVersion = 1;
}
// static
@@ -31,11 +31,13 @@ void WaylandZwpRelativePointerManager::Instantiate(
uint32_t name,
uint32_t version) {
if (connection->wayland_zwp_relative_pointer_manager_ ||
- version < kMinZwpRelativePointerManagerVersion)
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
return;
+ }
auto zwp_relative_pointer_manager_v1 =
- wl::Bind<struct zwp_relative_pointer_manager_v1>(registry, name, version);
+ wl::Bind<struct zwp_relative_pointer_manager_v1>(registry, name,
+ kMinVersion);
if (!zwp_relative_pointer_manager_v1) {
LOG(ERROR) << "Failed to bind zwp_relative_pointer_manager_v1";
return;
diff --git a/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc b/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc
index 43a419c125f13a749bd5769eba66fa052a5b300c..188ff4a61685a53705b2da2773cd583a1127fe22 100644
--- a/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc
+++ b/ui/ozone/platform/wayland/host/xdg_foreign_wrapper.cc
@@ -11,6 +11,8 @@
#include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/platform_window/platform_window_init_properties.h"
+constexpr uint32_t kMinVersion = 1;
+
namespace ui {
// static
@@ -24,10 +26,12 @@ void XdgForeignWrapper::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->xdg_foreign_)
- return;
+ if (connection->xdg_foreign_ ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
+ return;
+ }
- auto zxdg_exporter = wl::Bind<zxdg_exporter_v1>(registry, name, version);
+ auto zxdg_exporter = wl::Bind<zxdg_exporter_v1>(registry, name, kMinVersion);
if (!zxdg_exporter) {
LOG(ERROR) << "Failed to bind zxdg_exporter";
return;
diff --git a/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.cc b/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.cc
index ef9cf6fd6934ffd20c7d8f80bcb3f08c9e2e43d9..678f08e63d29b2388292729c6b77dbf163a6d007 100644
--- a/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.cc
+++ b/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.cc
@@ -12,7 +12,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxZwpIdleInhibitManagerVersion = 1;
+constexpr uint32_t kMinVersion = 1;
}
// static
@@ -26,11 +26,13 @@ void ZwpIdleInhibitManager::Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->zwp_idle_inhibit_manager_)
- return;
+ if (connection->zwp_idle_inhibit_manager_ ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
+ return;
+ }
- auto manager = wl::Bind<zwp_idle_inhibit_manager_v1>(
- registry, name, std::min(version, kMaxZwpIdleInhibitManagerVersion));
+ auto manager =
+ wl::Bind<zwp_idle_inhibit_manager_v1>(registry, name, kMinVersion);
if (!manager) {
LOG(ERROR) << "Failed to bind zwp_idle_inhibit_manager_v1";
return;
diff --git a/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc b/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc
index 0bae8670c33bc2998e29613e7647c167b4a3b957..e7a138942c955ce432e75d155b6a80b455d3243e 100644
--- a/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc
+++ b/ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.cc
@@ -16,7 +16,7 @@
namespace ui {
namespace {
-constexpr uint32_t kMaxGtkPrimarySelectionDeviceManagerVersion = 1;
+constexpr uint32_t kMinVersion = 1;
} // namespace
// static
@@ -32,12 +32,12 @@ void ZwpPrimarySelectionDeviceManager::Instantiate(
wl_registry* registry,
uint32_t name,
uint32_t version) {
- if (connection->zwp_primary_selection_device_manager_)
- return;
-
+ if (connection->zwp_primary_selection_device_manager_ ||
+ !wl::CanBind(version, kMinVersion, kMinVersion)) {
+ return;
+ }
auto manager = wl::Bind<zwp_primary_selection_device_manager_v1>(
- registry, name,
- std::min(version, kMaxGtkPrimarySelectionDeviceManagerVersion));
+ registry, name, kMinVersion);
if (!manager) {
LOG(ERROR) << "Failed to bind zwp_primary_selection_device_manager_v1";
return;

View File

@@ -0,0 +1,68 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robin Ebert <ebertrobin2002@gmail.com>
Date: Tue, 22 Feb 2022 18:12:22 +0100
Subject: Follow wayland specification regarding xkb keymap.
The wayland specification expects client to mmap the xkb keymap file descriptor with MAP_PRIVATE.
This fixes mapping issues regarding file descriptor permissions.
diff --git a/ui/ozone/platform/wayland/host/wayland_keyboard.cc b/ui/ozone/platform/wayland/host/wayland_keyboard.cc
index 272322210b59228e5faa606101957c48c6371249..1c661e1ed92428f7c810fe4c041e91a08a0901e5 100644
--- a/ui/ozone/platform/wayland/host/wayland_keyboard.cc
+++ b/ui/ozone/platform/wayland/host/wayland_keyboard.cc
@@ -4,11 +4,12 @@
#include "ui/ozone/platform/wayland/host/wayland_keyboard.h"
+#include <sys/mman.h>
+
#include <utility>
#include "base/files/scoped_file.h"
#include "base/logging.h"
-#include "base/memory/unsafe_shared_memory_region.h"
#include "base/unguessable_token.h"
#include "ui/base/buildflags.h"
#include "ui/events/base_event_utils.h"
@@ -111,26 +112,28 @@ WaylandKeyboard::~WaylandKeyboard() {
void WaylandKeyboard::Keymap(void* data,
wl_keyboard* obj,
uint32_t format,
- int32_t keymap_fd,
+ int32_t fd,
uint32_t size) {
WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data);
DCHECK(keyboard);
- base::ScopedFD fd(keymap_fd);
- auto length = size - 1;
- auto shmen = base::subtle::PlatformSharedMemoryRegion::Take(
- std::move(fd), base::subtle::PlatformSharedMemoryRegion::Mode::kUnsafe,
- length, base::UnguessableToken::Create());
- auto mapped_memory =
- base::UnsafeSharedMemoryRegion::Deserialize(std::move(shmen)).Map();
- const char* keymap = mapped_memory.GetMemoryAs<char>();
+ if (!data || format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
+ return;
+ }
- if (!keymap || format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
+ void* keymap = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (keymap == MAP_FAILED) {
+ DPLOG(ERROR) << "Failed to map XKB keymap.";
return;
+ }
- bool success = keyboard->layout_engine_->SetCurrentLayoutFromBuffer(
- keymap, mapped_memory.size());
- DCHECK(success) << "Failed to set the XKB keyboard mapping.";
+ const char* keymap_string = static_cast<const char*>(keymap);
+ if (!keyboard->layout_engine_->SetCurrentLayoutFromBuffer(
+ keymap_string, strnlen(keymap_string, size))) {
+ DLOG(ERROR) << "Failed to set XKB keymap.";
+ }
+ munmap(keymap, size);
+ close(fd);
}
void WaylandKeyboard::Enter(void* data,

View File

@@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rune Lillesveen <futhark@chromium.org>
Date: Fri, 15 Oct 2021 14:33:17 +0000
Subject: Handle PotentiallyDanglingMarkup() for CSSImageValue
The flag was lost in the KURL -> String -> KURL conversions. Store the
flag on CSSImageValue and always re-resolve from the original relative
url before fetching when that flag is set. The blocking happens in
BaseFetchContext::CanRequestInternal().
Bug: 1039885
Change-Id: Ia5777739a0ee0bee591163873926d19e0ea014bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3226142
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#932004}
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni
index d170dc0a9cdb6e7cfcd0979b8a4832e4fc8059f8..363301d60de1d206669a29dc27b9c58ec3d68c7a 100644
--- a/third_party/blink/renderer/core/css/build.gni
+++ b/third_party/blink/renderer/core/css/build.gni
@@ -638,6 +638,7 @@ blink_core_tests_css = [
"css_font_face_source_test.cc",
"css_gradient_value_test.cc",
"css_id_selector_value_test.cc",
+ "css_image_value_test.cc",
"css_invalid_variable_value_test.cc",
"css_light_dark_value_pair_test.cc",
"css_math_expression_node_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_image_value.cc b/third_party/blink/renderer/core/css/css_image_value.cc
index 81fe3aa1175a31d5c6f3611ec6bd2a27f71e900d..732b48f787d782779e5fea8bf60a55ca3f7fe95d 100644
--- a/third_party/blink/renderer/core/css/css_image_value.cc
+++ b/third_party/blink/renderer/core/css/css_image_value.cc
@@ -51,7 +51,8 @@ CSSImageValue::CSSImageValue(const AtomicString& raw_value,
absolute_url_(url.GetString()),
cached_image_(image),
origin_clean_(origin_clean),
- is_ad_related_(is_ad_related) {}
+ is_ad_related_(is_ad_related),
+ potentially_dangling_markup_(url.PotentiallyDanglingMarkup()) {}
CSSImageValue::~CSSImageValue() = default;
@@ -59,7 +60,17 @@ FetchParameters CSSImageValue::PrepareFetch(
const Document& document,
FetchParameters::ImageRequestBehavior image_request_behavior,
CrossOriginAttributeValue cross_origin) const {
- ResourceRequest resource_request(absolute_url_);
+ // The PotentiallyDanglingMarkup() flag is lost when storing the absolute url
+ // as a string from which the KURL is constructed here.
+ // The url passed into the constructor had the PotentiallyDanglingMarkup flag
+ // set. That information needs to be passed on to the fetch code to block such
+ // resources from loading.
+ KURL request_url = potentially_dangling_markup_
+ ? document.CompleteURL(relative_url_)
+ : KURL(absolute_url_);
+ SECURITY_CHECK(request_url.PotentiallyDanglingMarkup() ==
+ potentially_dangling_markup_);
+ ResourceRequest resource_request(request_url);
resource_request.SetReferrerPolicy(
ReferrerUtils::MojoReferrerPolicyResolveDefault(
referrer_.referrer_policy));
diff --git a/third_party/blink/renderer/core/css/css_image_value.h b/third_party/blink/renderer/core/css/css_image_value.h
index fca1d73c764412d2014bfd1fe4775937794c9e2d..f414195f4a543fb3f47c1fef3799161d13495507 100644
--- a/third_party/blink/renderer/core/css/css_image_value.h
+++ b/third_party/blink/renderer/core/css/css_image_value.h
@@ -102,6 +102,11 @@ class CORE_EXPORT CSSImageValue : public CSSValue {
// Whether this was created by an ad-related CSSParserContext.
const bool is_ad_related_;
+
+ // The url passed into the constructor had the PotentiallyDanglingMarkup flag
+ // set. That information needs to be passed on to the fetch code to block such
+ // resources from loading.
+ const bool potentially_dangling_markup_;
};
template <>
diff --git a/third_party/blink/renderer/core/css/css_image_value_test.cc b/third_party/blink/renderer/core/css/css_image_value_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..83415bd586e3187287dcb020ddafe4c7f8671a61
--- /dev/null
+++ b/third_party/blink/renderer/core/css/css_image_value_test.cc
@@ -0,0 +1,50 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_image_value.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+class CSSImageValueTest : public SimTest {};
+
+TEST_F(CSSImageValueTest, BlockPotentiallyDanglingMarkup) {
+ SimRequest main_resource("https://example.com", "text/html");
+
+ LoadURL("https://example.com");
+
+ main_resource.Complete(R"HTML(
+ <!doctype html>
+ <table id="t1" background="ht
+ tps://example.com/y<ay?foo"><td>XXX</td></table>
+ <table id="t2" background="ht
+ tps://example.com/y<ay?bar#boo"><td>XXX</td></table>
+ )HTML");
+
+ test::RunPendingTasks();
+ Compositor().BeginFrame();
+
+ auto* t1 = GetDocument().getElementById("t1");
+ ImageResourceContent* content1 =
+ t1->ComputedStyleRef().BackgroundLayers().GetImage()->CachedImage();
+ ASSERT_TRUE(content1);
+ EXPECT_TRUE(content1->ErrorOccurred());
+
+ auto* t2 = GetDocument().getElementById("t2");
+ ImageResourceContent* content2 =
+ t2->ComputedStyleRef().BackgroundLayers().GetImage()->CachedImage();
+ ASSERT_TRUE(content2);
+ EXPECT_TRUE(content2->ErrorOccurred());
+}
+
+} // namespace blink

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 fc723d2dd83aae8f2b1abdf9d5a00990bbee5293..04f2b584d20a37c0b7bd2fb6a0d3a7095f7d8a38 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
@@ -31,13 +31,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,
@@ -45,6 +42,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;
@@ -84,15 +83,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.
@@ -118,31 +120,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() {
@@ -150,6 +129,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());
@@ -158,6 +139,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());
@@ -166,8 +149,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;
@@ -178,9 +185,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,
@@ -188,7 +196,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);
@@ -256,10 +264,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 59b019a6ce9c6db896ab20f4684e8db117c289f8..eb4f778e72dcc32043628d5f03da17d27f34d062 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_BYTES_PROVIDER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_BYTES_PROVIDER_H_
+#include "base/sequence_checker.h"
#include "base/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"
@@ -16,8 +17,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:
@@ -25,19 +26,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;
@@ -50,17 +49,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 b62dca5e303898fbdbc4c931dfcbc7361504194a..75c769665148d8530742586f4cdd6eb98cf96e50 100644
--- a/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -106,6 +106,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_);
}
@@ -140,16 +146,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;
@@ -273,6 +269,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) {
@@ -284,9 +281,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 fa905f87ed4cee14909827e8f078f51bb91cfa61..805da754eb510224f67f719bb43ab281d702f5fb 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 8f1d08efa8e505fdb098742bd5b778a8b2b82213..9b8927b18bbe261afa2990ef7695cc33bdea53c5 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,42 @@
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 703dd4c1aee81aa8b05733b91d1de05b87ff1c0b..507595e2bb5d47128fc6e08dbadf21c43d36cdf0 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -582,13 +582,13 @@ error::Error WebGPUDecoderImpl::InitDawnDevice(
uint32_t device_generation,
const WGPUDeviceProperties& request_device_properties,
bool* creation_succeeded) {
- DCHECK_LE(0, requested_adapter_index);
-
- DCHECK_LT(static_cast<size_t>(requested_adapter_index),
- dawn_adapters_.size());
-
*creation_succeeded = false;
+ if (requested_adapter_index < 0 ||
+ static_cast<uint32_t>(requested_adapter_index) >= dawn_adapters_.size()) {
+ return error::kOutOfBounds;
+ }
+
dawn_native::DeviceDescriptor device_descriptor;
if (request_device_properties.textureCompressionBC) {
device_descriptor.requiredExtensions.push_back("texture_compression_bc");

View File

@@ -0,0 +1,93 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Cunningham <chcunningham@chromium.org>
Date: Tue, 30 Nov 2021 20:53:26 +0000
Subject: Various DecoderTemplate shutdown cleanups
1. Use DeleteSoon() when destroying the |decoder_| to avoid destructing
in error conditions where it's callback (OnDecodeDone()) is actively
executing.
2. Call Shutdown() from ContextDestroyed() to invoke full reset
algorithm and tidily clean up all state.
(cherry picked from commit b5e609d4e7a296fa8c2d50f1373e9f3a50003995)
Bug: 1267426
Change-Id: I927d8a3bd245b3f833e73c74103cbaacf6d73406
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3277273
Commit-Queue: Chrome Cunningham <chcunningham@chromium.org>
Auto-Submit: Chrome Cunningham <chcunningham@chromium.org>
Reviewed-by: Dan Sanders <sandersd@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#941390}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3308537
Commit-Queue: Dan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/branch-heads/4692@{#599}
Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
index fbb40f4a6a245706abcab1cc34595168f444528d..18e6d5f9f5675591dfcfa557f28bec72e41c276a 100644
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
@@ -79,8 +79,10 @@ DecoderTemplate<Traits>::DecoderTemplate(ScriptState* script_state,
ExecutionContext* context = GetExecutionContext();
DCHECK(context);
- logger_ = std::make_unique<CodecLogger>(
- context, context->GetTaskRunner(TaskType::kInternalMedia));
+ main_thread_task_runner_ =
+ context->GetTaskRunner(TaskType::kInternalMediaRealTime);
+
+ logger_ = std::make_unique<CodecLogger>(context, main_thread_task_runner_);
logger_->log()->SetProperty<media::MediaLogProperty::kFrameUrl>(
context->Url().GetString().Ascii());
@@ -504,8 +506,10 @@ void DecoderTemplate<Traits>::Shutdown(DOMException* exception) {
// Prevent any further logging from being reported.
logger_->Neuter();
- // Clear decoding and JS-visible queue state.
- decoder_.reset();
+ // Clear decoding and JS-visible queue state. Use DeleteSoon() to avoid
+ // deleting decoder_ when its callback (e.g. OnDecodeDone()) may be below us
+ // in the stack.
+ main_thread_task_runner_->DeleteSoon(FROM_HERE, std::move(decoder_));
if (pending_request_) {
// This request was added as part of calling ResetAlgorithm above. However,
@@ -722,9 +726,8 @@ void DecoderTemplate<Traits>::TraceQueueSizes() const {
template <typename Traits>
void DecoderTemplate<Traits>::ContextDestroyed() {
- state_ = V8CodecState(V8CodecState::Enum::kClosed);
- logger_->Neuter();
- decoder_.reset();
+ // Deallocate resources and supress late callbacks from media thread.
+ Shutdown();
}
template <typename Traits>
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.h b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
index bc186b60c84e2b4b76468f21a9305c5792796e7e..c16dbeee58048644291fe856e33573068da3c69f 100644
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template.h
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
@@ -29,6 +29,10 @@
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
+namespace base {
+class SingleThreadTaskRunner;
+}
+
namespace media {
class GpuVideoAcceleratorFactories;
class ScopedDecodeTrace;
@@ -227,6 +231,9 @@ class MODULES_EXPORT DecoderTemplate
// Keyframes are required after configure(), flush(), and reset().
bool require_key_frame_ = true;
+
+ // Task runner for main thread.
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
};
} // namespace blink

View File

@@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Sullivan <asully@chromium.org>
Date: Thu, 10 Feb 2022 22:18:54 +0000
Subject: M98: FS: Fix FileUtil lifetime issue
Keeps FileSystemContext alive while while resolving a URL on an open
file system, removing the possibility of the file system being
destroyed while a URL is being resolved on it.
(cherry picked from commit 3fdf2adf11b3c716c9015597d30b59bffc7ac91b)
Bug: 1275622, 1289394
Change-Id: Ic1b97552f9d41a61163d72ff8c605699f673f55f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3373583
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Commit-Queue: Austin Sullivan <asully@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#968470}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3451059
Auto-Submit: Austin Sullivan <asully@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/branch-heads/4758@{#1131}
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}
diff --git a/storage/browser/file_system/file_system_context.cc b/storage/browser/file_system/file_system_context.cc
index a9dff4886dc2697a5e146d3dae14dfd7137c8942..54dc48d097f37e62db188157bd928f85e2666fa9 100644
--- a/storage/browser/file_system/file_system_context.cc
+++ b/storage/browser/file_system/file_system_context.cc
@@ -430,9 +430,22 @@ void FileSystemContext::OpenFileSystem(const blink::StorageKey& storage_key,
return;
}
+ // Bind `this` to the callback to ensure this instance stays alive while the
+ // URL is resolving.
backend->ResolveURL(
CreateCrackedFileSystemURL(storage_key, type, base::FilePath()), mode,
- std::move(callback));
+ base::BindOnce(&FileSystemContext::DidResolveURLOnOpenFileSystem, this,
+ std::move(callback)));
+}
+
+void FileSystemContext::DidResolveURLOnOpenFileSystem(
+ OpenFileSystemCallback callback,
+ const GURL& filesystem_root,
+ const std::string& filesystem_name,
+ base::File::Error error) {
+ DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
+
+ std::move(callback).Run(filesystem_root, filesystem_name, error);
}
void FileSystemContext::ResolveURL(const FileSystemURL& url,
diff --git a/storage/browser/file_system/file_system_context.h b/storage/browser/file_system/file_system_context.h
index 49d34aaf8a4f5226a26232cf6d29567fa75616ec..22e55b190c95fbdba247526deaa030b50bb45e42 100644
--- a/storage/browser/file_system/file_system_context.h
+++ b/storage/browser/file_system/file_system_context.h
@@ -396,6 +396,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext
const std::string& filesystem_name,
base::File::Error error);
+ void DidResolveURLOnOpenFileSystem(OpenFileSystemCallback callback,
+ const GURL& filesystem_root,
+ const std::string& filesystem_name,
+ base::File::Error error);
+
// Returns a FileSystemBackend, used only by test code.
SandboxFileSystemBackend* sandbox_backend() const {
return sandbox_backend_.get();

View File

@@ -0,0 +1,122 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Reilly Grant <reillyg@chromium.org>
Date: Fri, 12 Nov 2021 20:09:12 +0000
Subject: serial: Check for detached buffers when writing
This change adds check in SerialPortUnderlyingSink::WriteData() to
ensure that the V8BufferSource being written to the Mojo data pipe has
not been detached since it was passed to the WritableStream.
(cherry picked from commit 7ce1516b49e86430c9216d0df8e23a325104a8c5)
Bug: 1267627
Change-Id: I63d48584eb0be1c1d87c27115900aa5c17931fcf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3269348
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Auto-Submit: Reilly Grant <reillyg@chromium.org>
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#940631}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3279207
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4692@{#132}
Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
index 08ab2c7e05668710b77712f3ffc0d5aeef4dd213..7876baf19a1f547c71e2a115db8a2cc4ccd43a3b 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
@@ -172,12 +172,25 @@ void SerialPortUnderlyingSink::WriteData() {
DCHECK(buffer_source_);
DOMArrayPiece array_piece(buffer_source_);
+ // From https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy, if the
+ // buffer source is detached then an empty byte sequence is returned, which
+ // means the write is complete.
+ if (array_piece.IsDetached()) {
+ buffer_source_ = nullptr;
+ offset_ = 0;
+ pending_operation_->Resolve();
+ pending_operation_ = nullptr;
+ return;
+ }
+
if (array_piece.ByteLength() > std::numeric_limits<uint32_t>::max()) {
- pending_exception_ = DOMException::Create(
- "Buffer size exceeds maximum heap object size.", "DataError");
+ pending_exception_ = MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kDataError,
+ "Buffer size exceeds maximum heap object size.");
PipeClosed();
return;
}
+
const uint8_t* data = array_piece.Bytes();
const uint32_t length = static_cast<uint32_t>(array_piece.ByteLength());
diff --git a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
index 9728af7de5051dce874e10082e1443a3ca9fa7dc..5e3b8548a91ddc2a0afa9793dea167f8e89defe3 100644
--- a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable.https.any.js
@@ -70,7 +70,7 @@ serial_test(async (t, fake) => {
compareArrays(data, value);
await port.close();
-}, 'Can read a large amount of data');
+}, 'Can write a large amount of data');
serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake);
diff --git a/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js
new file mode 100644
index 0000000000000000000000000000000000000000..828e877726b1c63dba14efc36324d9a16aa4e62f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serialPort_writable_detachBuffer.https.any.js
@@ -0,0 +1,48 @@
+// META: script=/resources/test-only-api.js
+// META: script=/serial/resources/common.js
+// META: script=resources/automation.js
+
+function detachBuffer(buffer) {
+ const channel = new MessageChannel();
+ channel.port1.postMessage('', [buffer]);
+}
+
+serial_test(async (t, fake) => {
+ const {port, fakePort} = await getFakeSerialPort(fake);
+ await port.open({baudRate: 9600, bufferSize: 64});
+
+ const writer = port.writable.getWriter();
+ const data = new Uint8Array(64);
+ detachBuffer(data.buffer);
+
+ // Writing a detached buffer is equivalent to writing an empty buffer so this
+ // should trivially succeed.
+ await writer.write(data);
+ writer.releaseLock();
+
+ await port.close();
+}, 'Writing a detached buffer is safe');
+
+serial_test(async (t, fake) => {
+ const {port, fakePort} = await getFakeSerialPort(fake);
+ // Select a buffer size smaller than the amount of data transferred.
+ await port.open({baudRate: 9600, bufferSize: 64});
+
+ // Start writing a buffer much larger than bufferSize above so that it can't
+ // all be transfered in a single operation.
+ const writer = port.writable.getWriter();
+ const data = new Uint8Array(1024);
+ const promise = writer.write(data);
+ writer.releaseLock();
+
+ // Read half of the written data and then detach the buffer.
+ await fakePort.readable();
+ await fakePort.readWithLength(data.byteLength / 2);
+ detachBuffer(data.buffer);
+
+ // When the buffer is detached its length becomes zero and so the write should
+ // succeed but it is undefined how much data was written before that happened.
+ await promise;
+
+ await port.close();
+}, 'Detaching a buffer while writing is safe');

View File

@@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Tue, 14 Dec 2021 01:21:26 +0000
Subject: reject AddBrokerClient on non-broker nodes
(cherry picked from commit b66b0b1ba61d0f0d4bb745d6a643e3da6128306f)
Fixed: 1259557
Change-Id: Ib8d7639b4c200a92336ff6a9f9a80c0560162dbe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3223127
Reviewed-by: Alex Gough <ajgo@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Auto-Submit: Ken Rockot <rockot@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#949902}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3335320
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Nicolas Ouellet-Payeur <nicolaso@chromium.org>
Cr-Commit-Position: refs/branch-heads/4664@{#1296}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/content/browser/launch_as_mojo_client_browsertest.cc b/content/browser/launch_as_mojo_client_browsertest.cc
index 96038525b80cda3d9c74b2d3f8f32819ad7b9cd1..355096b7b236d10b06975882ab086144fc3e6c6e 100644
--- a/content/browser/launch_as_mojo_client_browsertest.cc
+++ b/content/browser/launch_as_mojo_client_browsertest.cc
@@ -165,21 +165,14 @@ IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest, LaunchAndBindInterface) {
shell_controller->ShutDown();
}
-// Running a Content embedder with a dynamically loaded Mojo Core library is
-// currently only supported on Linux and Chrome OS.
-//
-// TODO(crbug.com/1096899): Re-enable on MSan if possible. MSan complains about
-// spurious uninitialized memory reads inside base::PlatformThread due to what
-// appears to be poor interaction among MSan, PlatformThread's thread_local
-// storage, and Mojo's use of dlopen().
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
-#if defined(MEMORY_SANITIZER) || BUILDFLAG(CFI_ICALL_CHECK)
-#define MAYBE_WithMojoCoreLibrary DISABLED_WithMojoCoreLibrary
-#else
-#define MAYBE_WithMojoCoreLibrary WithMojoCoreLibrary
-#endif
+// TODO(crbug.com/1259557): This test implementation fundamentally conflicts
+// with a fix for the linked bug because it causes a browser process to behave
+// partially as a broker and partially as a non-broker. This can be re-enabled
+// when we migrate away from the current Mojo implementation. It's OK to disable
+// for now because no production code relies on this feature.
IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest,
- MAYBE_WithMojoCoreLibrary) {
+ DISABLED_WithMojoCoreLibrary) {
// Instructs a newly launched Content Shell browser to initialize Mojo Core
// dynamically from a shared library, rather than using the version linked
// into the Content Shell binary.
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
index 21edab39368e69ee6665e490b2c4de13f424edbd..b34753b2dc0c58e5a80e1d0678ee178e2589e8e3 100644
--- a/mojo/core/node_controller.cc
+++ b/mojo/core/node_controller.cc
@@ -889,6 +889,11 @@ void NodeController::OnAddBrokerClient(const ports::NodeName& from_node,
return;
}
+ if (!GetConfiguration().is_broker_process) {
+ DLOG(ERROR) << "Ignoring AddBrokerClient on non-broker node.";
+ return;
+ }
+
if (GetPeerChannel(client_name)) {
DLOG(ERROR) << "Ignoring AddBrokerClient for known client.";
DropPeer(from_node, nullptr);

View File

@@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement
session.setCertificateVerifyCallback.
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac9337be88dec 100644
index 7c64f63ad0661497103839f172dc7ef8286af86a..24298fa4c35fec195e0e1b15422b97e2cf89daa8 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -117,6 +117,11 @@
@@ -22,12 +22,38 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
#if BUILDFLAG(IS_CT_SUPPORTED)
#include "components/certificate_transparency/chrome_ct_policy_enforcer.h"
#include "components/certificate_transparency/chrome_require_ct_delegate.h"
@@ -400,6 +405,79 @@ void GetCTPolicyConfigForCTLogInfo(
@@ -400,6 +405,91 @@ void GetCTPolicyConfigForCTLogInfo(
} // namespace
+class RemoteCertVerifier : public net::CertVerifier {
+ public:
+ class Request : public net::CertVerifier::Request {
+ public:
+ Request() {}
+ ~Request() override = default;
+ void OnRemoteResponse(
+ const RequestParams& params,
+ net::CertVerifyResult* verify_result,
+ int error_from_upstream,
+ net::CompletionOnceCallback callback,
+ int error_from_client,
+ const net::CertVerifyResult& verify_result_from_client) {
+ if (error_from_client == net::ERR_ABORTED) {
+ // use the default
+ std::move(callback).Run(error_from_upstream);
+ } else {
+ // use the override
+ verify_result->Reset();
+ verify_result->verified_cert = verify_result_from_client.verified_cert;
+ std::move(callback).Run(error_from_client);
+ }
+ }
+ base::WeakPtr<Request> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
+ private:
+ base::WeakPtrFactory<Request> weak_factory_{this};
+ };
+
+ RemoteCertVerifier(std::unique_ptr<net::CertVerifier> upstream): upstream_(std::move(upstream)) {
+ }
+ ~RemoteCertVerifier() override = default;
@@ -44,20 +70,14 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
+ int Verify(const RequestParams& params,
+ net::CertVerifyResult* verify_result,
+ net::CompletionOnceCallback callback,
+ std::unique_ptr<Request>* out_req,
+ std::unique_ptr<CertVerifier::Request>* out_req,
+ const net::NetLogWithSource& net_log) override {
+ out_req->reset();
+
+ net::CompletionOnceCallback callback2 = base::BindOnce(
+ &RemoteCertVerifier::OnRequestFinished, base::Unretained(this),
+ params, std::move(callback), verify_result);
+ int result = upstream_->Verify(params, verify_result,
+ std::move(callback2), out_req, net_log);
+ if (result != net::ERR_IO_PENDING) {
+ // Synchronous completion
+ }
+
+ return result;
+ params, std::move(callback), verify_result, out_req);
+ return upstream_->Verify(params, verify_result, std::move(callback2), out_req, net_log);
+ }
+
+
@@ -65,35 +85,27 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
+ upstream_->SetConfig(config);
+ }
+
+ void OnRequestFinished(const RequestParams& params, net::CompletionOnceCallback callback, net::CertVerifyResult* verify_result, int error) {
+ void OnRequestFinished(const RequestParams& params,
+ net::CompletionOnceCallback callback,
+ net::CertVerifyResult* verify_result,
+ std::unique_ptr<CertVerifier::Request>* out_req,
+ int error) {
+ if (client_.is_bound()) {
+ // We take a weak pointer to the request because deletion of the request
+ // is what signals cancellation. Thus if the request is cancelled, the
+ // callback won't be called, thus avoiding UAF, because |verify_result|
+ // is freed when the request is cancelled.
+ *out_req = std::make_unique<Request>();
+ base::WeakPtr<Request> weak_req = static_cast<Request*>(out_req->get())->GetWeakPtr();
+ client_->Verify(error, *verify_result, params.certificate(),
+ params.hostname(), params.flags(), params.ocsp_response(),
+ base::BindOnce(&RemoteCertVerifier::OnRemoteResponse,
+ base::Unretained(this), params, verify_result, error,
+ std::move(callback)));
+ base::BindOnce(&Request::OnRemoteResponse,
+ weak_req, params, verify_result, error, std::move(callback)));
+ } else {
+ std::move(callback).Run(error);
+ }
+ }
+
+ void OnRemoteResponse(
+ const RequestParams& params,
+ net::CertVerifyResult* verify_result,
+ int error,
+ net::CompletionOnceCallback callback,
+ int error2,
+ const net::CertVerifyResult& verify_result2) {
+ if (error2 == net::ERR_ABORTED) {
+ // use the default
+ std::move(callback).Run(error);
+ } else {
+ // use the override
+ verify_result->Reset();
+ verify_result->verified_cert = verify_result2.verified_cert;
+ std::move(callback).Run(error2);
+ }
+ }
+ private:
+ std::unique_ptr<net::CertVerifier> upstream_;
+ mojo::Remote<mojom::CertVerifierClient> client_;
@@ -102,7 +114,7 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
NetworkContext::PendingCertVerify::PendingCertVerify() = default;
@@ -612,6 +690,13 @@ void NetworkContext::SetClient(
@@ -612,6 +702,13 @@ void NetworkContext::SetClient(
client_.Bind(std::move(client));
}
@@ -116,7 +128,7 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
void NetworkContext::CreateURLLoaderFactory(
mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
mojom::URLLoaderFactoryParamsPtr params) {
@@ -1998,6 +2083,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
@@ -1998,6 +2095,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
std::move(cert_verifier));
cert_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_);
#endif // BUILDFLAG(IS_CHROMEOS_ASH)

View File

@@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dominic Battre <battre@chromium.org>
Date: Mon, 20 Dec 2021 18:53:00 +0000
Subject: Pin scrollTop to 0 during autofill preview
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This CL forces scrollTop of a ListBox to be 0 during autofill preview
state. After autofill preview ends, it attempts to scroll the ListBox
back so that a previously selected element becomes visible.
(cherry picked from commit 55b07dc54220200313366ec821d2303cd847187a)
Fixed: 1261689
Change-Id: I8593544577cf054cca40e7a487d3248acdcfdaa7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3279960
Commit-Queue: Dominic Battré <battre@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#941822}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3347570
Auto-Submit: Dominic Battré <battre@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/branch-heads/4664@{#1330}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index fb24f5710d37e84701944d4b053764fadc29a6df..daa9e25f645f9d554dd85ed4199bc80bf3a7e049 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -122,6 +122,7 @@
#include "third_party/blink/renderer/core/html/custom/custom_element_registry.h"
#include "third_party/blink/renderer/core/html/forms/html_form_controls_collection.h"
#include "third_party/blink/renderer/core/html/forms/html_options_collection.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
#include "third_party/blink/renderer/core/html/html_document.h"
@@ -1556,6 +1557,13 @@ double Element::scrollTop() {
return 0;
}
+ // Don't disclose scroll position in preview state. See crbug.com/1261689.
+ auto* select_element = DynamicTo<HTMLSelectElement>(this);
+ if (select_element && !select_element->UsesMenuList() &&
+ !select_element->SuggestedValue().IsEmpty()) {
+ return 0;
+ }
+
LayoutBox* box = GetLayoutBoxForScrolling();
if (!box)
return 0;
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc
index 541a3e56671bc26cd7098a8b785061be69027be3..4fd15874c4ce78c19b21ac310eb076077075a4f0 100644
--- a/third_party/blink/renderer/core/html/forms/select_type.cc
+++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -977,8 +977,16 @@ void ListBoxSelectType::DidBlur() {
}
void ListBoxSelectType::DidSetSuggestedOption(HTMLOptionElement* option) {
- if (select_->GetLayoutObject())
- ScrollToOption(option);
+ if (!select_->GetLayoutObject())
+ return;
+ // When ending preview state, don't leave the scroll position at the
+ // previewed element but return to the active selection end if it is
+ // defined or to the first selectable option. See crbug.com/1261689.
+ if (!option)
+ option = ActiveSelectionEnd();
+ if (!option)
+ option = FirstSelectableOption();
+ ScrollToOption(option);
}
void ListBoxSelectType::SaveLastSelection() {
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index c855514e9ac6c7521515c417cceffc2dacbab2d9..967f1a0ff38db262b74650915efcc44d6ef1d7ad 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -1743,8 +1743,14 @@ void Internals::setSuggestedValue(Element* element,
if (auto* textarea = DynamicTo<HTMLTextAreaElement>(*element))
textarea->SetSuggestedValue(value);
- if (auto* select = DynamicTo<HTMLSelectElement>(*element))
- select->SetSuggestedValue(value);
+ if (auto* select = DynamicTo<HTMLSelectElement>(*element)) {
+ // A Null string resets the suggested value.
+ select->SetSuggestedValue(value.IsEmpty() ? String() : value);
+ }
+
+ To<HTMLFormControlElement>(element)->SetAutofillState(
+ value.IsEmpty() ? WebAutofillState::kNotFilled
+ : WebAutofillState::kPreviewed);
}
void Internals::setAutofilledValue(Element* element,
@@ -1773,11 +1779,16 @@ void Internals::setAutofilledValue(Element* element,
*Event::CreateBubble(event_type_names::kKeyup));
}
- if (auto* select = DynamicTo<HTMLSelectElement>(*element))
- select->setValue(value, true /* send_events */);
+ if (auto* select = DynamicTo<HTMLSelectElement>(*element)) {
+ select->setValue(value.IsEmpty()
+ ? String() // Null string resets the autofill state.
+ : value,
+ true /* send_events */);
+ }
To<HTMLFormControlElement>(element)->SetAutofillState(
- blink::WebAutofillState::kAutofilled);
+ value.IsEmpty() ? WebAutofillState::kNotFilled
+ : blink::WebAutofillState::kAutofilled);
}
void Internals::setEditingValue(Element* element,
diff --git a/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-over-placeholder-value-expected.html b/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-over-placeholder-value-expected.html
index cac91c4f2fbecf5117b35318e7a88bda1a268135..30e454a79c4d3a5bc2a49879f0929557e011f819 100644
--- a/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-over-placeholder-value-expected.html
+++ b/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-over-placeholder-value-expected.html
@@ -1 +1,4 @@
<input id="input" value="Springfield">
+<script>
+internals.setAutofilled(input, true);
+</script>
diff --git a/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-when-underlying-placeholder-is-removed-expected.html b/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-when-underlying-placeholder-is-removed-expected.html
index cac91c4f2fbecf5117b35318e7a88bda1a268135..30e454a79c4d3a5bc2a49879f0929557e011f819 100644
--- a/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-when-underlying-placeholder-is-removed-expected.html
+++ b/third_party/blink/web_tests/fast/forms/text/input-appearance-autocomplete-suggested-value-when-underlying-placeholder-is-removed-expected.html
@@ -1 +1,4 @@
<input id="input" value="Springfield">
+<script>
+internals.setAutofilled(input, true);
+</script>

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 a6061a9c5bf1ebb37fb18ecabfb12af3c45ffdf5..f254061d1c118d6505eb1989f65b77b81839b752 100644
--- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
+++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -1189,6 +1189,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 0652dca43b5b5a7b37d96817e5818ec3e9cc9824..bc44948de39c56cbd94305d7b73433da45237ddd 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6446,17 +6446,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 63f53ff39240ea59a03f1a6f9d032444b0e4214d..db8f3e3c9794163feea2c020fc100e7f6cc9c73b 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -531,8 +531,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 57f970d15bf03f817680982fa8605c333485804b..7244d1a7f2b4c706c8dc56fafaed2d4b7f7c1c04 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -302,8 +302,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()
@@ -323,11 +342,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,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bruce Dawson <brucedawson@chromium.org>
Date: Mon, 28 Feb 2022 19:07:41 +0000
Subject: Remove incorrect width/height adjustments
In late 2016 a change which fixed some problems around window sizing
when attaching or detaching additional displays was landed, which fixed
some genuine bugs. Unfortunately it included a subtraction of 1 from the
width and height of the Chrome window. I couldn't find any discussion of
this size adjustment and I think that it was just a misunderstanding of
how window rectangles work (inclusive versus exclusive extents).
This size adjustment causes non-maximized Chrome windows to shrink every
time a monitor is added or removed. The problematic commit was found
by the bug-filer through a bisect of more than four years of Chrome
history - I'm just landing the fix that they suggested.
Bug: 1300415
Change-Id: Ief124f584a91aa9cc3f10704b0cc1e83356dea5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3492658
Reviewed-by: Allen Bauer <kylixrd@chromium.org>
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
Cr-Commit-Position: refs/heads/main@{#975872}
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index dc4e4755116935c527c34e98a27ce19de0e7b7bc..61ab82a38dd829677a7d642b5b12478ff2e2de96 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -2818,8 +2818,8 @@ void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) {
// (Win+Shift+Arrows). See crbug.com/656001.
window_rect.left = window_pos->x;
window_rect.top = window_pos->y;
- window_rect.right = window_pos->x + window_pos->cx - 1;
- window_rect.bottom = window_pos->y + window_pos->cy - 1;
+ window_rect.right = window_pos->x + window_pos->cx;
+ window_rect.bottom = window_pos->y + window_pos->cy;
}
HMONITOR monitor;

View File

@@ -0,0 +1,271 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Ludwig <michaelludwig@google.com>
Date: Tue, 7 Dec 2021 20:49:07 +0000
Subject: - Don't explicitly clip scissor for large transforms
This adds a check to CanExplicitlyScissor that confirms that the device
space scissor rect, transformed to the quad's local space, can be
transformed back to device space and equal the same pixel bounds.
Without this check, sufficiently large scales and translates could
cause the local-space coordinates of the scissor rect to be in a float
range that does not have single-pixel precision, meaning it could round
significantly. Clipping the quad's coordinates to those rounded edges
and then transforming to device space can result in coordinates that
fall outside the original device-space scissor rect.
If however, we ensure we can round-trip the scissor coordinates, then
any clipping to the quad's coordinates will also be projected to within
the scissor rect as well.
(cherry picked from commit ab1b76f3e7cdad702c562f0b43bf3367caff4812)
Bug: 1272250
Change-Id: I7c37c54efd082723797ccf32b5d19ef285c520c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3306893
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#946552}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3320870
Auto-Submit: Michael Ludwig <michaelludwig@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4692@{#786}
Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index 67d8f6b28a4edee1764660ede8eb48581c2b897e..054b18016922520a5545de64fb1243888117dd9c 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -125,45 +125,6 @@ bool IsTextureResource(DisplayResourceProviderSkia* resource_provider,
return !resource_provider->IsResourceSoftwareBacked(resource_id);
}
-void ApplyExplicitScissor(const DrawQuad* quad,
- const gfx::Rect& scissor_rect,
- const gfx::Transform& device_transform,
- unsigned* aa_flags,
- gfx::RectF* vis_rect) {
- // Inset rectangular edges and turn off the AA for clipped edges. Operates in
- // the quad's space, so apply inverse of transform to get new scissor
- gfx::RectF scissor(scissor_rect);
- device_transform.TransformRectReverse(&scissor);
-
- float left_inset = scissor.x() - vis_rect->x();
- float top_inset = scissor.y() - vis_rect->y();
- float right_inset = vis_rect->right() - scissor.right();
- float bottom_inset = vis_rect->bottom() - scissor.bottom();
-
- if (left_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kLeft_QuadAAFlag;
- } else {
- left_inset = 0;
- }
- if (top_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kTop_QuadAAFlag;
- } else {
- top_inset = 0;
- }
- if (right_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kRight_QuadAAFlag;
- } else {
- right_inset = 0;
- }
- if (bottom_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kBottom_QuadAAFlag;
- } else {
- bottom_inset = 0;
- }
-
- vis_rect->Inset(left_inset, top_inset, right_inset, bottom_inset);
-}
-
unsigned GetCornerAAFlags(const DrawQuad* quad,
const SkPoint& vertex,
unsigned edge_mask) {
@@ -556,6 +517,10 @@ struct SkiaRenderer::DrawQuadParams {
p.setAntiAlias(aa_flags != SkCanvas::kNone_QuadAAFlags);
return p;
}
+
+ void ApplyScissor(const SkiaRenderer* renderer,
+ const DrawQuad* quad,
+ const gfx::Rect* scissor_to_apply);
};
SkiaRenderer::DrawQuadParams::DrawQuadParams(const gfx::Transform& cdt,
@@ -1324,18 +1289,7 @@ SkiaRenderer::DrawQuadParams SkiaRenderer::CalculateDrawQuadParams(
params.opacity = 1.f;
}
- // Applying the scissor explicitly means avoiding a clipRect() call and
- // allows more quads to be batched together in a DrawEdgeAAImageSet call
- if (scissor_rect) {
- if (CanExplicitlyScissor(quad, draw_region, params.content_device_transform,
- *scissor_rect)) {
- ApplyExplicitScissor(quad, *scissor_rect, params.content_device_transform,
- &params.aa_flags, &params.visible_rect);
- params.vis_tex_coords = params.visible_rect;
- } else {
- params.scissor_rect = *scissor_rect;
- }
- }
+ params.ApplyScissor(this, quad, scissor_rect);
// Determine final rounded rect clip geometry. We transform it from target
// space to window space to make batching and canvas preparation easier
@@ -1365,28 +1319,40 @@ SkiaRenderer::DrawQuadParams SkiaRenderer::CalculateDrawQuadParams(
return params;
}
-bool SkiaRenderer::CanExplicitlyScissor(
+void SkiaRenderer::DrawQuadParams::ApplyScissor(
+ const SkiaRenderer* renderer,
const DrawQuad* quad,
- const gfx::QuadF* draw_region,
- const gfx::Transform& contents_device_transform,
- const gfx::Rect& scissor_rect) const {
+ const gfx::Rect* scissor_to_apply) {
+ // No scissor should have been set before calling ApplyScissor
+ DCHECK(!scissor_rect.has_value());
+
+ if (!scissor_to_apply) {
+ // No scissor at all, which matches the DCHECK'ed state above
+ return;
+ }
+
+ // Assume at start that the scissor will be applied through the canvas clip,
+ // so that this can simply return when it detects the scissor cannot be
+ // applied explicitly to |visible_rect|.
+ scissor_rect = *scissor_to_apply;
+
// PICTURE_CONTENT is not like the others, since it is executing a list of
// draw calls into the canvas.
if (quad->material == DrawQuad::Material::kPictureContent)
- return false;
+ return;
// Intersection with scissor and a quadrilateral is not necessarily a quad,
// so don't complicate things
- if (draw_region)
- return false;
+ if (draw_region.has_value())
+ return;
// This is slightly different than
// gfx::Transform::IsPositiveScaleAndTranslation in that it also allows zero
// scales. This is because in the common orthographic case the z scale is 0.
- if (!contents_device_transform.IsScaleOrTranslation() ||
- contents_device_transform.matrix().get(0, 0) < 0.0f ||
- contents_device_transform.matrix().get(1, 1) < 0.0f ||
- contents_device_transform.matrix().get(2, 2) < 0.0f) {
- return false;
+ if (!content_device_transform.IsScaleOrTranslation() ||
+ content_device_transform.matrix().get(0, 0) < 0.0f ||
+ content_device_transform.matrix().get(1, 1) < 0.0f ||
+ content_device_transform.matrix().get(2, 2) < 0.0f) {
+ return;
}
// State check: should not have a CompositorRenderPassDrawQuad if we got here.
@@ -1396,22 +1362,69 @@ bool SkiaRenderer::CanExplicitlyScissor(
// geometry beyond the quad's visible_rect, so it's not safe to pre-clip.
auto pass_id =
AggregatedRenderPassDrawQuad::MaterialCast(quad)->render_pass_id;
- if (FiltersForPass(pass_id) || BackdropFiltersForPass(pass_id))
- return false;
+ if (renderer->FiltersForPass(pass_id) ||
+ renderer->BackdropFiltersForPass(pass_id))
+ return;
}
// If the intersection of the scissor and the quad's visible_rect results in
// subpixel device-space geometry, do not drop the scissor. Otherwise Skia
// sees an unclipped anti-aliased hairline and uses different AA methods that
// would cause the rasterized result to extend beyond the scissor.
- gfx::RectF device_bounds(quad->visible_rect);
- contents_device_transform.TransformRect(&device_bounds);
- device_bounds.Intersect(gfx::RectF(scissor_rect));
+ gfx::RectF device_bounds(visible_rect);
+ content_device_transform.TransformRect(&device_bounds);
+ device_bounds.Intersect(gfx::RectF(*scissor_rect));
if (device_bounds.width() < 1.0f || device_bounds.height() < 1.0f) {
- return false;
+ return;
+ }
+
+ // The explicit scissor is applied in the quad's local space. If the transform
+ // does not leave sufficient precision to round-trip the scissor rect to-from
+ // device->local->device space, the explicitly "clipped" geometry does not
+ // necessarily respect the original scissor.
+ gfx::RectF local_scissor(*scissor_rect);
+ content_device_transform.TransformRectReverse(&local_scissor);
+ gfx::RectF remapped_scissor(local_scissor);
+ content_device_transform.TransformRect(&remapped_scissor);
+ if (gfx::ToRoundedRect(remapped_scissor) != *scissor_rect) {
+ return;
+ }
+
+ // At this point, we've determined that we can transform the scissor rect into
+ // the quad's local space and adjust |vis_rect|, such that when it's mapped to
+ // 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();
+
+ // The scissor is a non-AA clip, so we unset the bit flag for clipped edges.
+ if (left_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kLeft_QuadAAFlag;
+ } else {
+ left_inset = 0;
+ }
+ if (top_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kTop_QuadAAFlag;
+ } else {
+ top_inset = 0;
+ }
+ if (right_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kRight_QuadAAFlag;
+ } else {
+ right_inset = 0;
+ }
+ if (bottom_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kBottom_QuadAAFlag;
+ } else {
+ bottom_inset = 0;
}
- return true;
+ visible_rect.Inset(left_inset, top_inset, right_inset, bottom_inset);
+ vis_tex_coords = visible_rect;
+ scissor_rect.reset();
}
const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectly(
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h
index b94ffe0bae845928db4f3dc05d71fef72e4b3523..933c63fa4625797eb00ec256fcb7abc41a4c88ad 100644
--- a/components/viz/service/display/skia_renderer.h
+++ b/components/viz/service/display/skia_renderer.h
@@ -139,6 +139,7 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
const gfx::Rect* scissor_rect,
const DrawQuad* quad,
const gfx::QuadF* draw_region) const;
+
DrawRPDQParams CalculateRPDQParams(const AggregatedRenderPassDrawQuad* quad,
DrawQuadParams* params);
// Modifies |params| and |rpdq_params| to apply correctly when drawing the
@@ -156,12 +157,6 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
const SkImage* image,
const gfx::RectF& valid_texel_bounds,
DrawQuadParams* params) const;
- // True or false if the DrawQuad can have the scissor rect applied by
- // modifying the quad's visible_rect instead of as a separate clip operation.
- bool CanExplicitlyScissor(const DrawQuad* quad,
- const gfx::QuadF* draw_region,
- const gfx::Transform& contents_device_transform,
- const gfx::Rect& scissor_rect) const;
bool MustFlushBatchedQuads(const DrawQuad* new_quad,
const DrawRPDQParams* rpdq_params,

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 054b18016922520a5545de64fb1243888117dd9c..07b45ac958ef609ad8a103240e3c06edb0eaefc6 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -1395,34 +1395,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 37559380e8a3a8f857100bea9e1a5f6e53ecdc08..5f3e220642451609fd587c98475d6a3b8f347e0c 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -369,6 +369,9 @@ crbug.com/1086687 [ chromeos chromeos-board-kevin ] Pixel_PrecisionRoundedCorner
crbug.com/1218288 [ fuchsia-board-astro ] Pixel_PrecisionRoundedCorner [ Skip ]
crbug.com/1136875 [ fuchsia-board-qemu-x64 ] Pixel_PrecisionRoundedCorner [ RetryOnFailure ]
+# Fails on Nexus 5X.
+crbug.com/1307317 [ android android-chromium android-nexus-5x ] Pixel_PrecisionRoundedCorner [ Failure ]
+
# Still fails on Nexus 5 after all other Pixel_CanvasLowLatency* pass.
crbug.com/1097752 [ android android-nexus-5 ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Skip ]

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,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 7c9fa09a12516e2a866bd2e64b85d9643189ef5d..178781a3346c3271ba2592e472ec1d45afe42e61 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 ee7b79b351e5002cb02842097b89156f6e407a54..8187282e09b0f11e2a0f704555e8f557aa97f920 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 nullptr;
}
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,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,387 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Abigail Klein <abigailbklein@google.com>
Date: Wed, 3 Nov 2021 03:53:27 +0000
Subject: Use AXNodeID rather than AXNode* in AXEventGenerator tree events.
We suspect that sometimes AXNodes are destroyed while processing events.
Specifically, we suspect that the extra mac nodes that are created for
table column and row headers when VoiceOver requests them are destroyed
if an ancestor up the chain is modified. In order to safeguard against
the possibility of an AXNode* becoming stale, we will store AXNodeIDs in
the list of tree events. This way, when the tree event is used, we can
first check for the validity of the AXNodeID before using the
corresponding AXNode.
Bug: 1262967
Change-Id: Ifa2b23544fff532b379857a637f417d5f639c7ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3244046
Commit-Queue: Abigail Klein <abigailbklein@google.com>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#937698}
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index e7756900afd53bab4b9f74c96a9f6c3ad05e18e3..ca05af4879d56be6de46604f10a801be91cb4e00 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -503,7 +503,7 @@ bool BrowserAccessibilityManager::OnAccessibilityEvents(
std::vector<ui::AXEventGenerator::TargetedEvent> deferred_events;
bool received_load_complete_event = false;
for (const auto& targeted_event : event_generator()) {
- BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
+ BrowserAccessibility* event_target = GetFromID(targeted_event.node_id);
if (!event_target)
continue;
@@ -540,7 +540,7 @@ bool BrowserAccessibilityManager::OnAccessibilityEvents(
// Now fire all of the rest of the generated events we previously deferred.
for (const auto& targeted_event : deferred_events) {
- BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
+ BrowserAccessibility* event_target = GetFromID(targeted_event.node_id);
if (!event_target)
continue;
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 4ce35f1c152cfc4927ade17431e6bfe4c6d75b1d..f6bc93e302920464ec2a1f26562d327a7989a805 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -949,7 +949,7 @@ void BrowserAccessibilityManagerWin::BeforeAccessibilityEvents() {
for (const auto& targeted_event : event_generator()) {
if (targeted_event.event_params.event ==
ui::AXEventGenerator::Event::IGNORED_CHANGED) {
- BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
+ BrowserAccessibility* event_target = GetFromID(targeted_event.node_id);
if (!event_target)
continue;
diff --git a/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc b/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc
index f8725107d788a6cc70ad337ad92b65ba636968b6..e9e09b22ff40b657dec538813cc3464c9933ab1a 100644
--- a/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc
+++ b/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc
@@ -152,7 +152,7 @@ bool AutomationAXTreeWrapper::OnAccessibilityEvents(
if (ShouldIgnoreGeneratedEvent(targeted_event.event_params.event))
continue;
ui::AXEvent generated_event;
- generated_event.id = targeted_event.node->id();
+ generated_event.id = targeted_event.node_id;
generated_event.event_from = targeted_event.event_params.event_from;
generated_event.event_from_action =
targeted_event.event_params.event_from_action;
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc
index d890e0365204421ac62aee716c9b1c364d810635..dbe1a78cdbd8fbead5d4a05f07bff7a55844197b 100644
--- a/ui/accessibility/ax_event_generator.cc
+++ b/ui/accessibility/ax_event_generator.cc
@@ -102,10 +102,10 @@ bool AXEventGenerator::EventParams::operator<(const EventParams& rhs) const {
// AXEventGenerator::TargetedEvent
//
-AXEventGenerator::TargetedEvent::TargetedEvent(AXNode* node,
+AXEventGenerator::TargetedEvent::TargetedEvent(AXNodeID node_id,
const EventParams& event_params)
- : node(node), event_params(event_params) {
- DCHECK(node);
+ : node_id(node_id), event_params(event_params) {
+ DCHECK_NE(node_id, kInvalidAXNodeID);
}
AXEventGenerator::TargetedEvent::~TargetedEvent() = default;
@@ -115,8 +115,8 @@ AXEventGenerator::TargetedEvent::~TargetedEvent() = default;
//
AXEventGenerator::Iterator::Iterator(
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_start_iter,
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_end_iter)
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_start_iter,
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_end_iter)
: map_iter_(map_start_iter), map_end_iter_(map_end_iter) {
if (map_iter_ != map_end_iter_)
set_iter_ = map_iter_->second.begin();
@@ -180,11 +180,11 @@ void swap(AXEventGenerator::Iterator& lhs, AXEventGenerator::Iterator& rhs) {
if (lhs == rhs)
return;
- std::map<AXNode*, std::set<AXEventGenerator::EventParams>>::const_iterator
+ std::map<AXNodeID, std::set<AXEventGenerator::EventParams>>::const_iterator
map_iter = lhs.map_iter_;
lhs.map_iter_ = rhs.map_iter_;
rhs.map_iter_ = map_iter;
- std::map<AXNode*, std::set<AXEventGenerator::EventParams>>::const_iterator
+ std::map<AXNodeID, std::set<AXEventGenerator::EventParams>>::const_iterator
map_end_iter = lhs.map_end_iter_;
lhs.map_end_iter_ = rhs.map_end_iter_;
rhs.map_end_iter_ = map_end_iter;
@@ -269,7 +269,7 @@ void AXEventGenerator::AddEvent(AXNode* node, AXEventGenerator::Event event) {
if (node->data().role == ax::mojom::Role::kInlineTextBox)
return;
- std::set<EventParams>& node_events = tree_events_[node];
+ std::set<EventParams>& node_events = tree_events_[node->id()];
node_events.emplace(event, ax::mojom::EventFrom::kNone,
ax::mojom::Action::kNone, tree_->event_intents());
}
@@ -739,7 +739,7 @@ void AXEventGenerator::OnNodeWillBeDeleted(AXTree* tree, AXNode* node) {
live_region_tracker_->OnNodeWillBeDeleted(*node);
DCHECK_EQ(tree_, tree);
- tree_events_.erase(node);
+ tree_events_.erase(node->id());
}
void AXEventGenerator::OnSubtreeWillBeDeleted(AXTree* tree, AXNode* node) {
@@ -748,7 +748,7 @@ void AXEventGenerator::OnSubtreeWillBeDeleted(AXTree* tree, AXNode* node) {
void AXEventGenerator::OnNodeWillBeReparented(AXTree* tree, AXNode* node) {
DCHECK_EQ(tree_, tree);
- tree_events_.erase(node);
+ tree_events_.erase(node->id());
}
void AXEventGenerator::OnSubtreeWillBeReparented(AXTree* tree, AXNode* node) {
@@ -823,10 +823,9 @@ void AXEventGenerator::OnAtomicUpdateFinished(
}
void AXEventGenerator::AddEventsForTesting(
- AXNode* node,
+ const AXNode& node,
const std::set<EventParams>& events) {
- DCHECK(node);
- tree_events_[node] = events;
+ tree_events_[node.id()] = events;
}
void AXEventGenerator::FireLiveRegionEvents(AXNode* node) {
@@ -951,7 +950,7 @@ void AXEventGenerator::TrimEventsDueToAncestorIgnoredChanged(
// IGNORED_CHANGED event.
const auto& parent_map_iter =
ancestor_ignored_changed_map.find(node->parent());
- const auto& curr_events_iter = tree_events_.find(node);
+ const auto& curr_events_iter = tree_events_.find(node->id());
// Initialize |ancestor_ignored_changed_map[node]| with an empty bitset,
// representing neither |node| nor its ancestor has IGNORED_CHANGED.
@@ -1027,7 +1026,8 @@ void AXEventGenerator::PostprocessEvents() {
// First pass through |tree_events_|, remove events that we do not need.
for (auto& iter : tree_events_) {
- AXNode* node = iter.first;
+ AXNodeID node_id = iter.first;
+ AXNode* node = tree_->GetFromId(node_id);
// TODO(http://crbug.com/2279799): remove all of the cases that could
// add a null node to |tree_events|.
@@ -1067,8 +1067,8 @@ void AXEventGenerator::PostprocessEvents() {
// Don't fire text attribute changed on this node if its immediate parent
// also has text attribute changed.
if (parent && HasEvent(node_events, Event::TEXT_ATTRIBUTE_CHANGED) &&
- tree_events_.find(parent) != tree_events_.end() &&
- HasEvent(tree_events_[parent], Event::TEXT_ATTRIBUTE_CHANGED)) {
+ tree_events_.find(parent->id()) != tree_events_.end() &&
+ HasEvent(tree_events_[parent->id()], Event::TEXT_ATTRIBUTE_CHANGED)) {
RemoveEvent(&node_events, Event::TEXT_ATTRIBUTE_CHANGED);
}
@@ -1078,11 +1078,11 @@ void AXEventGenerator::PostprocessEvents() {
// of an existing node. In that instance, we need to inform ATs that the
// existing node's parent has changed on the platform.
if (HasEvent(node_events, Event::PARENT_CHANGED)) {
- while (parent && (tree_events_.find(parent) != tree_events_.end() ||
+ while (parent && (tree_events_.find(parent->id()) != tree_events_.end() ||
base::Contains(removed_parent_changed_nodes, parent))) {
if ((base::Contains(removed_parent_changed_nodes, parent) ||
- HasEvent(tree_events_[parent], Event::PARENT_CHANGED)) &&
- !HasEvent(tree_events_[parent], Event::SUBTREE_CREATED)) {
+ HasEvent(tree_events_[parent->id()], Event::PARENT_CHANGED)) &&
+ !HasEvent(tree_events_[parent->id()], Event::SUBTREE_CREATED)) {
RemoveEvent(&node_events, Event::PARENT_CHANGED);
removed_parent_changed_nodes.insert(node);
break;
@@ -1096,10 +1096,10 @@ void AXEventGenerator::PostprocessEvents() {
parent = node->GetUnignoredParent();
if (HasEvent(node_events, Event::SUBTREE_CREATED)) {
while (parent &&
- (tree_events_.find(parent) != tree_events_.end() ||
+ (tree_events_.find(parent->id()) != tree_events_.end() ||
base::Contains(removed_subtree_created_nodes, parent))) {
if (base::Contains(removed_subtree_created_nodes, parent) ||
- HasEvent(tree_events_[parent], Event::SUBTREE_CREATED)) {
+ HasEvent(tree_events_[parent->id()], Event::SUBTREE_CREATED)) {
RemoveEvent(&node_events, Event::SUBTREE_CREATED);
removed_subtree_created_nodes.insert(node);
break;
diff --git a/ui/accessibility/ax_event_generator.h b/ui/accessibility/ax_event_generator.h
index 026ecdf19342de6e0658a3c7f2a5cfe69a80ee4c..3bba25e9a1d5ca2f874efd18868aca2501f531b4 100644
--- a/ui/accessibility/ax_event_generator.h
+++ b/ui/accessibility/ax_event_generator.h
@@ -151,11 +151,10 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
};
struct AX_EXPORT TargetedEvent final {
- // |node| must not be null.
- TargetedEvent(AXNode* node, const EventParams& event_params);
+ TargetedEvent(AXNodeID node_id, const EventParams& event_params);
~TargetedEvent();
- AXNode* const node;
+ const AXNodeID node_id;
const EventParams& event_params;
};
@@ -163,8 +162,9 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
: public std::iterator<std::input_iterator_tag, TargetedEvent> {
public:
Iterator(
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_start_iter,
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_end_iter);
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator
+ map_start_iter,
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_end_iter);
Iterator(const Iterator& other);
~Iterator();
@@ -178,8 +178,8 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
AX_EXPORT friend bool operator!=(const Iterator& lhs, const Iterator& rhs);
AX_EXPORT friend void swap(Iterator& lhs, Iterator& rhs);
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_iter_;
- std::map<AXNode*, std::set<EventParams>>::const_iterator map_end_iter_;
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_iter_;
+ std::map<AXNodeID, std::set<EventParams>>::const_iterator map_end_iter_;
std::set<EventParams>::const_iterator set_iter_;
};
@@ -243,7 +243,8 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
always_fire_load_complete_ = val;
}
- void AddEventsForTesting(AXNode* node, const std::set<EventParams>& events);
+ void AddEventsForTesting(const AXNode& node,
+ const std::set<EventParams>& events);
protected:
// AXTreeObserver overrides.
@@ -332,7 +333,7 @@ class AX_EXPORT AXEventGenerator : public AXTreeObserver {
void PostprocessEvents();
AXTree* tree_ = nullptr; // Not owned.
- std::map<AXNode*, std::set<EventParams>> tree_events_;
+ std::map<AXNodeID, std::set<EventParams>> tree_events_;
// Valid between the call to OnIntAttributeChanged and the call to
// OnAtomicUpdateFinished. List of nodes whose active descendant changed.
diff --git a/ui/accessibility/ax_event_generator_unittest.cc b/ui/accessibility/ax_event_generator_unittest.cc
index 3797cf10490bd9cdd74dc2fec9934613281a51a0..2160fb1721c5929754e2464cbe3e80c455ba0c1a 100644
--- a/ui/accessibility/ax_event_generator_unittest.cc
+++ b/ui/accessibility/ax_event_generator_unittest.cc
@@ -16,7 +16,7 @@ namespace ui {
// Required by gmock to print TargetedEvent in a human-readable way.
void PrintTo(const AXEventGenerator::TargetedEvent& event, std::ostream* os) {
- *os << event.event_params.event << " on " << event.node->id();
+ *os << event.event_params.event << " on " << event.node_id;
}
namespace {
@@ -37,7 +37,7 @@ MATCHER_P2(HasEventAtNode,
PrintToString(expected_node_id)) {
const auto& event = arg;
return Matches(expected_event_type)(event.event_params.event) &&
- Matches(expected_node_id)(event.node->id());
+ Matches(expected_node_id)(event.node_id);
}
} // namespace
@@ -128,15 +128,15 @@ TEST(AXEventGeneratorTest, IterateThroughEmptyEventSets) {
// Node9 contains no event.
std::set<AXEventGenerator::EventParams> node9_events;
- event_generator.AddEventsForTesting(node1, node1_events);
- event_generator.AddEventsForTesting(node2, node2_events);
- event_generator.AddEventsForTesting(node3, node3_events);
- event_generator.AddEventsForTesting(node4, node4_events);
- event_generator.AddEventsForTesting(node5, node5_events);
- event_generator.AddEventsForTesting(node6, node6_events);
- event_generator.AddEventsForTesting(node7, node7_events);
- event_generator.AddEventsForTesting(node8, node8_events);
- event_generator.AddEventsForTesting(node9, node9_events);
+ event_generator.AddEventsForTesting(*node1, node1_events);
+ event_generator.AddEventsForTesting(*node2, node2_events);
+ event_generator.AddEventsForTesting(*node3, node3_events);
+ event_generator.AddEventsForTesting(*node4, node4_events);
+ event_generator.AddEventsForTesting(*node5, node5_events);
+ event_generator.AddEventsForTesting(*node6, node6_events);
+ event_generator.AddEventsForTesting(*node7, node7_events);
+ event_generator.AddEventsForTesting(*node8, node8_events);
+ event_generator.AddEventsForTesting(*node9, node9_events);
std::map<AXNode*, std::set<AXEventGenerator::Event>> expected_event_map;
expected_event_map[node3] = {AXEventGenerator::Event::IGNORED_CHANGED,
@@ -145,10 +145,12 @@ TEST(AXEventGeneratorTest, IterateThroughEmptyEventSets) {
expected_event_map[node7] = {AXEventGenerator::Event::IGNORED_CHANGED};
for (const auto& targeted_event : event_generator) {
- auto map_iter = expected_event_map.find(targeted_event.node);
+ AXNode* node = tree.GetFromId(targeted_event.node_id);
+ ASSERT_NE(nullptr, node);
+ auto map_iter = expected_event_map.find(node);
ASSERT_NE(map_iter, expected_event_map.end())
- << "|expected_event_map| contains node.id=" << targeted_event.node->id()
+ << "|expected_event_map| contains node_id=" << targeted_event.node_id
<< "\nExpected: true"
<< "\nActual: " << std::boolalpha
<< (map_iter != expected_event_map.end());
@@ -158,7 +160,7 @@ TEST(AXEventGeneratorTest, IterateThroughEmptyEventSets) {
ASSERT_NE(event_iter, node_events.end())
<< "Event=" << targeted_event.event_params.event
- << ", on node.id=" << targeted_event.node->id()
+ << ", on node_id=" << targeted_event.node_id
<< " NOT found in |expected_event_map|";
// If the event from |event_generator| is found in |expected_event_map|,
diff --git a/ui/accessibility/ax_generated_tree_unittest.cc b/ui/accessibility/ax_generated_tree_unittest.cc
index 6c301f68de70757a3abb2a632380e3136d9f183b..d3007e17ef07ec72145ac373ed6fea8d24650d1c 100644
--- a/ui/accessibility/ax_generated_tree_unittest.cc
+++ b/ui/accessibility/ax_generated_tree_unittest.cc
@@ -365,13 +365,15 @@ TEST(AXGeneratedTreeTest, GeneratedTreesWithIgnoredNodes) {
// Capture the events generated.
std::map<AXNodeID, std::set<AXEventGenerator::Event>> actual_events;
for (const AXEventGenerator::TargetedEvent& event : event_generator) {
- if (event.node->IsIgnored() ||
+ const AXNode* node = fat_tree.GetFromId(event.node_id);
+ ASSERT_NE(nullptr, node);
+ if (node->IsIgnored() ||
event.event_params.event ==
AXEventGenerator::Event::IGNORED_CHANGED) {
continue;
}
- actual_events[event.node->id()].insert(event.event_params.event);
+ actual_events[event.node_id].insert(event.event_params.event);
}
// Now, turn skinny_tree into skinny_tree1 and compare
@@ -391,7 +393,7 @@ TEST(AXGeneratedTreeTest, GeneratedTreesWithIgnoredNodes) {
std::map<AXNodeID, std::set<AXEventGenerator::Event>> expected_events;
for (const AXEventGenerator::TargetedEvent& event :
skinny_event_generator)
- expected_events[event.node->id()].insert(event.event_params.event);
+ expected_events[event.node_id].insert(event.event_params.event);
for (auto& entry : expected_events) {
AXNodeID node_id = entry.first;
diff --git a/ui/views/accessibility/views_ax_tree_manager.cc b/ui/views/accessibility/views_ax_tree_manager.cc
index 861009afe4fbe956ab63b3f261734a6d9590042b..d999c3cda6c3ef046c80a83f89909d3b8ed3fa38 100644
--- a/ui/views/accessibility/views_ax_tree_manager.cc
+++ b/ui/views/accessibility/views_ax_tree_manager.cc
@@ -185,7 +185,8 @@ void ViewsAXTreeManager::UnserializeTreeUpdates(
// AXEventGenerator to generate events based on the updates.
for (const ui::AXEventGenerator::TargetedEvent& targeted_event :
event_generator_) {
- FireGeneratedEvent(targeted_event.event_params.event, *targeted_event.node);
+ if (ui::AXNode* node = ax_tree().GetFromId(targeted_event.node_id))
+ FireGeneratedEvent(targeted_event.event_params.event, *node);
}
event_generator_.ClearEvents();
}

View File

@@ -5,6 +5,8 @@
"src/electron/patches/webrtc": "src/third_party/webrtc",
"src/electron/patches/pdfium": "src/third_party/pdfium",
"src/electron/patches/v8": "src/v8",
"src/electron/patches/node": "src/third_party/electron_node",
@@ -15,5 +17,7 @@
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"src/electron/patches/angle": "src/third_party/angle"
"src/electron/patches/angle": "src/third_party/angle",
"src/electron/patches/icu": "src/third_party/icu"
}

1
patches/icu/.patches Normal file
View File

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

View File

@@ -0,0 +1,349 @@
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 269fc7263ca642b24fd709312d6ecb70a9c8f48a..33c642b49be7fbebbe9b0f43edea565317e4c8ca 100644
--- a/README.chromium
+++ b/README.chromium
@@ -282,3 +282,7 @@ D. Local Modifications
- upstream PR:
https://github.com/unicode-org/icu/pull/1762
+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 b370f14f2ac4ff0873e5614376ae51fe0232b02d..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 overlow 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));

View File

@@ -31,3 +31,14 @@ fix_remove_expired_dst_root_ca_x3.patch
fix_system_python2_error.patch
fix_event_with_invalid_timestamp_in_trace_log.patch
test_fix_test-datetime-change-notify_after_daylight_change.patch
unix_protect_fork_in_uv_spawn_from_signals.patch
process_monitor_for_exit_with_kqueue_on_bsds_3441.patch
process_bsd_handle_kevent_note_exit_failure_3451.patch
reland_macos_use_posix_spawn_instead_of_fork_3257.patch
process_only_use_f_dupfd_cloexec_if_it_is_defined_3512.patch
unix_simplify_uv_cloexec_fcntl_3492.patch
unix_remove_uv_cloexec_ioctl_3515.patch
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
process_reset_the_signal_mask_if_the_fork_fails_3537.patch

View File

@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Noordhuis <info@bnoordhuis.nl>
Date: Wed, 9 Mar 2022 11:06:39 +0100
Subject: macos: don't use thread-unsafe strtok() (#3524)
Refs https://github.com/libuv/libuv/pull/3524
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index d40e3f9bebcdfbc5051c9a6af2452c2421728c9e..c0ec01c4b0ad32dcaa5438f5ca02030c31517095 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -380,30 +380,22 @@ static void uv__spawn_init_posix_spawn_fncs(void) {
static void uv__spawn_init_can_use_setsid(void) {
- static const int MACOS_CATALINA_VERSION_MAJOR = 19;
- char version_str[256];
- char* version_major_str;
- size_t version_str_size = 256;
- int r;
- int version_major;
-
- /* Get a version string */
- r = sysctlbyname("kern.osrelease", version_str, &version_str_size, NULL, 0);
- if (r != 0)
+ int which[] = {CTL_KERN, KERN_OSRELEASE};
+ unsigned major;
+ unsigned minor;
+ unsigned patch;
+ char buf[256];
+ size_t len;
+
+ len = sizeof(buf);
+ if (sysctl(which, ARRAY_SIZE(which), buf, &len, NULL, 0))
return;
- /* Try to get the major version number. If not found
- * fall back to the fork/exec flow */
- version_major_str = strtok(version_str, ".");
- if (version_major_str == NULL)
+ /* NULL specifies to use LC_C_LOCALE */
+ if (3 != sscanf_l(buf, NULL, "%u.%u.%u", &major, &minor, &patch))
return;
- /* Parse the version major as a number. If it is greater than
- * the major version for macOS Catalina (aka macOS 10.15), then
- * the POSIX_SPAWN_SETSID flag is available */
- version_major = atoi_l(version_major_str, NULL); /* Use LC_C_LOCALE */
- if (version_major >= MACOS_CATALINA_VERSION_MAJOR)
- posix_spawn_can_use_setsid = 1;
+ posix_spawn_can_use_setsid = (major >= 19); /* macOS Catalina */
}

View File

@@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash@gmail.com>
Date: Tue, 1 Feb 2022 15:27:12 -0500
Subject: process,bsd: handle kevent NOTE_EXIT failure (#3451)
The kernel may return ESRCH if the child has already exited here.
This is rather annoying, and means we must indirectly handle
notification to our event loop of the process exit.
Refs: https://github.com/libuv/libuv/pull/3441
Refs: https://github.com/libuv/libuv/pull/3257
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index cc15596f431aa42c30bc0510e38c0d5879a47c85..5bc9f36037594006e204dee31bc7d969bbf650d4 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -134,7 +134,8 @@ typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t;
/* loop flags */
enum {
- UV_LOOP_BLOCK_SIGPROF = 1
+ UV_LOOP_BLOCK_SIGPROF = 0x1,
+ UV_LOOP_REAP_CHILDREN = 0x2
};
/* flags of excluding ifaddr */
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 35200f17495d80ed2d19ef9f6f76bbc92ee042f6..071fe0ce0938657d0fb840af62a432352e938a8a 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -285,7 +285,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
for (i = 0; i < nfds; i++) {
ev = events + i;
if (ev->filter == EVFILT_PROC) {
- uv__wait_children(loop);
+ loop->flags |= UV_LOOP_REAP_CHILDREN;
nevents++;
continue;
}
@@ -383,6 +383,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
nevents++;
}
+ if (loop->flags & UV_LOOP_REAP_CHILDREN) {
+ loop->flags &= ~UV_LOOP_REAP_CHILDREN;
+ uv__wait_children(loop);
+ }
+
if (reset_timeout != 0) {
timeout = user_timeout;
reset_timeout = 0;
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index 3ee298b473ae4fbc2fa2039ba7150740b6717b73..690f542520160c7314a92b3f452867e83ee34594 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -507,8 +507,12 @@ int uv_spawn(uv_loop_t* loop,
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
struct kevent event;
EV_SET(&event, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, 0);
- if (kevent(loop->backend_fd, &event, 1, NULL, 0, NULL))
- abort();
+ if (kevent(loop->backend_fd, &event, 1, NULL, 0, NULL)) {
+ if (errno != ESRCH)
+ abort();
+ /* Process already exited. Call waitpid on the next loop iteration. */
+ loop->flags |= UV_LOOP_REAP_CHILDREN;
+ }
#endif
QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue);

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