Compare commits

..

58 Commits

Author SHA1 Message Date
trop[bot]
047fdbf3ca build: disable unneeded depot_tools update on Windows CI (#39017)
build: disable unneeded depot_tools update

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-07-10 10:43:51 +02:00
Pedro Pontes
1f91895d22 chore: cherry-pick 4 changes from Release-3-M114 (#38949)
* chore: [22-x-y] cherry-pick 4 changes from Release-3-M114

* 85beff6fd302 from chromium
* 60b93798c991 from chromium
* a1efa5343880 from v8
* d20849d07107 from webrtc

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-07-06 10:19:53 +09:00
David Sanders
4ade2a6fb6 build: use Xcode 13.4.1 (#38822) 2023-06-18 21:43:50 +02:00
Pedro Pontes
a68e328e53 chore: cherry-pick 5 changes from Release-2-M114, Release-1-M110 and Release-0-M110 (#38789)
* chore: [22-x-y] cherry-pick 1 changes from Release-2-M114

* 2e76270cf65e from v8

* chore: update patches

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-14 17:19:04 -04:00
Keeley Hammond
047f474eab chore: cherry-pick 7 changes from Release-0-M114 (#38534)
* chore: [22-x-y] cherry-pick 6 changes from Release-0-M114

* c6ec59dcae7d from angle
* 93c6be3a42e7 from chromium
* e6b75a8b4900 from chromium
* 3b0607d14060 from v8
* 9c6dfc733fce from v8
* ea1cd76358e0 from chromium

* chore: remove 2 invalid patches, fix 2 others

* chore: remove unnecessary patch.

* chore: add missing backports.

* chore: further fix a backport

* chore: update patches

---------

Co-authored-by: Pedro Pontes <pepontes@microsoft.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-09 12:24:31 -07:00
trop[bot]
81bc1ea876 build: upload node checksums before validating them (#38719)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-06-09 12:19:23 -07:00
trop[bot]
c676c0aaca build: move uploadIndexJson to just before publishRelease (#38702)
* build: move uploadIndexJson to just before publishRelease

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

* chore: move uploadNodeShasums as well

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-06-08 15:31:02 -07:00
Keeley Hammond
399d2b2d2c chore: cherry-pick 8 changes from Release-1-M113 (#38332)
* chore: [22-x-y] cherry-pick 8 changes from Release-1-M113

* f4c70bc5e89b from v8
* 257a63512782 from v8
* 9964ff18eada from chromium
* a1abaf29e189 from angle
* fe45418c6592 from angle
* d2ce640f16f2 from chromium
* bae60787d3e9 from dawn

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-08 16:24:45 -04:00
Pedro Pontes
1d60268033 chore: cherry-pick 2 changes from Release-1-M114 (#38653)
* chore: [22-x-y] cherry-pick 2 changes from Release-1-M114

* 73af1a19a901 from v8
* 0035a4a8dac2 from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-08 12:34:57 +02:00
David Sanders
609855101c build: upgrade @electron/github-app-auth to 2.0.0 (#38665)
build: upgrade @electron/github-app-auth to 2.0.0 (#38435)
2023-06-07 23:48:46 -07:00
trop[bot]
d654650f7b build: improve error output in release.js (#38662)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-06-07 19:18:05 -07:00
John Kleinschmidt
a6ce1bc96d build: drop python2 from CI (#38554)
build: drop python2 from CI (#38303)

(cherry picked from commit a22e2a778e)
(cherry picked from commit 9bdd4738ae)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2023-06-01 15:04:06 -04:00
trop[bot]
2cdaab741d docs: add <webview> new-window event removal to breaking-changes.md (#38524)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-05-31 15:50:36 -04:00
Pedro Pontes
b07f2f0f42 chore: cherry-pick cf90db14f2 from chromium (#38277)
* chore: cherry-pick cf90db14f2 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-05-18 11:30:22 -04:00
trop[bot]
df6f23bbd1 build: modify gclient.py with unified patch (#38370)
* build: modify gclient.py with unified patch

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* ci: ensure depot_tools does not update

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* ci: move auto-update disable outside if

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-17 20:01:34 -04:00
Pedro Pontes
900459e1b1 chore: cherry-pick 81d7b3e613 from chromium (#38274)
* chore: cherry-pick 81d7b3e613 from chromium

* build: bump brew cache to v6

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
(cherry picked from commit dbf986662b)

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2023-05-17 10:36:43 +02:00
Valentin Hăloiu
5af5b42422 chore: cherry-pick d42c3e5fb7c3 from chromium (#38199) 2023-05-09 10:07:06 +02:00
Alexey Kuzmin
de3a8a5389 test: use await to call "closeWindow" (#38172) 2023-05-04 10:48:07 +02:00
Robo
8c172f2e95 fix: crash in utilityProcess when generating code from strings (#38156)
fix: crash in utilityProcess when generating code from strings (#38040)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2023-05-03 09:56:25 +02:00
Pedro Pontes
6820094f8e chore: cherry-pick f098ff0d1230 from chromium (#38060)
chore: [22-x-y] cherry-pick f098ff0d1230 from chromium

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-26 10:11:51 +02:00
Pedro Pontes
f907c18bac chore: cherry-pick f58218891f8c from chromium (#38056)
* chore: [22-x-y] cherry-pick f58218891f8c from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-04-25 11:45:26 +02:00
Milan Burda
27575566c9 fix: defaults broken in shell.openExternal() options (#38092)
fix: defaults broken in shell.openExternal() options (#38038)

Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-04-24 15:25:29 +02:00
Pedro Pontes
518d3e490d chore: cherry-pick 2b30a50d0e62 from chromium (#38058)
* chore: [22-x-y] cherry-pick 2b30a50d0e62 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-24 14:25:32 +02:00
Pedro Pontes
29cdcb443a chore: cherry-pick 1d491fff578b, f7b87bea19d7 and 549d92d7ef35 from chromium (#38068)
* chore: cherry-pick 1d491fff578b from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-24 11:09:04 +02:00
Pedro Pontes
4c435b27e0 chore: cherry-pick 8421a9eebd8a and 4dc670a8c557 from skia (#38066)
chore: cherry-pick 9e1af6fa14ff from skia
2023-04-23 22:54:38 +02:00
Pedro Pontes
85317c3109 chore: cherry-pick 63686953dc22 from chromium (#38062)
* chore: cherry-pick 63686953dc22 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-04-23 22:15:35 +02:00
Pedro Pontes
ea7e3c80ee chore: cherry-pick aed05b609629 from angle (#38064)
* chore: cherry-pick aed05b609629 from angle

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-04-23 22:14:29 +02:00
Pedro Pontes
f0685b60a7 chore: cherry-pick 86fc0e9bedaf from chromium (#37665) 2023-04-17 21:11:55 -04:00
GhostlyDark
7fd1f3da64 fix: set background color for menu bar on Windows (#37991) 2023-04-17 11:24:39 -04:00
Pedro Pontes
c6b44676e6 chore: cherry-pick c605df24af3c from v8 (#37980)
* chore: [22-x-y] cherry-pick c605df24af3c from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-04-17 11:18:21 -04:00
Pedro Pontes
69d1434bcc chore: cherry-pick f4b66ae451c2 from v8 (#37983) 2023-04-15 21:20:49 -07:00
trop[bot]
f843f23363 fix: defaultFontFamily in webPreferences (#37970)
* fix: defaultFontFamily in webPreferences

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

* chore: check if default_font_family_ is empty

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-13 21:08:40 -04:00
trop[bot]
fcbd88f8aa fix: exceptions during function/promise result conversions live in calling world (#37923)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-04-13 15:10:54 +09:00
Darshan Sen
ee668f1472 fix: recommended node-gyp version in node.h error (#37942)
fix: recommended `node-gyp` version in `node.h` error (#37829)

fix: recommended node-gyp version in node.h error

In
https://github.com/electron/electron/blob/main/docs/tutorial/using-native-node-modules.md#using-npm,
we recommend setting the `npm_config_disturl` variable but doing that
does not work on node-gyp v8.4.0 because after
https://github.com/nodejs/node-gyp/pull/2497
landed, the dist URL was read only from `gyp.opts['dist-url']`. The fix
for reading the value from `npm_config_disturl` by parsing
`gyp.opts.disturl` was landed in
https://github.com/nodejs/node-gyp/pull/2547 and that change was
released in node-gyp v9.0.0, so this change updates the error macro to
recommend node-gyp v9.0.0 as the minimum required version.

Signed-off-by: Darshan Sen <raisinten@gmail.com>
2023-04-12 13:16:35 +02:00
Pedro Pontes
c875adf7cf chore: cherry-pick d6946b70b431 from chromium (#37848)
* chore: [22-x-y] cherry-pick d6946b70b431 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-04-11 21:13:19 +02:00
trop[bot]
3cd2f2ede9 docs: fix app.getPreferredSystemLanguages() return type (#37836)
docs: fix app.getPreferredSystemLanguages() return type

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-11 13:24:24 +02:00
trop[bot]
e2c4acd505 fix: apply csp correctly when contextIsolation: false (#37843)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-04-11 16:23:01 +09:00
trop[bot]
620bdcbb2a test: support 'latest'/'latest@X' Electron version strings (#37869)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-11 16:20:49 +09:00
trop[bot]
ae7b2ae3cb fix: exceptions in nested conversions live in the target world (#37899)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-04-10 20:00:07 -07:00
Pedro Pontes
ffff96e33f chore: cherry-pick d9081493c4b2 from chromium (#37850)
* chore: [22-x-y] cherry-pick d9081493c4b2 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-04-06 13:13:16 +02:00
trop[bot]
7a4a94b18c fix: record helper error messages in electron_main_mac (#37813)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-04-04 15:43:14 +02:00
yehengxuan
62dddd12ed chore: fix memory leak in v8.serialize() (#37774) 2023-04-03 13:20:45 +02:00
Pedro Pontes
0b17a20119 chore: cherry-pick b5c9e5efe5dd from chromium (#37693)
* chore: [22-x-y] cherry-pick b5c9e5efe5dd from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-29 12:14:44 +02:00
Pedro Pontes
f557f99631 chore: cherry-pick b041159d06ad from chromium (#37694)
* chore: [22-x-y] cherry-pick b041159d06ad from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-29 12:14:34 +02:00
trop[bot]
4b5998e51a fix: allow cancelling of bluetooth requests (#37739)
fix: allow cancelling of bluetooth requests (#37601)

(cherry picked from commit 6a6908c4c8)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-29 12:08:53 +02:00
trop[bot]
de3bc8cb4c chore: generator objects can't be sent over the context bridge (#37728)
chore: generator objects can't be sent over the context bridge (#37593)

* chore: generator objects can't be sent over the context bridge

* Trigger Build

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-28 11:39:36 -04:00
trop[bot]
ba1a2f3d0f docs: fixup incorrect value for disabling sandbox (#37722)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Peter Xu <sysu.peter.hsu@gmail.com>
2023-03-28 10:50:05 -04:00
trop[bot]
352ab57670 fix: crash in MessagePortMain with some postMessage params (#37725)
* fix: crash in MessagePortMain postMessage

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* Update shell/browser/api/message_port.cc

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

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-28 10:39:01 -04:00
Pedro Pontes
4a7bf76fa1 chore: cherry-pick 0407102d19b9 and 183a57f4eabc from chromium (#37661)
* chore: cherry-pick 0407102d19b9 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-27 19:56:27 -04:00
Pedro Pontes
978cc7bd7d chore: cherry-pick 56bd20b295b4 from chromium (#37652)
* chore: [22-x-y] cherry-pick 56bd20b295b4 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-27 18:20:02 -04:00
Pedro Pontes
94c7ad9ee2 chore: cherry-pick bfd926be8178 from chromium (#37659)
* chore: cherry-pick bfd926be8178 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-27 18:19:18 -04:00
Pedro Pontes
be71423d32 chore: cherry-pick aeceeb2187a6 from v8 (#37654)
* chore: [22-x-y] cherry-pick aeceeb2187a6 from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-27 14:48:44 -04:00
Pedro Pontes
565c4fe9a7 chore: cherry-pick 9aa4c45f21b1 from chromium (#37650)
* chore: [22-x-y] cherry-pick 9aa4c45f21b1 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-27 13:50:20 -04:00
Pedro Pontes
c0caa61022 chore: cherry-pick 1235110fce18 from chromium (#37691)
* chore: [22-x-y] cherry-pick 1235110fce18 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-27 12:21:26 -04:00
Pedro Pontes
f19e6d516a chore: cherry-pick ce029c91a662 from angle (#37696)
* chore: [22-x-y] cherry-pick ce029c91a662 from angle

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-27 11:18:58 -04:00
Pedro Pontes
3931d5a84f chore: cherry-pick a0d16d18d072 from pdfium (#37698) 2023-03-27 09:36:30 -04:00
Pedro Pontes
8a2e936053 chore: cherry-pick 86fc0e9bedaf and 8d52bc14b306 from chromium (#37669)
* chore: cherry-pick 86fc0e9bedaf from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-23 19:08:00 -04:00
trop[bot]
c43eed8782 ci: fixup gn check to actually run gn check (#37681)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-23 17:52:38 -04:00
124 changed files with 7937 additions and 524 deletions

View File

@@ -54,7 +54,7 @@ executors:
type: enum
enum: ["macos.x86.medium.gen2", "large"]
macos:
xcode: 13.3.0
xcode: 13.4.1
resource_class: << parameters.size >>
# Electron Runners
@@ -243,14 +243,27 @@ step-depot-tools-get: &step-depot-tools-get
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
cd depot_tools
patch gclient.py -R \<<'EOF'
676,677c676
< packages = dep_value.get('packages', [])
< for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
---
> for package in dep_value.get('packages', []):
cat > gclient.diff \<< 'EOF'
diff --git a/gclient.py b/gclient.py
index 3a9c5c6..f222043 100755
--- a/gclient.py
+++ b/gclient.py
@@ -712,7 +712,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
if dep_type == 'cipd':
cipd_root = self.GetCipdRoot()
- for package in dep_value.get('packages', []):
+ packages = dep_value.get('packages', [])
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
deps_to_add.append(
CipdDependency(
parent=self,
EOF
git apply --3way gclient.diff
fi
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
step-depot-tools-add-to-path: &step-depot-tools-add-to-path
run:
@@ -272,7 +285,7 @@ step-gclient-sync: &step-gclient-sync
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
if [ "$IS_RELEASE" != "true" ]; then
# Re-export all the patches to check if there were changes.
python src/electron/script/export_all_patches.py src/electron/patches/config.json
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron
git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then
@@ -326,8 +339,8 @@ step-setup-goma-for-build: &step-setup-goma-for-build
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
third_party/goma/goma_ctl.py ensure_start
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
python3 third_party/goma/goma_ctl.py ensure_start
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`python3 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
@@ -355,14 +368,14 @@ step-restore-brew-cache: &step-restore-brew-cache
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
keys:
- v5-brew-cache-{{ arch }}
- v7-brew-cache-{{ arch }}
step-save-brew-cache: &step-save-brew-cache
save_cache:
paths:
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
key: v5-brew-cache-{{ arch }}
key: v7-brew-cache-{{ arch }}
name: Persisting brew cache
step-get-more-space-on-mac: &step-get-more-space-on-mac
@@ -731,9 +744,9 @@ step-verify-mksnapshot: &step-verify-mksnapshot
if [ "$IS_ASAN" != "1" ]; then
cd src
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
else
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
fi
fi
@@ -743,7 +756,7 @@ step-verify-chromedriver: &step-verify-chromedriver
command: |
if [ "$IS_ASAN" != "1" ]; then
cd src
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
python3 electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
fi
step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
@@ -859,7 +872,7 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
elif [ "`uname`" == "Darwin" ]; then
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.dylib" out/Default
fi
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
mkdir cross-arch-snapshots
cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
fi
@@ -1011,26 +1024,12 @@ step-ts-compile: &step-ts-compile
# List of all steps.
steps-electron-gn-check: &steps-electron-gn-check
steps:
- *step-checkout-electron
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- install-python2-mac
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-generate-deps-hash
- *step-touch-sync-done
- maybe-restore-portaled-src-cache
- run:
name: Ensure src checkout worked
command: |
if [ ! -d "src/third_party/blink" ]; then
echo src cache was not restored for an unknown reason
exit 1
fi
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- checkout-from-cache
- *step-setup-env-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- *step-gn-check
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
steps:
@@ -1052,7 +1051,6 @@ steps-tests: &steps-tests
- *step-setup-linux-for-headless-testing
- *step-restore-brew-cache
- *step-fix-known-hosts-linux
- install-python2-mac
- *step-install-signing-cert-on-mac
- run:
@@ -1136,31 +1134,6 @@ steps-test-node: &steps-test-node
# Command Aliases
commands:
install-python2-mac:
steps:
- restore_cache:
keys:
- v2.7.18-python-cache-{{ arch }}
name: Restore python cache
- run:
name: Install python2 on macos
command: |
if [ "`uname`" == "Darwin" ] && [ "$IS_ELECTRON_RUNNER" != "1" ]; then
if [ ! -f "python-downloads/python-2.7.18-macosx10.9.pkg" ]; then
mkdir python-downloads
echo 'Downloading Python 2.7.18'
curl -O https://dev-cdn.electronjs.org/python/python-2.7.18-macosx10.9.pkg
mv python-2.7.18-macosx10.9.pkg python-downloads
else
echo 'Using Python install from cache'
fi
sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
fi
- save_cache:
paths:
- python-downloads
key: v2.7.18-python-cache-{{ arch }}
name: Persisting python cache
maybe-restore-portaled-src-cache:
parameters:
halt-if-successful:
@@ -1324,7 +1297,6 @@ commands:
- run: rm -rf src/electron
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- install-python2-mac
- *step-save-brew-cache
- when:
condition: << parameters.build >>
@@ -1496,7 +1468,6 @@ commands:
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-restore-brew-cache
- install-python2-mac
- *step-get-more-space-on-mac
- when:
condition: << parameters.checkout >>
@@ -2214,4 +2185,4 @@ workflows:
jobs:
- lint
# VS Code Extension Version: 1.4.0
# VS Code Extension Version: 1.4.0

View File

@@ -83,6 +83,8 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
- depot_tools\bootstrap\win_tools.bat
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {

View File

@@ -81,6 +81,8 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
- depot_tools\bootstrap\win_tools.bat
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {

View File

@@ -748,14 +748,21 @@ This API can be used for purposes such as deciding what language to present the
Here are some examples of return values of the various language and locale APIs with different configurations:
* For Windows, where the application locale is German, the regional format is Finnish (Finland), and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese (China), Finnish, and Spanish (Latin America):
* `app.getLocale()` returns `'de'`
* `app.getSystemLocale()` returns `'fi-FI'`
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-CN', 'fi', 'es-419']`
* On macOS, where the application locale is German, the region is Finland, and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese, and Spanish (Latin America):
* `app.getLocale()` returns `'de'`
* `app.getSystemLocale()` returns `'fr-FI'`
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-FI', 'es-419']`
On Windows, given application locale is German, the regional format is Finnish (Finland), and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese (China), Finnish, and Spanish (Latin America):
```js
app.getLocale() // 'de'
app.getSystemLocale() // 'fi-FI'
app.getPreferredSystemLanguages() // ['fr-CA', 'en-US', 'zh-Hans-CN', 'fi', 'es-419']
```
On macOS, given the application locale is German, the region is Finland, and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese, and Spanish (Latin America):
```js
app.getLocale() // 'de'
app.getSystemLocale() // 'fr-FI'
app.getPreferredSystemLanguages() // ['fr-CA', 'en-US', 'zh-Hans-FI', 'es-419']
```
Both the available languages and regions and the possible return values differ between the two operating systems.

View File

@@ -713,20 +713,24 @@ Returns:
* `callback` Function
* `deviceId` string
Emitted when bluetooth device needs to be selected on call to
`navigator.bluetooth.requestDevice`. To use `navigator.bluetooth` api
`webBluetooth` should be enabled. If `event.preventDefault` is not called,
first available device will be selected. `callback` should be called with
`deviceId` to be selected, passing empty string to `callback` will
cancel the request.
Emitted when a bluetooth device needs to be selected when a call to
`navigator.bluetooth.requestDevice` is made. `callback` should be called with
the `deviceId` of the device to be selected. Passing an empty string to
`callback` will cancel the request.
If no event listener is added for this event, all bluetooth requests will be cancelled.
If an event listener is not added for this event, or if `event.preventDefault`
is not called when handling this event, the first available device will be
automatically selected.
Due to the nature of bluetooth, scanning for devices when
`navigator.bluetooth.requestDevice` is called may take time and will cause
`select-bluetooth-device` to fire multiple times until `callback` is called
with either a device id or an empty string to cancel the request.
```javascript
const { app, BrowserWindow } = require('electron')
let win = null
app.commandLine.appendSwitch('enable-experimental-web-platform-features')
app.whenReady().then(() => {
win = new BrowserWindow({ width: 800, height: 600 })
@@ -736,6 +740,9 @@ app.whenReady().then(() => {
return device.deviceName === 'test'
})
if (!result) {
// The device wasn't found so we need to either wait longer (eg until the
// device is turned on) or cancel the request by calling the callback
// with an empty string.
callback('')
} else {
callback(result.deviceId)

View File

@@ -56,6 +56,39 @@ webContents.setWindowOpenHandler((details) => {
})
```
### Removed: `<webview>` `new-window` event
The `new-window` event of `<webview>` has been removed. There is no direct replacement.
```js
// Removed in Electron 22
webview.addEventListener('new-window', (event) => {})
```
```javascript fiddle='docs/fiddles/ipc/webview-new-window'
// Replace with
// main.js
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
wc.setWindowOpenHandler((details) => {
mainWindow.webContents.send('webview-new-window', wc.id, details)
return { action: 'deny' }
})
})
// preload.js
const { ipcRenderer } = require('electron')
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
console.log('webview-new-window', webContentsId, details)
document.getElementById('webview').dispatchEvent(new Event('new-window'))
})
// renderer.js
document.getElementById('webview').addEventListener('new-window', () => {
console.log('got new-window event')
})
```
### Deprecated: BrowserWindow `scroll-touch-*` events
The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on

View File

@@ -9,6 +9,7 @@
<h1>Web Bluetooth API</h1>
<button id="clickme">Test Bluetooth</button>
<button id="cancel">Cancel Bluetooth Request</button>
<p>Currently selected bluetooth device: <strong id="device-name""></strong></p>

View File

@@ -1,22 +1,37 @@
const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')
let bluetoothPinCallback
let selectBluetoothCallback
function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
}
})
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
event.preventDefault()
if (deviceList && deviceList.length > 0) {
callback(deviceList[0].deviceId)
}
selectBluetoothCallback = callback
const result = deviceList.find((device) => {
return device.deviceName === 'test'
})
if (result) {
callback(result.deviceId)
} else {
// The device wasn't found so we need to either wait longer (eg until the
// device is turned on) or until the user cancels the request
}
})
ipcMain.on('cancel-bluetooth-request', (event) => {
selectBluetoothCallback('')
})
// Listen for a message from the renderer to get the response for the Bluetooth pairing.
ipcMain.on('bluetooth-pairing-response', (event, response) => {
bluetoothPinCallback(response)
@@ -27,14 +42,14 @@ function createWindow () {
bluetoothPinCallback = callback
// Send a message to the renderer to prompt the user to confirm the pairing.
mainWindow.webContents.send('bluetooth-pairing-request', details)
})
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -1,6 +1,7 @@
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
cancelBluetoothRequest: (callback) => ipcRenderer.send('cancel-bluetooth-request', callback),
bluetoothPairingRequest: (callback) => ipcRenderer.on('bluetooth-pairing-request', callback),
bluetoothPairingResponse: (response) => ipcRenderer.send('bluetooth-pairing-response', response)
})

View File

@@ -7,9 +7,15 @@ async function testIt() {
document.getElementById('clickme').addEventListener('click',testIt)
function cancelRequest() {
window.electronAPI.cancelBluetoothRequest()
}
document.getElementById('cancel').addEventListener('click', cancelRequest)
window.electronAPI.bluetoothPairingRequest((event, details) => {
const response = {}
switch (details.pairingKind) {
case 'confirm': {
response.confirmed = confirm(`Do you want to connect to device ${details.deviceId}?`)
@@ -31,4 +37,4 @@ window.electronAPI.bluetoothPairingRequest((event, details) => {
}
window.electronAPI.bluetoothPairingResponse(response)
})
})

View File

@@ -0,0 +1,3 @@
<body>
<a href="child.html" target="_blank">new window</a>
</body>

View File

@@ -0,0 +1,4 @@
<body>
<webview id=webview src="child.html" allowpopups></webview>
<script src="renderer.js"></script>
</body>

View File

@@ -0,0 +1,51 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
webviewTag: true
}
})
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
wc.setWindowOpenHandler((details) => {
mainWindow.webContents.send('webview-new-window', wc.id, details)
return { action: 'deny' }
})
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -0,0 +1,6 @@
const { ipcRenderer } = require('electron')
const webview = document.getElementById('webview')
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
console.log('webview-new-window', webContentsId, details)
webview.dispatchEvent(new Event('new-window'))
})

View File

@@ -0,0 +1,4 @@
const webview = document.getElementById('webview')
webview.addEventListener('new-window', () => {
console.log('got new-window event')
})

View File

@@ -84,7 +84,7 @@ the `sandbox: false` preference in the [`BrowserWindow`][browser-window] constru
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
sandbox: true
sandbox: false
}
})
win.loadURL('https://google.com')

View File

@@ -7,7 +7,7 @@
"@azure/storage-blob": "^12.9.0",
"@electron/docs-parser": "^1.0.0",
"@electron/fiddle-core": "^1.0.4",
"@electron/github-app-auth": "^1.5.0",
"@electron/github-app-auth": "^2.0.0",
"@electron/typescript-definitions": "^8.10.0",
"@octokit/rest": "^19.0.7",
"@primer/octicons": "^10.0.0",

View File

@@ -1,2 +1,6 @@
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
cherry-pick-55e2b6daba9d.patch
cherry-pick-ce029c91a662.patch
cherry-pick-aed05b609629.patch
translator_limit_the_size_of_private_variables_in_webgl_shaders.patch
webgl_limit_total_size_of_private_data.patch

View File

@@ -0,0 +1,108 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Fri, 31 Mar 2023 16:44:35 -0400
Subject: M112: Mark RGBX and BGRX formats as having 8 unused bits.
This makes sure that pixelBytes ends up being 4 and fixes potential
buffer size validation.
Fix EGL configs using pixelBytes to compute EGL_BUFFER_SIZE which
is not supposed to include unused bits. This is covered by
dEQP-EGL.functional.query_config.constraints.color_buffer_size
Bug: chromium:1404790
Change-Id: Ie0480cbdc6229c4bb3a6c6242337eaed5a3ae3b7
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4428752
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index 76273f3be3406a1c4be11c8fe564e3f703aed4b9..4014953311976b0f1ae2d1842e8fced75ffecfc9 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -549,6 +549,21 @@ bool InternalFormat::isDepthOrStencil() const
return depthBits != 0 || stencilBits != 0;
}
+GLuint InternalFormat::getEGLConfigBufferSize() const
+{
+ // EGL config's EGL_BUFFER_SIZE is measured in bits and is the sum of all the color channels for
+ // color formats or the luma channels for luma formats. It ignores unused bits so compute the
+ // bit count by summing instead of using pixelBytes.
+ if (isLUMA())
+ {
+ return luminanceBits + alphaBits;
+ }
+ else
+ {
+ return redBits + greenBits + blueBits + alphaBits;
+ }
+}
+
Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) {}
Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) {}
@@ -1141,10 +1156,10 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
AddRGBAFormat(&map, GL_BGR10_A2_ANGLEX, true, 10, 10, 10, 2, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
// Special format to emulate RGB8 with RGBA8 within ANGLE.
- AddRGBAFormat(&map, GL_RGBX8_ANGLE, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGBX8_ANGLE, true, FB< 8, 8, 8, 0, 8, 0>(), GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, NeverSupported);
// Special format to emulate BGR8 with BGRA8 within ANGLE.
- AddRGBAFormat(&map, GL_BGRX8_ANGLEX, true, 8, 8, 8, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_BGRX8_ANGLEX, true, FB< 8, 8, 8, 0, 8, 0>(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
// This format is supported on ES 2.0 with two extensions, so keep it out-of-line to not widen the table above even more.
// | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
diff --git a/src/libANGLE/formatutils.h b/src/libANGLE/formatutils.h
index 64cc42ec1f50ea017216063896ba2c07296cde37..e6154072365a8a253937a3f148ae12f7199c593c 100644
--- a/src/libANGLE/formatutils.h
+++ b/src/libANGLE/formatutils.h
@@ -205,6 +205,8 @@ struct InternalFormat
bool isInt() const;
bool isDepthOrStencil() const;
+ GLuint getEGLConfigBufferSize() const;
+
bool operator==(const InternalFormat &other) const;
bool operator!=(const InternalFormat &other) const;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index cc56e9868248a192b6c22e650528986c88722503..040623866da9b78ca66efb7de4f8678dd98f5f1c 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -1242,7 +1242,7 @@ egl::ConfigSet Renderer11::generateConfigs()
egl::Config config;
config.renderTargetFormat = colorBufferInternalFormat;
config.depthStencilFormat = depthStencilBufferInternalFormat;
- config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
+ config.bufferSize = colorBufferFormatInfo.getEGLConfigBufferSize();
config.redSize = colorBufferFormatInfo.redBits;
config.greenSize = colorBufferFormatInfo.greenBits;
config.blueSize = colorBufferFormatInfo.blueBits;
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index d80997392d2d5d25cadc1381c84929401bce90a9..6979fe5445360e6703cdb35fd9a15a6e34d188c8 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -523,7 +523,7 @@ egl::ConfigSet Renderer9::generateConfigs()
egl::Config config;
config.renderTargetFormat = colorBufferInternalFormat;
config.depthStencilFormat = depthStencilBufferInternalFormat;
- config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
+ config.bufferSize = colorBufferFormatInfo.getEGLConfigBufferSize();
config.redSize = colorBufferFormatInfo.redBits;
config.greenSize = colorBufferFormatInfo.greenBits;
config.blueSize = colorBufferFormatInfo.blueBits;
diff --git a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
index f49b24744682910ae5142f784c9e01ba1977c360..f601b516441fdb4db9e17db5ad22cb6198755e99 100644
--- a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
@@ -1238,7 +1238,7 @@ egl::Config GenerateDefaultConfig(DisplayVk *display,
config.renderTargetFormat = colorFormat.internalFormat;
config.depthStencilFormat = depthStencilFormat.internalFormat;
- config.bufferSize = colorFormat.pixelBytes * 8;
+ config.bufferSize = colorFormat.getEGLConfigBufferSize();
config.redSize = colorFormat.redBits;
config.greenSize = colorFormat.greenBits;
config.blueSize = colorFormat.blueBits;

View File

@@ -0,0 +1,158 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Fri, 10 Mar 2023 13:48:03 -0500
Subject: M110: D3D11: Add logic to disassociate EGL image storages.
The TextureStorage classes for External and EGLImages were missing the
logic to disassociate from images. This lead to the images continuing
to hold references to deleted storages.
Bug: chromium:1415330
Change-Id: I8303f6751d87a9b0a52993c7d4e9509b086b93f3
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4328347
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
(cherry picked from commit a8720455fda43167465c3d2f9a13fca60c21f56e)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4348335
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
index f1277462a929ed867a325f12db5fbf011b3f678e..c2fe439ca826e86b023dbe982ff44dd3bfb56470 100644
--- a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -1652,7 +1652,8 @@ TextureStorage11_External::TextureStorage11_External(
egl::Stream *stream,
const egl::Stream::GLTextureDescription &glDesc,
const std::string &label)
- : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label)
+ : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label),
+ mAssociatedImage(nullptr)
{
ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture);
auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation());
@@ -1678,6 +1679,15 @@ angle::Result TextureStorage11_External::onDestroy(const gl::Context *context)
mRenderer->getStateManager()->invalidateBoundViews();
}
+ if (mAssociatedImage != nullptr)
+ {
+ mAssociatedImage->verifyAssociatedStorageValid(this);
+
+ // We must let the Images recover their data before we delete it from the
+ // TextureStorage.
+ ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
+ }
+
return angle::Result::Continue;
}
@@ -1885,7 +1895,8 @@ TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
mImage(eglImage),
mCurrentRenderTarget(0),
mSwizzleTexture(),
- mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS),
+ mAssociatedImage(nullptr)
{
mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
@@ -1897,6 +1908,20 @@ TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {}
+angle::Result TextureStorage11_EGLImage::onDestroy(const gl::Context *context)
+{
+ if (mAssociatedImage != nullptr)
+ {
+ mAssociatedImage->verifyAssociatedStorageValid(this);
+
+ // We must let the Images recover their data before we delete it from the
+ // TextureStorage.
+ ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
+ }
+
+ return angle::Result::Continue;
+}
+
angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context,
const gl::ImageIndex &index,
UINT *outSubresourceIndex) const
@@ -2120,6 +2145,42 @@ void TextureStorage11_EGLImage::onLabelUpdate()
}
}
+void TextureStorage11_EGLImage::associateImage(Image11 *image, const gl::ImageIndex &index)
+{
+ ASSERT(index.getLevelIndex() == 0);
+ mAssociatedImage = image;
+}
+
+void TextureStorage11_EGLImage::verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage);
+}
+
+void TextureStorage11_EGLImage::disassociateImage(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ ASSERT(index.getLevelIndex() == 0);
+ ASSERT(mAssociatedImage == expectedImage);
+ mAssociatedImage = nullptr;
+}
+
+angle::Result TextureStorage11_EGLImage::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage)
+{
+ ASSERT(index.getLevelIndex() == 0);
+
+ if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage)
+ {
+ mAssociatedImage->verifyAssociatedStorageValid(this);
+
+ ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
+ }
+
+ return angle::Result::Continue;
+}
+
TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer,
GLenum internalformat,
BindFlags bindFlags,
diff --git a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
index 72bc1b802c5d4f2befe7a440aae8e115d5b94c8a..7c5245acd8fcb7880f19905c0f69c7b7886e9e72 100644
--- a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
@@ -492,6 +492,8 @@ class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
const std::string &label);
~TextureStorage11_EGLImage() override;
+ angle::Result onDestroy(const gl::Context *context) override;
+
angle::Result getSubresourceIndex(const gl::Context *context,
const gl::ImageIndex &index,
UINT *outSubresourceIndex) const override;
@@ -518,6 +520,13 @@ class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
bool useLevelZeroTexture) override;
void onLabelUpdate() override;
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+
protected:
angle::Result getSwizzleTexture(const gl::Context *context,
const TextureHelper11 **outTexture) override;
@@ -545,6 +554,8 @@ class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
// Swizzle-related variables
TextureHelper11 mSwizzleTexture;
std::vector<d3d11::RenderTargetView> mSwizzleRenderTargets;
+
+ Image11 *mAssociatedImage;
};
class TextureStorage11_Cube : public TextureStorage11

View File

@@ -0,0 +1,87 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Tue, 28 Mar 2023 11:43:23 -0400
Subject: Translator: Limit the size of private variables in WebGL shaders
As a follow up to
https://chromium-review.googlesource.com/c/angle/angle/+/3023033, the
limit to shader-private variables (locals and globals) is further
reduced to 1MB. A variable that large will not fit in GPU registers and
will spill to memory, killing performance.
Bug: chromium:1427865
Change-Id: I77314d4b891c591cd9a83ad2aebb77d7256f3ada
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4377639
Reviewed-by: Kenneth Russell <kbr@chromium.org>
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index c9607db74b53487950d31f6a56d55f3e834556a0..6097b6d236b547710aeaf37a6fb45df97d621ca0 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -20,9 +20,13 @@ namespace sh
namespace
{
-// Arbitrarily enforce that types - even local variables' - declared
-// with a size in bytes of over 2 GB will cause compilation failure.
-constexpr size_t kMaxTypeSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
+// Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause
+// compilation failure.
+//
+// For local and global variables, the limit is much lower (1MB) as that much memory won't fit in
+// the GPU registers anyway.
+constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
// Traverses intermediate tree to ensure that the shader does not
// exceed certain implementation-defined limits on the sizes of types.
@@ -78,13 +82,24 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
// whether the row-major layout is correctly determined.
bool isRowMajorLayout = false;
TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
- if (layoutEncoder.getCurrentOffset() > kMaxTypeSizeInBytes)
+ if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
{
error(asSymbol->getLine(),
"Size of declared variable exceeds implementation-defined limit",
asSymbol->getName());
return false;
}
+
+ const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
+ variableType.getQualifier() == EvqGlobal ||
+ variableType.getQualifier() == EvqConst;
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared private variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
}
return true;
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 7dc56cddbc63add1aca6fca3bfd031f3da8d04fc..f4bd19baf3582c0b4a840d73a57ea6fc385159a6 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5283,8 +5283,8 @@ void main()
constexpr char kVSArrayTooLarge[] =
R"(varying vec4 color;
-// 2 GB / 32 aligned bytes per mat2 = 67108864
-const int array_size = 67108865;
+// 1 MB / 32 aligned bytes per mat2 = 32768
+const int array_size = 32769;
void main()
{
mat2 array[array_size];
@@ -5296,7 +5296,7 @@ void main()
constexpr char kVSArrayMuchTooLarge[] =
R"(varying vec4 color;
-const int array_size = 556007917;
+const int array_size = 55600;
void main()
{
mat2 array[array_size];

View File

@@ -0,0 +1,207 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Wed, 3 May 2023 13:41:36 -0400
Subject: WebGL: Limit total size of private data
... not just individual arrays.
Bug: chromium:1431761
Change-Id: I721e29aeceeaf12c3f6a67b668abffb8dfbc89b0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4503753
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index 6097b6d236b547710aeaf37a6fb45df97d621ca0..2a033ad9d9422349865a9f2af7084bbf1c2c23d9 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -35,7 +35,9 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
{
public:
ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
- : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mDiagnostics(diagnostics),
+ mTotalPrivateVariablesSize(0)
{
ASSERT(diagnostics);
}
@@ -93,18 +95,33 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
variableType.getQualifier() == EvqGlobal ||
variableType.getQualifier() == EvqConst;
- if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
+ if (isPrivate)
{
- error(asSymbol->getLine(),
- "Size of declared private variable exceeds implementation-defined limit",
- asSymbol->getName());
- return false;
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared private variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+ mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
}
}
return true;
}
+ void validateTotalPrivateVariableSize()
+ {
+ if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
+ {
+ mDiagnostics->error(
+ TSourceLoc{},
+ "Total size of declared private variables exceeds implementation-defined limit",
+ "");
+ }
+ }
+
private:
void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
{
@@ -213,6 +230,8 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
TDiagnostics *mDiagnostics;
std::vector<int> mLoopSymbolIds;
+
+ size_t mTotalPrivateVariablesSize;
};
} // namespace
@@ -223,6 +242,7 @@ bool ValidateTypeSizeLimitations(TIntermNode *root,
{
ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
root->traverse(&validate);
+ validate.validateTotalPrivateVariableSize();
return diagnostics->numErrors() == 0;
}
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index f4bd19baf3582c0b4a840d73a57ea6fc385159a6..1b265568fc8a87280cc192fbd573a8b11dfb29ec 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5271,11 +5271,12 @@ TEST_P(WebGLCompatibilityTest, ValidateArraySizes)
// fairly small array.
constexpr char kVSArrayOK[] =
R"(varying vec4 color;
-const int array_size = 1000;
+const int array_size = 500;
void main()
{
mat2 array[array_size];
- if (array[0][0][0] == 2.0)
+ mat2 array2[array_size];
+ if (array[0][0][0] + array2[0][0][0] == 2.0)
color = vec4(0.0, 1.0, 0.0, 1.0);
else
color = vec4(1.0, 0.0, 0.0, 1.0);
@@ -5353,6 +5354,103 @@ void main()
EXPECT_EQ(0u, program);
}
+// Reject attempts to allocate too much private memory.
+// This is an implementation-defined limit - crbug.com/1431761.
+TEST_P(WebGLCompatibilityTest, ValidateTotalPrivateSize)
+{
+ constexpr char kTooLargeGlobalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+vec4 array2[32769];
+
+void main()
+{
+ if (array[0].x + array[1].x == 0.)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32767];
+vec4 array2[32767];
+vec4 x, y, z;
+
+void main()
+{
+ if (array[0].x + array[1].x == x.w + y.w + z.w)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalAndLocalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+void main()
+{
+ vec4 array2[32769];
+ if (array[0].x + array[1].x == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ // Note: The call stack is not taken into account for the purposes of total memory calculation.
+ constexpr char kTooLargeGlobalAndLocalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+float f()
+{
+ vec4 array2[16384];
+ return array2[0].x;
+}
+
+float g()
+{
+ vec4 array3[16383];
+ return array3[0].x;
+}
+
+float h()
+{
+ vec4 value;
+ float value2
+ return value.x + value2;
+}
+
+void main()
+{
+ if (array[0].x + f() + g() + h() == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ GLuint program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory2);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
+ EXPECT_EQ(0u, program);
+}
+
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
// qualifiers.
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)

View File

@@ -133,6 +133,36 @@ m108-lts_further_simplify_webmediaplayermscompositor_lifetime.patch
cherry-pick-e79b89b47dac.patch
cherry-pick-06851790480e.patch
cherry-pick-aeec1ba5893d.patch
cherry-pick-0407102d19b9.patch
fix_crash_in_annotationagentimpl.patch
cherry-pick-bfd926be8178.patch
cherry-pick-9aa4c45f21b1.patch
m108-lts_do_not_register_browser_watcher_activity_report_with.patch
prevent_potential_integer_overflow_in_persistentmemoryallocator_1_2.patch
m108-lts_prevent_potential_integer_overflow_in.patch
cherry-pick-38de42d2bbc3.patch
cherry-pick-8731bd8a30f6.patch
cherry-pick-26bfa5807606.patch
cherry-pick-b5c9e5efe5dd.patch
cherry-pick-56bd20b295b4.patch
cherry-pick-1235110fce18.patch
cherry-pick-b041159d06ad.patch
cherry-pick-d6946b70b431.patch
cherry-pick-d9081493c4b2.patch
cherry-pick-2b30a50d0e62.patch
merge_m112_remove_the_second_weakptrfactory_from.patch
merge_m112_check_spdyproxyclientsocket_is_alive_after_write.patch
check_callback_availability_in.patch
cherry-pick-63686953dc22.patch
cherry-pick-f098ff0d1230.patch
cherry-pick-f58218891f8c.patch
wayland_ensure_dnd_buffer_size_is_a_multiple_of_scale.patch
m112_cherry_pick_libxml_cve_fix.patch
m112_fix_scopedobservation_uaf_in.patch
cherry-pick-ea1cd76358e0.patch
cherry-pick-48785f698b1c.patch
m108-lts_return_after_readycommitnavigation_call_in_commiterrorpage.patch
m114_merge_fix_a_crash_caused_by_calling_trace_event.patch
base_do_not_use_va_args_twice_in_asprintf.patch
cherry-pick-85beff6fd302.patch
m114_webcodecs_fix_crash_when_changing_temporal_layer_count_in_av1.patch

View File

@@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benoit Lize <lizeb@chromium.org>
Date: Fri, 9 Jun 2023 17:59:08 +0000
Subject: Do not use va_args twice in asprintf()
(cherry picked from commit 3cff0cb19a6d01cbdd9932f43dabaaeda9c0330a)
Bug: 1450536
Change-Id: Ib34d96935278869a63897f9a1c66afc98865d90f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4579347
Reviewed-by: Egor Pasko <pasko@chromium.org>
Commit-Queue: Benoit Lize <lizeb@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1151796}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4604070
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/branch-heads/5735@{#1224}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
index 621873126602463a09efca1bf1548ed10910d323..de2af6d7d54e254b9e7b8264b53d30a338fb13e8 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
+++ b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
@@ -123,13 +123,21 @@ SHIM_ALWAYS_EXPORT char* __wrap_getcwd(char* buffer, size_t size) {
SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
const char* fmt,
va_list va_args) {
+ // There are cases where we need to use the list of arguments twice, namely
+ // when the original buffer is too small. It is not allowed to walk the list
+ // twice, so make a copy for the second invocation of vsnprintf().
+ va_list va_args_copy;
+ va_copy(va_args_copy, va_args);
+
constexpr int kInitialSize = 128;
*strp = static_cast<char*>(
malloc(kInitialSize)); // Our malloc() doesn't return nullptr.
int actual_size = vsnprintf(*strp, kInitialSize, fmt, va_args);
- if (actual_size < 0)
+ if (actual_size < 0) {
+ va_end(va_args_copy);
return actual_size;
+ }
*strp =
static_cast<char*>(realloc(*strp, static_cast<size_t>(actual_size + 1)));
@@ -139,9 +147,14 @@ SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
//
// This is very lightly used in Chromium in practice, see crbug.com/116558 for
// details.
- if (actual_size >= kInitialSize)
- return vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt, va_args);
-
+ if (actual_size >= kInitialSize) {
+ int ret = vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt,
+ va_args_copy);
+ va_end(va_args_copy);
+ return ret;
+ }
+
+ va_end(va_args_copy);
return actual_size;
}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
index 6caf9d6ffe0db92602ac1e448f45da422e077c2c..57d36f722e1aa747cda3a808104cc108147552c1 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
+++ b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
@@ -706,6 +706,28 @@ TEST_F(AllocatorShimTest, InterceptVasprintf) {
// Should not crash.
}
+TEST_F(AllocatorShimTest, InterceptLongVasprintf) {
+ char* str = nullptr;
+ const char* lorem_ipsum =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. "
+ "Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, "
+ "ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula "
+ "massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci "
+ "nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit "
+ "amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat "
+ "in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero "
+ "pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo "
+ "in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue "
+ "blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus "
+ "et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed "
+ "pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales "
+ "hendrerit.";
+ int err = asprintf(&str, "%s", lorem_ipsum);
+ EXPECT_EQ(err, static_cast<int>(strlen(lorem_ipsum)));
+ EXPECT_TRUE(str);
+ free(str);
+}
+
#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
#endif // BUILDFLAG(IS_ANDROID)

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kenichi Ishibashi <bashi@chromium.org>
Date: Tue, 18 Apr 2023 05:58:29 +0000
Subject: Check callback availability in
SpdyProxyClientSocket::RunWriteCallback
OnClose() could consume `write_callback_` so it may not be available
when RunWriteCallback() is invoked.
Bug: 1428820
Change-Id: I9a5ade62d67f5bf15e12d0915d1ad6098657ffd4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4437791
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Reviewed-by: Adam Rice <ricea@chromium.org>
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1131689}
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
index d9b67febc27cc99e5b3383a372451345cec6daaa..bdcf24a1cb65f5df291bd91784d68aa9c05e7b0d 100644
--- a/net/spdy/spdy_proxy_client_socket.cc
+++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -278,10 +278,11 @@ int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
}
void SpdyProxyClientSocket::RunWriteCallback(int result) {
- CHECK(write_callback_);
-
base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr();
- std::move(write_callback_).Run(result);
+ // `write_callback_` might be consumed by OnClose().
+ if (write_callback_) {
+ std::move(write_callback_).Run(result);
+ }
if (!weak_ptr) {
// `this` was already destroyed while running `write_callback_`. Must
// return immediately without touching any field member.

View File

@@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@chromium.org>
Date: Tue, 14 Mar 2023 16:49:10 +0000
Subject: Convert known it != end() DCHECK failures to CHECK
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These have hit on DCHECK builds in the wild and precede erasing or
dereferencing an iterator that is UB.
This CL excludes DCHECK failures that precede non-DCHECK handling of the
it != end() failures. Those should probably be rewritten as CHECKs
but are less urgent and semi-orthogonal.
Known crashes (one per file) are:
crash/dc49e3cadab36d4c
crash/0ee3427d25937024
crash/b89303e84d123019
crash/cc35183b861a4992
(cherry picked from commit 1aec0b297900a7b59bd24314dff239f3c5697f45)
Bug: 1418734
Change-Id: I81ed7b45be33769e250c65c8bb7334a34be4380e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4288168
Commit-Queue: Peter Boström <pbos@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1109350}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4296138
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Peter Boström <pbos@chromium.org>
Cr-Commit-Position: refs/branch-heads/5359@{#1406}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/base/scoped_multi_source_observation.h b/base/scoped_multi_source_observation.h
index 07ea3edd71246f02fe0044b33129f13699ce43b2..cd368c23956078acd6d5694f7f16c106f6461b31 100644
--- a/base/scoped_multi_source_observation.h
+++ b/base/scoped_multi_source_observation.h
@@ -68,7 +68,7 @@ class ScopedMultiSourceObservation {
// Remove the object passed to the constructor as an observer from |source|.
void RemoveObservation(Source* source) {
auto it = base::ranges::find(sources_, source);
- DCHECK(it != sources_.end());
+ CHECK(it != sources_.end());
sources_.erase(it);
(source->*RemoveObsFn)(observer_);
}
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index 8a49e44647d8c6d35e7fa04dafbd32c06c153927..4ad050db8a3e590742501507d7777ba923ad3832 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -1379,8 +1379,8 @@ Iterator GpuImageDecodeCache::RemoveFromPersistentCache(Iterator it) {
}
auto entries_it = paint_image_entries_.find(it->second->paint_image_id);
- DCHECK(entries_it != paint_image_entries_.end());
- DCHECK_GT(entries_it->second.count, 0u);
+ CHECK(entries_it != paint_image_entries_.end());
+ CHECK_GT(entries_it->second.count, 0u);
// If this is the last entry for this image, remove its tracking.
--entries_it->second.count;
diff --git a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
index 4f4fbb6c8775e1019a6c2938812f5535737433a3..9e9181677fb676100ff2a20890e902f298b16644 100644
--- a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
+++ b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
@@ -117,7 +117,7 @@ void AnnotationAgentImpl::ScrollIntoView() const {
EphemeralRangeInFlatTree range = attached_range_->ToEphemeralRange();
- DCHECK(range.Nodes().begin() != range.Nodes().end());
+ CHECK(range.Nodes().begin() != range.Nodes().end());
Node& first_node = *range.Nodes().begin();
diff --git a/ui/base/interaction/element_tracker_mac.mm b/ui/base/interaction/element_tracker_mac.mm
index d3b8d98e499a074678d7e06efcc2146d92ae3eb4..b467aa234043ebc8537bb4576ce0eed713593597 100644
--- a/ui/base/interaction/element_tracker_mac.mm
+++ b/ui/base/interaction/element_tracker_mac.mm
@@ -50,7 +50,7 @@ void AddElement(ElementIdentifier identifier,
void ActivateElement(ElementIdentifier identifier) {
const auto it = elements_.find(identifier);
- DCHECK(it != elements_.end());
+ CHECK(it != elements_.end());
ui::ElementTracker::GetFrameworkDelegate()->NotifyElementActivated(
it->second.get());
}

View File

@@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Tue, 14 Mar 2023 21:15:46 +0000
Subject: Disable glShaderBinary in the passthrough cmd decoder.
This matches the behaviour of the validating command decoder. The client
does not use this function and it's not exposed to WebGL.
(cherry picked from commit 4a81311a62d853a43e002f45c6867f73c0accdab)
Bug: 1422594
Change-Id: I87c670e4e80b0078fddb9f089b7ac7777a6debfa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4324998
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1115379}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4335184
Cr-Commit-Position: refs/branch-heads/5481@{#1357}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 9b09ddfe074ebe2786c7bc341b84a5eb5b7b73c9..373dab1c379152c45878faa60a5648bf0bc662e7 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -2666,6 +2666,10 @@ error::Error GLES2DecoderPassthroughImpl::DoShaderBinary(GLsizei n,
GLenum binaryformat,
const void* binary,
GLsizei length) {
+#if 1 // No binary shader support.
+ InsertError(GL_INVALID_ENUM, "Invalid enum.");
+ return error::kNoError;
+#else
std::vector<GLuint> service_shaders(n, 0);
for (GLsizei i = 0; i < n; i++) {
service_shaders[i] = GetShaderServiceID(shaders[i], resources_);
@@ -2673,6 +2677,7 @@ error::Error GLES2DecoderPassthroughImpl::DoShaderBinary(GLsizei n,
api()->glShaderBinaryFn(n, service_shaders.data(), binaryformat, binary,
length);
return error::kNoError;
+#endif
}
error::Error GLES2DecoderPassthroughImpl::DoShaderSource(GLuint shader,

View File

@@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Date: Mon, 10 Apr 2023 05:32:06 +0000
Subject: Use ScriptState::Scope instead of setting HandleScope.
Since `GetEffectiveFunction` may call `Get` if the given v8 listener is
an object, we need to prepare `v8::Context::Scope` before calling it.
Blink already have a helper class to prepare the environment for the
script execution, which has already been used used in other
ServiceWorkerGlobalScope member functions. It is `ScriptState::Scope`
This CL also use it instead.
(cherry picked from commit 299385e09d41d5ce3abd434879b5f9b0a8880cd7)
Bug: 1429197
Change-Id: Idbcfdfa9c06160a18b57155a9540f72eed4ec0b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4387655
Commit-Queue: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Commit-Queue: Kouhei Ueno <kouhei@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1125148}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4411454
Reviewed-by: Shunya Shishido <sisidovski@chromium.org>
Cr-Commit-Position: refs/branch-heads/5615@{#1191}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc
index 5e1aeaa11cc99e9ac4c89be082e0b4254f6df000..0435c5a1850dd3ed16197bbc40c1e276e4613a60 100644
--- a/content/browser/service_worker/service_worker_version_browsertest.cc
+++ b/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -976,6 +976,18 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
version_->fetch_handler_type());
}
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
+ NonFunctionFetchHandlerWithHandleEventProperty) {
+ StartServerAndNavigateToSetup();
+ ASSERT_EQ(
+ Install("/service_worker/fetch_event_with_handle_event_property.js"),
+ blink::ServiceWorkerStatusCode::kOk);
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::EXISTS,
+ version_->fetch_handler_existence());
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerType::kNotSkippable,
+ version_->fetch_handler_type());
+}
+
// Check that fetch event handler added in the install event should result in a
// service worker that doesn't count as having a fetch event handler.
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
diff --git a/content/test/data/service_worker/fetch_event_with_handle_event_property.js b/content/test/data/service_worker/fetch_event_with_handle_event_property.js
new file mode 100644
index 0000000000000000000000000000000000000000..2fe6153af242a10162f7ecb8eaab93c17d840211
--- /dev/null
+++ b/content/test/data/service_worker/fetch_event_with_handle_event_property.js
@@ -0,0 +1,11 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+let obj = {};
+Object.defineProperty(obj, "handleEvent", {
+ get: () => {},
+ configurable: true,
+ enumerable: true,
+});
+self.addEventListener('fetch', obj);
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index c66d232a65535bf1c66d47c6d51bc56418e57f26..b3a9f691a0fabf14bf6f319173f400c31c664c12 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -2602,12 +2602,15 @@ ServiceWorkerGlobalScope::FetchHandlerType() {
if (!elv) {
return mojom::blink::ServiceWorkerFetchHandlerType::kNoHandler;
}
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope handle_scope(isolate);
+
+ ScriptState* script_state = ScriptController()->GetScriptState();
+ // Do not remove this, |scope| is needed by `GetEffectiveFunction`.
+ ScriptState::Scope scope(script_state);
+
// TODO(crbug.com/1349613): revisit the way to implement this.
// The following code returns kEmptyFetchHandler if all handlers are nop.
for (RegisteredEventListener& e : *elv) {
- EventTarget* et = EventTarget::Create(ScriptController()->GetScriptState());
+ EventTarget* et = EventTarget::Create(script_state);
v8::Local<v8::Value> v =
To<JSBasedEventListener>(e.Callback())->GetEffectiveFunction(*et);
if (!v->IsFunction() ||

View File

@@ -0,0 +1,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Arthur Sonzogni <arthursonzogni@chromium.org>
Date: Tue, 2 May 2023 09:40:37 +0000
Subject: Avoid buffer overflow read in HFSReadNextNonIgnorableCodePoint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Unicode codepoints goes beyond 0xFFFF.
It exists upper and lower case characters there: `𞤡 `vs `𞥃`.
The buffer overflow occurred when using the lookup table:
```
lower_case_table[codepoint >> 8]
```
Bug: 1425115
Fixed: 1425115
Change-Id: I679da02dbe570283a68176fbd3c0c620caa4f9ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4481260
Reviewed-by: Alexander Timin <altimin@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1138234}
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index a43c09317da96332584286fdb67284b2bedd753f..3a7cca6fad051816d6d018857c8039594c51ec65 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -775,7 +775,7 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
#elif BUILDFLAG(IS_APPLE)
// Mac OS X specific implementation of file string comparisons.
-// cf. http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties
+// cf. https://developer.apple.com/library/archive/technotes/tn/tn1150.html#UnicodeSubtleties
//
// "When using CreateTextEncoding to create a text encoding, you should set
// the TextEncodingBase to kTextEncodingUnicodeV2_0, set the
@@ -801,11 +801,12 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
// Ignored characters are mapped to zero.
//
// cf. downloadable file linked in
-// http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm
+// https://developer.apple.com/library/archive/technotes/tn/tn1150.html#Downloads
namespace {
-const UInt16 lower_case_table[] = {
+// clang-format off
+const UInt16 lower_case_table[11 * 256] = {
// High-byte indices ( == 0 iff no case mapping and no ignorables )
/* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
@@ -1191,11 +1192,12 @@ const UInt16 lower_case_table[] = {
/* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
};
+// clang-format on
-// Returns the next non-ignorable codepoint within string starting from the
-// position indicated by index, or zero if there are no more.
-// The passed-in index is automatically advanced as the characters in the input
-// HFS-decomposed UTF-8 strings are read.
+// Returns the next non-ignorable codepoint within `string` starting from the
+// position indicated by `index`, or zero if there are no more.
+// The passed-in `index` is automatically advanced as the characters in the
+// input HFS-decomposed UTF-8 strings are read.
inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
size_t length,
size_t* index) {
@@ -1206,12 +1208,16 @@ inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
CBU8_NEXT(reinterpret_cast<const uint8_t*>(string), *index, length,
codepoint);
DCHECK_GT(codepoint, 0);
- if (codepoint > 0) {
+
+ // Note: Here, there are no lower case conversion implemented in the
+ // Supplementary Multilingual Plane (codepoint > 0xFFFF).
+
+ if (codepoint > 0 && codepoint <= 0xFFFF) {
// Check if there is a subtable for this upper byte.
int lookup_offset = lower_case_table[codepoint >> 8];
if (lookup_offset != 0)
codepoint = lower_case_table[lookup_offset + (codepoint & 0x00FF)];
- // Note: codepoint1 may be again 0 at this point if the character was
+ // Note: `codepoint` may be again 0 at this point if the character was
// an ignorable.
}
}
diff --git a/base/files/file_path_unittest.cc b/base/files/file_path_unittest.cc
index b9b14c1ebb6a7046f6432531913fd72b045d6cb0..90457a001c2f0d5652ae1394c9d142bfd0003ca6 100644
--- a/base/files/file_path_unittest.cc
+++ b/base/files/file_path_unittest.cc
@@ -1188,6 +1188,13 @@ TEST_F(FilePathTest, CompareIgnoreCase) {
{{FPL("K\u0301U\u032DO\u0304\u0301N"), FPL("\u1E31\u1E77\u1E53n")}, 0},
{{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("\u1E30\u1E76\u1E52n")}, 0},
{{FPL("k\u0301u\u032Do\u0304\u0302n"), FPL("\u1E30\u1E76\u1E52n")}, 1},
+
+ // Codepoints > 0xFFFF
+ // Here, we compare the `Adlam Letter Shu` in its capital and small version.
+ {{FPL("\U0001E921"), FPL("\U0001E943")}, -1},
+ {{FPL("\U0001E943"), FPL("\U0001E921")}, 1},
+ {{FPL("\U0001E921"), FPL("\U0001E921")}, 0},
+ {{FPL("\U0001E943"), FPL("\U0001E943")}, 0},
#endif
};

View File

@@ -0,0 +1,130 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Sesek <rsesek@chromium.org>
Date: Mon, 27 Feb 2023 21:25:11 +0000
Subject: Update Crashpad to 3e8727238bae3c069bd71cfb3b2bbaa98b55f05b
3e8727238bae win: Only process up to EXCEPTION_MAXIMUM_PARAMETERS in an
EXCEPTION_RECORD
(cherry picked from commit d05bea76b7ce72d66507ebbe00caf5e45afd587a)
Fixed: 1412658
Change-Id: I7461602d1a18d44ea1a11ac19f1487fbdb92acf6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4285061
Commit-Queue: Robert Sesek <rsesek@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Auto-Submit: Robert Sesek <rsesek@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1108722}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4295200
Cr-Commit-Position: refs/branch-heads/5481@{#1298}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 29ad402c3558b7c75b68339e0f07ad004170fe76..2be0ee4d29e445b5531fc3fddcc3efa28ef968f1 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad
URL: https://crashpad.chromium.org/
Version: unknown
-Revision: 9f472e5a18d7611adaeb5df727b51102f35e109e
+Revision: 9f472e5a18d7611adaeb5df727b51102f35e109e with 3e8727238bae3c069bd71cfb3b2bbaa98b55f05b cherry-picked
License: Apache 2.0
License File: crashpad/LICENSE
Security Critical: yes
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
index 2a70c5c0cea234ee1d81262738d7c4e48736b78e..b8931444ac8b11044a6fa7ce2a5ccf34aa4409c8 100644
--- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
@@ -14,6 +14,8 @@
#include "snapshot/win/exception_snapshot_win.h"
+#include <algorithm>
+
#include "base/logging.h"
#include "snapshot/capture_memory.h"
#include "snapshot/memory_snapshot.h"
@@ -261,8 +263,12 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers(
exception_code_ = first_record.ExceptionCode;
exception_flags_ = first_record.ExceptionFlags;
exception_address_ = first_record.ExceptionAddress;
- for (DWORD i = 0; i < first_record.NumberParameters; ++i)
+
+ const DWORD number_parameters = std::min<DWORD>(
+ first_record.NumberParameters, EXCEPTION_MAXIMUM_PARAMETERS);
+ for (DWORD i = 0; i < number_parameters; ++i) {
codes_.push_back(first_record.ExceptionInformation[i]);
+ }
if (first_record.ExceptionRecord) {
// https://crashpad.chromium.org/bug/43
LOG(WARNING) << "dropping chained ExceptionRecord";
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
index dcdc3cf4d6f4c1298905e5fba6580e73fca014e0..aa78e5579319341c08a6866fb7ae1272d403d23c 100644
--- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
@@ -14,11 +14,14 @@
#include "snapshot/win/exception_snapshot_win.h"
+#include <windows.h>
+
#include <string>
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "gtest/gtest.h"
+#include "snapshot/win/exception_snapshot_win.h"
#include "snapshot/win/process_snapshot_win.h"
#include "test/errors.h"
#include "test/test_paths.h"
@@ -315,6 +318,48 @@ TEST(SimulateCrash, ChildDumpWithoutCrashingWOW64) {
}
#endif // ARCH_CPU_64_BITS
+TEST(ExceptionSnapshot, TooManyExceptionParameters) {
+ ProcessReaderWin process_reader;
+ ASSERT_TRUE(process_reader.Initialize(GetCurrentProcess(),
+ ProcessSuspensionState::kRunning));
+
+ // Construct a fake exception record and CPU context.
+ auto exception_record = std::make_unique<EXCEPTION_RECORD>();
+ exception_record->ExceptionCode = STATUS_FATAL_APP_EXIT;
+ exception_record->ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+ exception_record->ExceptionAddress = reinterpret_cast<PVOID>(0xFA15E);
+ // One more than is permitted in the struct.
+ exception_record->NumberParameters = EXCEPTION_MAXIMUM_PARAMETERS + 1;
+ for (int i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; ++i) {
+ exception_record->ExceptionInformation[i] = 1000 + i;
+ }
+
+ auto cpu_context = std::make_unique<internal::CPUContextUnion>();
+
+ auto exception_pointers = std::make_unique<EXCEPTION_POINTERS>();
+ exception_pointers->ExceptionRecord =
+ reinterpret_cast<PEXCEPTION_RECORD>(exception_record.get());
+ exception_pointers->ContextRecord =
+ reinterpret_cast<PCONTEXT>(cpu_context.get());
+
+ internal::ExceptionSnapshotWin snapshot;
+ ASSERT_TRUE(snapshot.Initialize(
+ &process_reader,
+ GetCurrentThreadId(),
+ reinterpret_cast<WinVMAddress>(exception_pointers.get()),
+ nullptr));
+
+ EXPECT_EQ(STATUS_FATAL_APP_EXIT, snapshot.Exception());
+ EXPECT_EQ(static_cast<uint32_t>(EXCEPTION_NONCONTINUABLE),
+ snapshot.ExceptionInfo());
+ EXPECT_EQ(0xFA15Eu, snapshot.ExceptionAddress());
+ EXPECT_EQ(static_cast<size_t>(EXCEPTION_MAXIMUM_PARAMETERS),
+ snapshot.Codes().size());
+ for (size_t i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; ++i) {
+ EXPECT_EQ(1000 + i, snapshot.Codes()[i]);
+ }
+}
+
} // namespace
} // namespace test
} // namespace crashpad

View File

@@ -0,0 +1,124 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Florian Leimgruber <fleimgruber@google.com>
Date: Thu, 6 Apr 2023 09:21:41 +0000
Subject: Add lock to AlternativeStateNameMap.
To prevent the class from accessing its localized_state_names_map_ and
localized_state_names_reverse_lookup_map_ members, a lock is added. It
locks all reads/write from the aforementioned members.
(cherry picked from commit dd848883aa0d7d88520846bbf6735eaae9f2b60e)
Bug: 1360571, 1414241, 1425951
Change-Id: Ic01b0cba3878748617863274deb04ec9e13645d4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4352658
Reviewed-by: Christoph Schwering <schwering@google.com>
Commit-Queue: Florian Leimgruber <fleimgruber@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#1119411}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4402262
Auto-Submit: Florian Leimgruber <fleimgruber@google.com>
Cr-Commit-Position: refs/branch-heads/5615@{#1147}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map.cc b/components/autofill/core/browser/geo/alternative_state_name_map.cc
index d217082a0faf23d2fd74dce8eec1043d83b5e509..ed22752c50f15e1f45e48b9ef561b0cb7134fba8 100644
--- a/components/autofill/core/browser/geo/alternative_state_name_map.cc
+++ b/components/autofill/core/browser/geo/alternative_state_name_map.cc
@@ -53,7 +53,6 @@ AlternativeStateNameMap::GetCanonicalStateName(
const CountryCode& country_code,
const StateName& state_name,
bool is_state_name_normalized) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
// Example:
// Entries in |localized_state_names_map_| are:
// ("DE", "Bavaria") -> {
@@ -73,6 +72,7 @@ AlternativeStateNameMap::GetCanonicalStateName(
if (!is_state_name_normalized)
normalized_state_name = NormalizeStateName(state_name);
+ base::AutoLock lock(lock_);
auto it = localized_state_names_reverse_lookup_map_.find(
{country_code, normalized_state_name});
if (it != localized_state_names_reverse_lookup_map_.end())
@@ -84,8 +84,6 @@ AlternativeStateNameMap::GetCanonicalStateName(
absl::optional<StateEntry> AlternativeStateNameMap::GetEntry(
const CountryCode& country_code,
const StateName& state_string_from_profile) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
-
StateName normalized_state_string_from_profile =
NormalizeStateName(state_string_from_profile);
absl::optional<CanonicalStateName> canonical_state_name =
@@ -93,6 +91,7 @@ absl::optional<StateEntry> AlternativeStateNameMap::GetEntry(
/*is_state_name_normalized=*/true);
if (canonical_state_name) {
+ base::AutoLock lock(lock_);
auto it = localized_state_names_map_.find(
{country_code, canonical_state_name.value()});
if (it != localized_state_names_map_.end())
@@ -108,8 +107,6 @@ void AlternativeStateNameMap::AddEntry(
const StateEntry& state_entry,
const std::vector<StateName>& normalized_alternative_state_names,
const CanonicalStateName& normalized_canonical_state_name) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
-
// Example:
// AddEntry("DE", "Bavaria", {
// "canonical_name": "Bayern",
@@ -126,12 +123,15 @@ void AlternativeStateNameMap::AddEntry(
// ("DE", "Bayern") -> "Bayern"
// ("DE", "BY") -> "Bayern"
// ("DE", "Bavaria") -> "Bayern"
- if (localized_state_names_map_.size() == kMaxMapSize ||
- GetCanonicalStateName(country_code, normalized_state_value_from_profile,
+ if (GetCanonicalStateName(country_code, normalized_state_value_from_profile,
/*is_state_name_normalized=*/true)) {
return;
}
+ base::AutoLock lock(lock_);
+ if (localized_state_names_map_.size() == kMaxMapSize) {
+ return;
+ }
localized_state_names_map_[{country_code, normalized_canonical_state_name}] =
state_entry;
for (const auto& alternative_name : normalized_alternative_state_names) {
@@ -141,12 +141,12 @@ void AlternativeStateNameMap::AddEntry(
}
bool AlternativeStateNameMap::IsLocalisedStateNamesMapEmpty() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
+ base::AutoLock lock(lock_);
return localized_state_names_map_.empty();
}
void AlternativeStateNameMap::ClearAlternativeStateNameMap() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
+ base::AutoLock lock(lock_);
localized_state_names_map_.clear();
localized_state_names_reverse_lookup_map_.clear();
}
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map.h b/components/autofill/core/browser/geo/alternative_state_name_map.h
index d20cdf8a02fff5d3c3ea91ef3aa67c6522804692..58dd754bfbf39fd24c82e6d46ccb566008a4cd73 100644
--- a/components/autofill/core/browser/geo/alternative_state_name_map.h
+++ b/components/autofill/core/browser/geo/alternative_state_name_map.h
@@ -9,7 +9,7 @@
#include "base/i18n/case_conversion.h"
#include "base/no_destructor.h"
-#include "base/sequence_checker.h"
+#include "base/synchronization/lock.h"
#include "base/types/strong_alias.h"
#include "components/autofill/core/browser/proto/states.pb.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@@ -177,7 +177,8 @@ class AlternativeStateNameMap {
CaseInsensitiveLessComparator>
localized_state_names_reverse_lookup_map_;
- SEQUENCE_CHECKER(alternative_state_name_map_sequence_checker_);
+ // TODO(crbug.com/1425951): Remove lock.
+ mutable base::Lock lock_;
};
} // namespace autofill

View File

@@ -0,0 +1,215 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kevin McNee <mcnee@chromium.org>
Date: Wed, 14 Jun 2023 01:10:19 +0000
Subject: M114: Don't recursively destroy guests when clearing unattached
guests
Don't recursively destroy guests when clearing unattached guests
When an embedder process is destroyed, we also destroy any unattached
guests associated with that process. This is currently done with a
single call to `owned_guests_.erase`. However, it's possible that two
unattached guests could have an opener relationship, which causes the
destruction of the opener guest to also destroy the other guest, during
the call to `erase`, which is unsafe.
We now separate the steps of erasing `owned_guests_` and destroying the
guests, to avoid this recursive guest destruction.
This also fixes the WaitForNumGuestsCreated test method to not
return prematurely.
(cherry picked from commit 6345e7871e8197af92f9c6158b06c6e197f87945)
Bug: 1450397
Change-Id: Ifef5ec9ff3a1e6952ff56ec279e29e8522625ac0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4589949
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Auto-Submit: Kevin McNee <mcnee@chromium.org>
Reviewed-by: James Maclean <wjmaclean@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1153396}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4611152
Commit-Queue: James Maclean <wjmaclean@chromium.org>
Cr-Commit-Position: refs/branch-heads/5735@{#1292}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 7159cf6af5cfd0ad5b9e5ba526043a4407a5399d..e43966f43f7ae551b3ea335a3f4222887071a75e 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -2731,6 +2731,22 @@ IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest,
EXPECT_TRUE(content::NavigateToURLFromRenderer(guest2, coop_url));
}
+// This test creates a situation where we have two unattached webviews which
+// have an opener relationship, and ensures that we can shutdown safely. See
+// https://crbug.com/1450397.
+IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, DestroyOpenerBeforeAttachment) {
+ TestHelper("testDestroyOpenerBeforeAttachment", "web_view/newwindow",
+ NEEDS_TEST_SERVER);
+ GetGuestViewManager()->WaitForNumGuestsCreated(2);
+
+ content::RenderProcessHost* embedder_rph =
+ GetEmbedderWebContents()->GetPrimaryMainFrame()->GetProcess();
+ content::RenderProcessHostWatcher kill_observer(
+ embedder_rph, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ EXPECT_TRUE(embedder_rph->Shutdown(content::RESULT_CODE_KILLED));
+ kill_observer.Wait();
+}
+
IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenuInspectElement) {
LoadAppWithGuest("web_view/context_menus/basic");
content::RenderFrameHost* guest_rfh = GetGuestRenderFrameHost();
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
index 900911f4963d23d74225868dce01326ba533f63a..4dd25d8849b0b13957ab7fa2912c0a158d3cd244 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
@@ -34,6 +34,9 @@ embedder.setUp_ = function(config) {
embedder.guestWithLinkURL = embedder.baseGuestURL +
'/extensions/platform_apps/web_view/newwindow' +
'/guest_with_link.html';
+ embedder.guestOpenOnLoadURL = embedder.baseGuestURL +
+ '/extensions/platform_apps/web_view/newwindow' +
+ '/guest_opener_open_on_load.html';
};
/** @private */
@@ -652,6 +655,24 @@ function testNewWindowDeferredAttachmentIndefinitely() {
embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
}
+// This is not a test in and of itself, but a means of creating a webview that
+// is left in an unattached state while its opener webview is also in an
+// unattached state, so that the C++ side can test it in that state.
+function testDestroyOpenerBeforeAttachment() {
+ embedder.test.succeed();
+
+ let webview = new WebView();
+ webview.src = embedder.guestOpenOnLoadURL;
+ document.body.appendChild(webview);
+
+ // By spinning forever here, we prevent `webview` from completing the
+ // attachment process. But since the guest is still created and it calls
+ // window.open, we have a situation where two unattached webviews have an
+ // opener relationship. The C++ side will test that we can shutdown safely in
+ // this case.
+ while (true) {}
+}
+
embedder.test.testList = {
'testNewWindowAttachAfterOpenerDestroyed':
testNewWindowAttachAfterOpenerDestroyed,
@@ -675,7 +696,9 @@ embedder.test.testList = {
testNewWindowWebViewNameTakesPrecedence,
'testNewWindowAndUpdateOpener': testNewWindowAndUpdateOpener,
'testNewWindowDeferredAttachmentIndefinitely':
- testNewWindowDeferredAttachmentIndefinitely
+ testNewWindowDeferredAttachmentIndefinitely,
+ 'testDestroyOpenerBeforeAttachment':
+ testDestroyOpenerBeforeAttachment
};
onload = function() {
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html
new file mode 100644
index 0000000000000000000000000000000000000000..e961feb3c6487066801adf414bf4a2746c50a3f6
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html
@@ -0,0 +1,13 @@
+<!--
+Copyright 2023 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<html>
+<body>
+<script>
+ // A guest that opens a new window on load.
+ window.open('guest.html');
+</script>
+</body>
+</html>
diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc
index 38f0f12e65009c660a6dba262617d48c10ff72ea..129443365f474b840e2ddc61868e89af2851a892 100644
--- a/components/guest_view/browser/guest_view_manager.cc
+++ b/components/guest_view/browser/guest_view_manager.cc
@@ -324,7 +324,20 @@ void GuestViewManager::RemoveGuest(int guest_instance_id) {
void GuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
embedders_observed_.erase(embedder_process_id);
+
+ // We can't just call std::multimap::erase here because destroying a guest
+ // could trigger the destruction of another guest which is also owned by
+ // `owned_guests_`. Recursively calling std::multimap::erase is unsafe (see
+ // https://crbug.com/1450397). So we take ownership of all of the guests that
+ // will be destroyed before erasing the entries from the map.
+ std::vector<std::unique_ptr<GuestViewBase>> guests_to_destroy;
+ const auto destroy_range = owned_guests_.equal_range(embedder_process_id);
+ for (auto it = destroy_range.first; it != destroy_range.second; ++it) {
+ guests_to_destroy.push_back(std::move(it->second));
+ }
owned_guests_.erase(embedder_process_id);
+ guests_to_destroy.clear();
+
CallViewDestructionCallbacks(embedder_process_id);
}
diff --git a/components/guest_view/browser/test_guest_view_manager.cc b/components/guest_view/browser/test_guest_view_manager.cc
index ab703db51b5ecd33e5fabd831ba121a2b5047d93..877f3eea7b440ed0a860253f85108c2442afee2e 100644
--- a/components/guest_view/browser/test_guest_view_manager.cc
+++ b/components/guest_view/browser/test_guest_view_manager.cc
@@ -36,7 +36,6 @@ TestGuestViewManager::TestGuestViewManager(
num_guests_created_(0),
expected_num_guests_created_(0),
num_views_garbage_collected_(0),
- waiting_for_guests_created_(false),
waiting_for_attach_(nullptr) {}
TestGuestViewManager::~TestGuestViewManager() = default;
@@ -127,14 +126,15 @@ GuestViewBase* TestGuestViewManager::WaitForNextGuestViewCreated() {
}
void TestGuestViewManager::WaitForNumGuestsCreated(size_t count) {
- if (count == num_guests_created_)
+ if (count == num_guests_created_) {
return;
+ }
- waiting_for_guests_created_ = true;
expected_num_guests_created_ = count;
num_created_run_loop_ = std::make_unique<base::RunLoop>();
num_created_run_loop_->Run();
+ num_created_run_loop_ = nullptr;
}
void TestGuestViewManager::WaitUntilAttached(GuestViewBase* guest_view) {
@@ -179,13 +179,11 @@ void TestGuestViewManager::AddGuest(int guest_instance_id,
created_run_loop_->Quit();
++num_guests_created_;
- if (!waiting_for_guests_created_ &&
- num_guests_created_ != expected_num_guests_created_) {
- return;
- }
- if (num_created_run_loop_)
+ if (num_created_run_loop_ &&
+ num_guests_created_ == expected_num_guests_created_) {
num_created_run_loop_->Quit();
+ }
}
void TestGuestViewManager::AttachGuest(int embedder_process_id,
diff --git a/components/guest_view/browser/test_guest_view_manager.h b/components/guest_view/browser/test_guest_view_manager.h
index 75015f30cfaf8f4bb427b360951f01c729f37308..557afdbdcde44062f13dd981aacd56b8c17d35d6 100644
--- a/components/guest_view/browser/test_guest_view_manager.h
+++ b/components/guest_view/browser/test_guest_view_manager.h
@@ -121,7 +121,6 @@ class TestGuestViewManager : public GuestViewManager {
size_t num_guests_created_;
size_t expected_num_guests_created_;
int num_views_garbage_collected_;
- bool waiting_for_guests_created_;
// Tracks the life time of the GuestView's main FrameTreeNode. The main FTN
// has the same lifesspan as the GuestView.

View File

@@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= <hbos@chromium.org>
Date: Tue, 14 Mar 2023 13:07:19 +0000
Subject: Shutdown RtpContributingSourceCache in Dispose().
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The cache is an off-heap object, but it is owned by an on-heap object
(RTCPeerConnection). Dispoing the owning object poisons memory owned by
it, but the cache may have in-flight tasks (cache doing ClearCache in a
delayed microtask). This CL adds a Shutdown() method to ensure the
cache isn't doing anything in the next microtask after disposal.
No reliable way to repro this has been found but the change should be
safe so hoping we can land without tests.
(cherry picked from commit 4d450ecd6ec7776c7505dcf7d2f04157ff3ba0eb)
Bug: 1413628
Change-Id: I479aace9859f4c10cd75d4aa5a34808b4726299d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4247023
Commit-Queue: Henrik Boström <hbos@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1105653}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4291513
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Henrik Boström <hbos@chromium.org>
Commit-Queue: Zakhar Voit <voit@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1404}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index e951bf3faa35a8634ae2c8b90446843d77e509a9..8aeb3497e7b036904a25e807bc2a6ca654cd3752 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -643,12 +643,18 @@ RTCPeerConnection::~RTCPeerConnection() {
}
void RTCPeerConnection::Dispose() {
- // Promptly clears the handler
- // so that content/ doesn't access it in a lazy sweeping phase.
- // Other references to the handler use a weak pointer, preventing access.
+ // Promptly clears the handler so that content doesn't access it in a lazy
+ // sweeping phase. Other references to the handler use a weak pointer,
+ // preventing access.
if (peer_handler_) {
peer_handler_.reset();
}
+ // Memory owned by RTCPeerConnection must not be touched after Dispose().
+ // Shut down the cache to cancel any in-flight tasks that may otherwise have
+ // used the cache.
+ if (rtp_contributing_source_cache_.has_value()) {
+ rtp_contributing_source_cache_.value().Shutdown();
+ }
}
ScriptPromise RTCPeerConnection::createOffer(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc
index 1f91cf9c128a1bb19fb0a63ea9d869a5c4e6d07d..5ad457fae9bc62a252ca94297fc4231a886b62b9 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc
@@ -102,6 +102,10 @@ RtpContributingSourceCache::RtpContributingSourceCache(
DCHECK(worker_thread_runner_);
}
+void RtpContributingSourceCache::Shutdown() {
+ weak_factory_.InvalidateWeakPtrs();
+}
+
HeapVector<Member<RTCRtpSynchronizationSource>>
RtpContributingSourceCache::getSynchronizationSources(
ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h
index 0d0ef9d1c59328e04217d9fca3f4e59b01ecca96..3a42751ab02f5680758c2b3ebce8a599f751c1ca 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h
@@ -43,6 +43,10 @@ class RtpContributingSourceCache {
RTCPeerConnection* pc,
scoped_refptr<base::SingleThreadTaskRunner> worker_thread_runner);
+ // When the owner of this object is Disposed(), this method must be called to
+ // cancel any in-flight tasks.
+ void Shutdown();
+
HeapVector<Member<RTCRtpSynchronizationSource>> getSynchronizationSources(
ScriptState* script_state,
ExceptionState& exception_state,

View File

@@ -0,0 +1,506 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matt Reynolds <mattreynolds@google.com>
Date: Wed, 8 Mar 2023 23:55:10 +0000
Subject: hid: Handle empty input reports
It's possible for a HID device to define its report descriptor such that
one or more reports have no data fields within the report. When receiving these reports, the report buffer should contain only the
report ID byte and no other data.
Ensure that we do not read past the end of the buffer when handling
zero-length input reports.
(cherry picked from commit c9d77da78bc66c135520ac77873d67b89cdcaee6)
Bug: 1419718
Change-Id: I51d32c20f6b16f0d2b0172e0a165469b6b79748c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4296562
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Matt Reynolds <mattreynolds@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1112009}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4320692
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Auto-Submit: Matt Reynolds <mattreynolds@chromium.org>
Cr-Commit-Position: refs/branch-heads/5481@{#1341}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/services/device/hid/hid_connection_impl.cc b/services/device/hid/hid_connection_impl.cc
index c413123e12191c413ae327732c9e95caa696e0ff..adfaa66b7601dce4a267e0113c3e14cdc9445f3e 100644
--- a/services/device/hid/hid_connection_impl.cc
+++ b/services/device/hid/hid_connection_impl.cc
@@ -54,11 +54,12 @@ void HidConnectionImpl::OnInputReport(
scoped_refptr<base::RefCountedBytes> buffer,
size_t size) {
DCHECK(client_);
- uint8_t report_id = buffer->data()[0];
- uint8_t* begin = &buffer->data()[1];
- uint8_t* end = buffer->data().data() + size;
- std::vector<uint8_t> data(begin, end);
- client_->OnInputReport(report_id, data);
+ DCHECK_GE(size, 1u);
+ std::vector<uint8_t> data;
+ if (size > 1) {
+ data = std::vector<uint8_t>(buffer->front() + 1, buffer->front() + size);
+ }
+ client_->OnInputReport(/*report_id=*/buffer->data()[0], data);
}
void HidConnectionImpl::Read(ReadCallback callback) {
diff --git a/services/device/hid/hid_connection_impl_unittest.cc b/services/device/hid/hid_connection_impl_unittest.cc
index 25f715fa5bd0584228b5d6dd7c27103ce5a61885..3d2e74aeaa6676af88719d56fd9c889a296eccd3 100644
--- a/services/device/hid/hid_connection_impl_unittest.cc
+++ b/services/device/hid/hid_connection_impl_unittest.cc
@@ -8,17 +8,28 @@
#include "base/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted_memory.h"
+#include "base/test/repeating_test_future.h"
+#include "base/test/test_future.h"
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/device/device_service_test_base.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace device {
namespace {
+using ::testing::ElementsAre;
+
+using ReadFuture = base::test::
+ TestFuture<bool, uint8_t, const absl::optional<std::vector<uint8_t>>&>;
+using WriteFuture = base::test::TestFuture<bool>;
+using GetFeatureFuture =
+ base::test::TestFuture<bool, const absl::optional<std::vector<uint8_t>>&>;
+
#if BUILDFLAG(IS_MAC)
const uint64_t kTestDeviceId = 123;
#elif BUILDFLAG(IS_WIN)
@@ -30,46 +41,37 @@ const char* kTestDeviceId = "123";
// The report ID to use for reports sent to or received from the test device.
const uint8_t kTestReportId = 0x42;
-// The max size of input and output reports for the test device. Feature reports
-// are not used in this test.
+// The max size of reports for the test device.
const uint64_t kMaxReportSizeBytes = 10;
-// A fake HidConnection implementation that allows the test to simulate an
-// input report.
-class FakeHidConnection : public HidConnection {
+// A mock HidConnection implementation that allows the test to simulate reports.
+class MockHidConnection : public HidConnection {
public:
- explicit FakeHidConnection(scoped_refptr<HidDeviceInfo> device)
+ explicit MockHidConnection(scoped_refptr<HidDeviceInfo> device)
: HidConnection(device,
/*allow_protected_reports=*/false,
/*allow_fido_reports=*/false) {}
- FakeHidConnection(const FakeHidConnection&) = delete;
- FakeHidConnection& operator=(const FakeHidConnection&) = delete;
+ MockHidConnection(const MockHidConnection&) = delete;
+ MockHidConnection& operator=(const MockHidConnection&) = delete;
// HidConnection implementation.
void PlatformClose() override {}
- void PlatformWrite(scoped_refptr<base::RefCountedBytes> buffer,
- WriteCallback callback) override {
- std::move(callback).Run(true);
- }
- void PlatformGetFeatureReport(uint8_t report_id,
- ReadCallback callback) override {
- NOTIMPLEMENTED();
- }
- void PlatformSendFeatureReport(scoped_refptr<base::RefCountedBytes> buffer,
- WriteCallback callback) override {
- NOTIMPLEMENTED();
- }
+ MOCK_METHOD2(PlatformWrite,
+ void(scoped_refptr<base::RefCountedBytes>, WriteCallback));
+ MOCK_METHOD2(PlatformGetFeatureReport, void(uint8_t, ReadCallback));
+ MOCK_METHOD2(PlatformSendFeatureReport,
+ void(scoped_refptr<base::RefCountedBytes>, WriteCallback));
void SimulateInputReport(scoped_refptr<base::RefCountedBytes> buffer) {
ProcessInputReport(buffer, buffer->size());
}
private:
- ~FakeHidConnection() override = default;
+ ~MockHidConnection() override = default;
};
-// A test implementation of HidConnectionClient that signals once an input
-// report has been received. The contents of the input report are saved.
+// An implementation of HidConnectionClient that enables the test to wait until
+// an input report is received.
class TestHidConnectionClient : public mojom::HidConnectionClient {
public:
TestHidConnectionClient() = default;
@@ -81,76 +83,18 @@ class TestHidConnectionClient : public mojom::HidConnectionClient {
receiver_.Bind(std::move(receiver));
}
- // mojom::HidConnectionClient implementation.
void OnInputReport(uint8_t report_id,
const std::vector<uint8_t>& buffer) override {
- report_id_ = report_id;
- buffer_ = buffer;
- run_loop_.Quit();
- }
-
- void WaitForInputReport() { run_loop_.Run(); }
-
- uint8_t report_id() { return report_id_; }
- const std::vector<uint8_t>& buffer() { return buffer_; }
-
- private:
- base::RunLoop run_loop_;
- mojo::Receiver<mojom::HidConnectionClient> receiver_{this};
- uint8_t report_id_ = 0;
- std::vector<uint8_t> buffer_;
-};
-
-// A utility for capturing the state returned by mojom::HidConnection I/O
-// callbacks.
-class TestIoCallback {
- public:
- TestIoCallback() = default;
- TestIoCallback(const TestIoCallback&) = delete;
- TestIoCallback& operator=(const TestIoCallback&) = delete;
- ~TestIoCallback() = default;
-
- void SetReadResult(bool result,
- uint8_t report_id,
- const absl::optional<std::vector<uint8_t>>& buffer) {
- result_ = result;
- report_id_ = report_id;
- has_buffer_ = buffer.has_value();
- if (has_buffer_)
- buffer_ = *buffer;
- run_loop_.Quit();
- }
-
- void SetWriteResult(bool result) {
- result_ = result;
- run_loop_.Quit();
- }
-
- bool WaitForResult() {
- run_loop_.Run();
- return result_;
- }
-
- mojom::HidConnection::ReadCallback GetReadCallback() {
- return base::BindOnce(&TestIoCallback::SetReadResult,
- base::Unretained(this));
+ future_.AddValue(report_id, buffer);
}
- mojom::HidConnection::WriteCallback GetWriteCallback() {
- return base::BindOnce(&TestIoCallback::SetWriteResult,
- base::Unretained(this));
+ std::pair<uint8_t, std::vector<uint8_t>> GetNextInputReport() {
+ return future_.Take();
}
- uint8_t report_id() { return report_id_; }
- bool has_buffer() { return has_buffer_; }
- const std::vector<uint8_t>& buffer() { return buffer_; }
-
private:
- base::RunLoop run_loop_;
- bool result_ = false;
- uint8_t report_id_ = 0;
- bool has_buffer_ = false;
- std::vector<uint8_t> buffer_;
+ mojo::Receiver<mojom::HidConnectionClient> receiver_{this};
+ base::test::RepeatingTestFuture<uint8_t, std::vector<uint8_t>> future_;
};
} // namespace
@@ -158,8 +102,8 @@ class TestIoCallback {
class HidConnectionImplTest : public DeviceServiceTestBase {
public:
HidConnectionImplTest() = default;
- HidConnectionImplTest(HidConnectionImplTest&) = delete;
- HidConnectionImplTest& operator=(HidConnectionImplTest&) = delete;
+ HidConnectionImplTest(const HidConnectionImplTest&) = delete;
+ HidConnectionImplTest& operator=(const HidConnectionImplTest&) = delete;
protected:
void SetUp() override {
@@ -167,18 +111,28 @@ class HidConnectionImplTest : public DeviceServiceTestBase {
base::RunLoop().RunUntilIdle();
}
- void CreateHidConnection(bool with_connection_client) {
+ void TearDown() override {
+ // HidConnectionImpl is self-owned and will self-destruct when its mojo pipe
+ // is disconnected. Allow disconnect handlers to run so HidConnectionImpl
+ // can self-destruct before the end of the test.
+ base::RunLoop().RunUntilIdle();
+ }
+
+ mojo::Remote<mojom::HidConnection> CreateHidConnection(
+ bool with_connection_client) {
mojo::PendingRemote<mojom::HidConnectionClient> hid_connection_client;
if (with_connection_client) {
connection_client_ = std::make_unique<TestHidConnectionClient>();
connection_client_->Bind(
hid_connection_client.InitWithNewPipeAndPassReceiver());
}
- fake_connection_ = new FakeHidConnection(CreateTestDevice());
- hid_connection_impl_ = new HidConnectionImpl(
- fake_connection_, hid_connection_.InitWithNewPipeAndPassReceiver(),
- std::move(hid_connection_client),
- /*watcher=*/mojo::NullRemote());
+ mock_connection_ = new MockHidConnection(CreateTestDevice());
+ mojo::Remote<mojom::HidConnection> hid_connection;
+ HidConnectionImpl::Create(mock_connection_,
+ hid_connection.BindNewPipeAndPassReceiver(),
+ std::move(hid_connection_client),
+ /*watcher=*/mojo::NullRemote());
+ return hid_connection;
}
scoped_refptr<HidDeviceInfo> CreateTestDevice() {
@@ -190,7 +144,7 @@ class HidConnectionImplTest : public DeviceServiceTestBase {
/*vendor_id=*/0x1234, /*product_id=*/0xabcd, "product name",
"serial number", mojom::HidBusType::kHIDBusTypeUSB,
std::move(collection), kMaxReportSizeBytes, kMaxReportSizeBytes,
- /*max_feature_report_size=*/0);
+ kMaxReportSizeBytes);
}
std::vector<uint8_t> CreateTestReportBuffer(uint8_t report_id, size_t size) {
@@ -201,37 +155,42 @@ class HidConnectionImplTest : public DeviceServiceTestBase {
return buffer;
}
- mojo::PendingRemote<mojom::HidConnection> hid_connection_;
- raw_ptr<HidConnectionImpl>
- hid_connection_impl_; // Owned by |hid_connection_|.
- scoped_refptr<FakeHidConnection> fake_connection_;
+ MockHidConnection& mock_connection() { return *mock_connection_.get(); }
+ TestHidConnectionClient& connection_client() { return *connection_client_; }
+
+ private:
+ scoped_refptr<MockHidConnection> mock_connection_;
std::unique_ptr<TestHidConnectionClient> connection_client_;
};
TEST_F(HidConnectionImplTest, ReadWrite) {
- CreateHidConnection(/*with_connection_client=*/false);
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
const size_t kTestBufferSize = kMaxReportSizeBytes;
std::vector<uint8_t> buffer_vec =
CreateTestReportBuffer(kTestReportId, kTestBufferSize);
// Simulate an output report (host to device).
- TestIoCallback write_callback;
- hid_connection_impl_->Write(kTestReportId, buffer_vec,
- write_callback.GetWriteCallback());
- ASSERT_TRUE(write_callback.WaitForResult());
+ EXPECT_CALL(mock_connection(), PlatformWrite)
+ .WillOnce([](scoped_refptr<base::RefCountedBytes> buffer,
+ HidConnectionImpl::WriteCallback callback) {
+ std::move(callback).Run(/*success=*/true);
+ });
+ WriteFuture write_future;
+ hid_connection->Write(kTestReportId, buffer_vec, write_future.GetCallback());
+ EXPECT_TRUE(write_future.Get());
// Simulate an input report (device to host).
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(buffer_vec);
ASSERT_EQ(buffer->size(), kTestBufferSize);
- fake_connection_->SimulateInputReport(buffer);
+ mock_connection().SimulateInputReport(buffer);
// Simulate reading the input report.
- TestIoCallback read_callback;
- hid_connection_impl_->Read(read_callback.GetReadCallback());
- ASSERT_TRUE(read_callback.WaitForResult());
- EXPECT_EQ(read_callback.report_id(), kTestReportId);
- ASSERT_TRUE(read_callback.has_buffer());
- const auto& read_buffer = read_callback.buffer();
+ ReadFuture read_future;
+ hid_connection->Read(read_future.GetCallback());
+ EXPECT_TRUE(read_future.Get<0>());
+ EXPECT_EQ(read_future.Get<1>(), kTestReportId);
+ ASSERT_TRUE(read_future.Get<2>().has_value());
+ const auto& read_buffer = read_future.Get<2>().value();
ASSERT_EQ(read_buffer.size(), kTestBufferSize - 1);
for (size_t i = 1; i < kTestBufferSize; ++i) {
EXPECT_EQ(read_buffer[i - 1], buffer_vec[i])
@@ -240,26 +199,29 @@ TEST_F(HidConnectionImplTest, ReadWrite) {
}
TEST_F(HidConnectionImplTest, ReadWriteWithConnectionClient) {
- CreateHidConnection(/*with_connection_client=*/true);
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/true);
const size_t kTestBufferSize = kMaxReportSizeBytes;
std::vector<uint8_t> buffer_vec =
CreateTestReportBuffer(kTestReportId, kTestBufferSize);
// Simulate an output report (host to device).
- TestIoCallback write_callback;
- hid_connection_impl_->Write(kTestReportId, buffer_vec,
- write_callback.GetWriteCallback());
- ASSERT_TRUE(write_callback.WaitForResult());
+ EXPECT_CALL(mock_connection(), PlatformWrite)
+ .WillOnce([](scoped_refptr<base::RefCountedBytes> buffer,
+ HidConnectionImpl::WriteCallback callback) {
+ std::move(callback).Run(/*success=*/true);
+ });
+ WriteFuture write_future;
+ hid_connection->Write(kTestReportId, buffer_vec, write_future.GetCallback());
+ EXPECT_TRUE(write_future.Get());
// Simulate an input report (device to host).
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(buffer_vec);
ASSERT_EQ(buffer->size(), kTestBufferSize);
- fake_connection_->SimulateInputReport(buffer);
- connection_client_->WaitForInputReport();
+ mock_connection().SimulateInputReport(buffer);
+ auto [report_id, in_buffer] = connection_client().GetNextInputReport();
// The connection client should have been notified.
- EXPECT_EQ(connection_client_->report_id(), kTestReportId);
- const std::vector<uint8_t>& in_buffer = connection_client_->buffer();
+ EXPECT_EQ(report_id, kTestReportId);
ASSERT_EQ(in_buffer.size(), kTestBufferSize - 1);
for (size_t i = 1; i < kTestBufferSize; ++i) {
EXPECT_EQ(in_buffer[i - 1], buffer_vec[i])
@@ -268,7 +230,7 @@ TEST_F(HidConnectionImplTest, ReadWriteWithConnectionClient) {
}
TEST_F(HidConnectionImplTest, DestroyWithPendingInputReport) {
- CreateHidConnection(/*with_connection_client=*/false);
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
const size_t kTestBufferSize = kMaxReportSizeBytes;
std::vector<uint8_t> buffer_vec =
CreateTestReportBuffer(kTestReportId, kTestBufferSize);
@@ -276,21 +238,20 @@ TEST_F(HidConnectionImplTest, DestroyWithPendingInputReport) {
// Simulate an input report (device to host).
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(buffer_vec);
ASSERT_EQ(buffer->size(), kTestBufferSize);
- fake_connection_->SimulateInputReport(buffer);
+ mock_connection().SimulateInputReport(buffer);
// Destroy the connection without reading the report.
- hid_connection_.reset();
+ hid_connection.reset();
}
TEST_F(HidConnectionImplTest, DestroyWithPendingRead) {
- CreateHidConnection(/*with_connection_client=*/false);
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
// Simulate reading an input report.
- TestIoCallback read_callback;
- hid_connection_impl_->Read(read_callback.GetReadCallback());
+ hid_connection->Read(base::DoNothing());
// Destroy the connection without receiving an input report.
- hid_connection_.reset();
+ hid_connection.reset();
}
TEST_F(HidConnectionImplTest, WatcherClosedWhenHidConnectionClosed) {
@@ -301,7 +262,7 @@ TEST_F(HidConnectionImplTest, WatcherClosedWhenHidConnectionClosed) {
mojo::Remote<mojom::HidConnection> hid_connection;
HidConnectionImpl::Create(
- base::MakeRefCounted<FakeHidConnection>(CreateTestDevice()),
+ base::MakeRefCounted<MockHidConnection>(CreateTestDevice()),
hid_connection.BindNewPipeAndPassReceiver(),
/*connection_client=*/mojo::NullRemote(), std::move(watcher));
@@ -326,7 +287,7 @@ TEST_F(HidConnectionImplTest, HidConnectionClosedWhenWatcherClosed) {
mojo::Remote<mojom::HidConnection> hid_connection;
HidConnectionImpl::Create(
- base::MakeRefCounted<FakeHidConnection>(CreateTestDevice()),
+ base::MakeRefCounted<MockHidConnection>(CreateTestDevice()),
hid_connection.BindNewPipeAndPassReceiver(),
/*connection_client=*/mojo::NullRemote(), std::move(watcher));
@@ -344,4 +305,74 @@ TEST_F(HidConnectionImplTest, HidConnectionClosedWhenWatcherClosed) {
EXPECT_FALSE(hid_connection.is_connected());
}
+TEST_F(HidConnectionImplTest, ReadZeroLengthInputReport) {
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
+ mock_connection().SimulateInputReport(
+ base::MakeRefCounted<base::RefCountedBytes>(
+ CreateTestReportBuffer(kTestReportId, /*size=*/1u)));
+ ReadFuture read_future;
+ hid_connection->Read(read_future.GetCallback());
+ EXPECT_TRUE(read_future.Get<0>());
+ EXPECT_EQ(read_future.Get<1>(), kTestReportId);
+ ASSERT_TRUE(read_future.Get<2>().has_value());
+ EXPECT_EQ(read_future.Get<2>().value().size(), 0u);
+}
+
+TEST_F(HidConnectionImplTest, ReadZeroLengthInputReportWithClient) {
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/true);
+ mock_connection().SimulateInputReport(
+ base::MakeRefCounted<base::RefCountedBytes>(
+ CreateTestReportBuffer(kTestReportId, /*size=*/1u)));
+ auto [report_id, in_buffer] = connection_client().GetNextInputReport();
+ EXPECT_EQ(report_id, kTestReportId);
+ EXPECT_EQ(in_buffer.size(), 0u);
+}
+
+TEST_F(HidConnectionImplTest, WriteZeroLengthOutputReport) {
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
+ EXPECT_CALL(mock_connection(), PlatformWrite)
+ .WillOnce([](scoped_refptr<base::RefCountedBytes> buffer,
+ HidConnectionImpl::WriteCallback callback) {
+ std::move(callback).Run(/*success=*/true);
+ });
+ WriteFuture write_future;
+ hid_connection->Write(kTestReportId, /*buffer=*/{},
+ write_future.GetCallback());
+ EXPECT_TRUE(write_future.Get());
+}
+
+TEST_F(HidConnectionImplTest, ReadZeroLengthFeatureReport) {
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
+ EXPECT_CALL(mock_connection(), PlatformGetFeatureReport)
+ .WillOnce([](uint8_t report_id, HidConnection::ReadCallback callback) {
+ std::move(callback).Run(/*success=*/true,
+ base::MakeRefCounted<base::RefCountedBytes>(
+ std::vector<uint8_t>{report_id}),
+ /*size=*/1u);
+ });
+ GetFeatureFuture get_feature_future;
+ hid_connection->GetFeatureReport(kTestReportId,
+ get_feature_future.GetCallback());
+ EXPECT_TRUE(get_feature_future.Get<0>());
+ ASSERT_TRUE(get_feature_future.Get<1>().has_value());
+ EXPECT_EQ(get_feature_future.Get<1>().value().size(), 1u);
+}
+
+TEST_F(HidConnectionImplTest, WriteZeroLengthFeatureReport) {
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
+ scoped_refptr<base::RefCountedBytes> feature_buffer;
+ EXPECT_CALL(mock_connection(), PlatformSendFeatureReport)
+ .WillOnce([&feature_buffer](scoped_refptr<base::RefCountedBytes> buffer,
+ HidConnectionImpl::WriteCallback callback) {
+ feature_buffer = buffer;
+ std::move(callback).Run(/*success=*/true);
+ });
+ WriteFuture write_future;
+ hid_connection->SendFeatureReport(kTestReportId, /*buffer=*/{},
+ write_future.GetCallback());
+ EXPECT_TRUE(write_future.Get());
+ ASSERT_TRUE(feature_buffer);
+ EXPECT_THAT(feature_buffer->data(), ElementsAre(kTestReportId));
+}
+
} // namespace device

View File

@@ -0,0 +1,257 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Wed, 15 Mar 2023 22:55:57 +0000
Subject: Merge M110: "Improve checks for VideoFrame layouts."
Adds a `VideoFrameLayout::IsValidForSize(size)` method which clients can
use to verify a VideoFrameLayout for their purpose. Updates a few call
sites to use the new verifier and adds tests.
(cherry picked from commit 17f73200c066158330542c19d521c517586533a2)
Fixed: 1421268
Change-Id: I51049ada6119eddb31cdd9b7edfe77ee65b1da7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4307674
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Commit-Queue: Dominick Ng <dominickn@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1116233}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4342492
Cr-Commit-Position: refs/branch-heads/5481@{#1361}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 4aa077a567840545b59645ee5ae84194517226b4..4ec81d5c1fc9b26559914b56f48f3eea1fca6bad 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -427,20 +427,9 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDataWithLayout(
StorageType storage_type = STORAGE_UNOWNED_MEMORY;
if (!IsValidConfig(layout.format(), storage_type, layout.coded_size(),
- visible_rect, natural_size)) {
- DLOG(ERROR) << __func__ << " Invalid config."
- << ConfigToString(layout.format(), storage_type,
- layout.coded_size(), visible_rect,
- natural_size);
- return nullptr;
- }
-
- const auto& last_plane = layout.planes()[layout.planes().size() - 1];
- const size_t required_size = last_plane.offset + last_plane.size;
- if (data_size < required_size) {
- DLOG(ERROR) << __func__ << " Provided data size is too small. Provided "
- << data_size << " bytes, but " << required_size
- << " bytes are required."
+ visible_rect, natural_size) ||
+ !layout.FitsInContiguousBufferOfSize(data_size)) {
+ DLOG(ERROR) << "Invalid config: "
<< ConfigToString(layout.format(), storage_type,
layout.coded_size(), visible_rect,
natural_size);
diff --git a/media/base/video_frame_layout.cc b/media/base/video_frame_layout.cc
index b3307c302bfd678caf3c90c639d32659dd2cad21..1426adb193d92c4aeb658321a6d40cdaa34461ad 100644
--- a/media/base/video_frame_layout.cc
+++ b/media/base/video_frame_layout.cc
@@ -9,6 +9,7 @@
#include <sstream>
#include "base/notreached.h"
+#include "base/numerics/checked_math.h"
namespace media {
@@ -173,6 +174,34 @@ bool VideoFrameLayout::operator!=(const VideoFrameLayout& rhs) const {
return !(*this == rhs);
}
+bool VideoFrameLayout::FitsInContiguousBufferOfSize(size_t data_size) const {
+ if (is_multi_planar_) {
+ return false;
+ }
+
+ base::CheckedNumeric<size_t> required_size = 0;
+ for (const auto& plane : planes_) {
+ if (plane.offset > data_size || plane.size > data_size) {
+ return false;
+ }
+
+ // No individual plane should have a size + offset > data_size.
+ base::CheckedNumeric<size_t> plane_end = plane.size;
+ plane_end += plane.offset;
+ if (!plane_end.IsValid() || plane_end.ValueOrDie() > data_size) {
+ return false;
+ }
+
+ required_size += plane.size;
+ }
+
+ if (!required_size.IsValid() || required_size.ValueOrDie() > data_size) {
+ return false;
+ }
+
+ return true;
+}
+
std::ostream& operator<<(std::ostream& ostream,
const VideoFrameLayout& layout) {
ostream << "VideoFrameLayout(format: " << layout.format()
diff --git a/media/base/video_frame_layout.h b/media/base/video_frame_layout.h
index d899c15d2d3f31bfac022d2900b62a53eccc1665..ae68bcfe5ab3669932344a6489fce76d8d9ccefa 100644
--- a/media/base/video_frame_layout.h
+++ b/media/base/video_frame_layout.h
@@ -112,6 +112,13 @@ class MEDIA_EXPORT VideoFrameLayout {
// Return the modifier of buffers.
uint64_t modifier() const { return modifier_; }
+ // Any constructible layout is valid in and of itself, it can only be invalid
+ // if the backing memory is too small to contain it.
+ //
+ // Returns true if this VideoFrameLayout can fit in a contiguous buffer of
+ // size `data_size` -- always false for multi-planar layouts.
+ bool FitsInContiguousBufferOfSize(size_t data_size) const;
+
private:
VideoFrameLayout(VideoPixelFormat format,
const gfx::Size& coded_size,
diff --git a/media/base/video_frame_layout_unittest.cc b/media/base/video_frame_layout_unittest.cc
index 71ef5d11d75de5693aa255b5d2400301ad3488c4..c11136eaee78b2cd35154d1a9cc10ec19835ac88 100644
--- a/media/base/video_frame_layout_unittest.cc
+++ b/media/base/video_frame_layout_unittest.cc
@@ -308,4 +308,50 @@ TEST(VideoFrameLayout, EqualOperator) {
EXPECT_NE(*layout, *different_layout);
}
+TEST(VideoFrameLayout, FitsInContiguousBufferOfSize) {
+ auto coded_size = gfx::Size(320, 180);
+
+ std::vector<int32_t> strides = {384, 192, 192};
+ std::vector<size_t> offsets = {0, 200, 300};
+ std::vector<size_t> sizes = {200, 100, 100};
+ std::vector<ColorPlaneLayout> planes(strides.size());
+ for (size_t i = 0; i < strides.size(); i++) {
+ planes[i].stride = strides[i];
+ planes[i].offset = offsets[i];
+ planes[i].size = sizes[i];
+ }
+
+ auto layout =
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
+ ASSERT_TRUE(layout.has_value());
+
+ EXPECT_TRUE(
+ layout->FitsInContiguousBufferOfSize(sizes[0] + sizes[1] + sizes[2]));
+
+ // Validate single plane size exceeds data size.
+ EXPECT_FALSE(layout->FitsInContiguousBufferOfSize(1));
+
+ // Validate sum of planes exceeds data size.
+ EXPECT_FALSE(layout->FitsInContiguousBufferOfSize(sizes[0] + sizes[1]));
+
+ // Validate offset exceeds plane size.
+ planes[2].offset = 301;
+ layout =
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
+ ASSERT_TRUE(layout.has_value());
+ EXPECT_TRUE(
+ layout->FitsInContiguousBufferOfSize(sizes[0] + sizes[1] + sizes[2] + 1));
+ EXPECT_FALSE(layout->FitsInContiguousBufferOfSize(sizes[0]));
+
+ // Validate overflow.
+ planes[0].offset = 0;
+ planes[0].size = planes[1].size = planes[2].size =
+ std::numeric_limits<size_t>::max() / 2;
+ layout =
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
+ ASSERT_TRUE(layout.has_value());
+ EXPECT_FALSE(
+ layout->FitsInContiguousBufferOfSize(std::numeric_limits<size_t>::max()));
+}
+
} // namespace media
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc
index 2fb254e8315b57cad3ac743d7ecf4f7c11371823..9e2cd0878362ff4b6315338cc1a39816ffadf49c 100644
--- a/media/base/video_frame_unittest.cc
+++ b/media/base/video_frame_unittest.cc
@@ -770,6 +770,46 @@ TEST(VideoFrame, AllocationSize_OddSize) {
}
}
+TEST(VideoFrame, WrapExternalDataWithInvalidLayout) {
+ auto coded_size = gfx::Size(320, 180);
+
+ std::vector<int32_t> strides = {384, 192, 192};
+ std::vector<size_t> offsets = {0, 200, 300};
+ std::vector<size_t> sizes = {200, 100, 100};
+ std::vector<ColorPlaneLayout> planes(strides.size());
+ for (size_t i = 0; i < strides.size(); i++) {
+ planes[i].stride = strides[i];
+ planes[i].offset = offsets[i];
+ planes[i].size = sizes[i];
+ }
+
+ auto layout =
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
+ ASSERT_TRUE(layout.has_value());
+
+ // Validate single plane size exceeds data size.
+ uint8_t data = 0;
+ auto frame = VideoFrame::WrapExternalDataWithLayout(
+ *layout, gfx::Rect(coded_size), coded_size, &data, sizeof(data),
+ base::TimeDelta());
+ ASSERT_FALSE(frame);
+
+ // Validate sum of planes exceeds data size.
+ frame = VideoFrame::WrapExternalDataWithLayout(
+ *layout, gfx::Rect(coded_size), coded_size, &data, sizes[0] + sizes[1],
+ base::TimeDelta());
+ ASSERT_FALSE(frame);
+
+ // Validate offset exceeds plane size.
+ planes[0].offset = 201;
+ layout =
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
+ frame = VideoFrame::WrapExternalDataWithLayout(*layout, gfx::Rect(coded_size),
+ coded_size, &data, sizes[0],
+ base::TimeDelta());
+ ASSERT_FALSE(frame);
+}
+
TEST(VideoFrameMetadata, MergeMetadata) {
VideoFrameMetadata reference_metadata = GetFullVideoFrameMetadata();
VideoFrameMetadata full_metadata = reference_metadata;
diff --git a/media/mojo/mojom/video_frame_mojom_traits.cc b/media/mojo/mojom/video_frame_mojom_traits.cc
index cdc4498f52873a6ba68271e4b373c5ace27f43c9..3a07ab5e7e877c9230df7f1a3bcd0df51a8940b6 100644
--- a/media/mojo/mojom/video_frame_mojom_traits.cc
+++ b/media/mojo/mojom/video_frame_mojom_traits.cc
@@ -231,14 +231,17 @@ bool StructTraits<media::mojom::VideoFrameDataView,
auto layout = media::VideoFrameLayout::CreateWithPlanes(format, coded_size,
std::move(planes));
- if (!layout) {
+ if (!layout || !layout->FitsInContiguousBufferOfSize(mapping.size())) {
DLOG(ERROR) << "Invalid layout";
return false;
}
+
frame = media::VideoFrame::WrapExternalYuvDataWithLayout(
*layout, visible_rect, natural_size, addr[0], addr[1], addr[2],
timestamp);
- frame->BackWithOwnedSharedMemory(std::move(region), std::move(mapping));
+ if (frame) {
+ frame->BackWithOwnedSharedMemory(std::move(region), std::move(mapping));
+ }
} else if (data.is_gpu_memory_buffer_data()) {
media::mojom::GpuMemoryBufferVideoFrameDataDataView gpu_memory_buffer_data;
data.GetGpuMemoryBufferDataDataView(&gpu_memory_buffer_data);
@@ -313,8 +316,9 @@ bool StructTraits<media::mojom::VideoFrameDataView,
return false;
}
- if (!frame)
+ if (!frame) {
return false;
+ }
media::VideoFrameMetadata metadata;
if (!input.ReadMetadata(&metadata))

View File

@@ -0,0 +1,134 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Thu, 23 Feb 2023 23:29:10 +0000
Subject: webcodecs: Fix VP9 p2 encoding of NV12 frames
(cherry picked from commit 503831d1bdfdbe20c096f04cefc2231efd9ca4c0)
Bug: 1412991
Change-Id: I2e596f65170c1fc98c122bfb0ecff4b241feee15
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250421
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1105528}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4288113
Cr-Commit-Position: refs/branch-heads/5481@{#1271}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/media/video/BUILD.gn b/media/video/BUILD.gn
index ce155164c821ddf60f73f7b0af0dce6e3d399af4..da517ef08a4cd1094f8e1660dfb5e4b7d847c979 100644
--- a/media/video/BUILD.gn
+++ b/media/video/BUILD.gn
@@ -169,6 +169,7 @@ source_set("unit_tests") {
"//media:test_support",
"//testing/gmock",
"//testing/gtest",
+ "//third_party/libvpx:libvpx",
"//third_party/libyuv:libyuv",
"//ui/gfx",
]
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc
index 2059f4e076ff9fa1720683ac5dfb90312df2183e..318c743bddcf9bec3a994f125ea329d45f8c4376 100644
--- a/media/video/software_video_encoder_test.cc
+++ b/media/video/software_video_encoder_test.cc
@@ -40,6 +40,8 @@
#if BUILDFLAG(ENABLE_LIBVPX)
#include "media/filters/vpx_video_decoder.h"
#include "media/video/vpx_video_encoder.h"
+#include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
+#include "third_party/libvpx/source/libvpx/vpx/vpx_codec.h"
#endif
#if BUILDFLAG(ENABLE_LIBAOM)
@@ -74,6 +76,9 @@ class SoftwareVideoEncoderTest
pixel_format_ = args.pixel_format;
codec_ = args.codec;
encoder_ = CreateEncoder(codec_);
+ if (!encoder_) {
+ GTEST_SKIP() << "Encoder is not supported on the platform";
+ }
}
void TearDown() override {
@@ -200,6 +205,12 @@ class SoftwareVideoEncoderTest
case media::VideoCodec::kVP8:
case media::VideoCodec::kVP9:
#if BUILDFLAG(ENABLE_LIBVPX)
+ if (profile_ == VP9PROFILE_PROFILE2) {
+ vpx_codec_caps_t codec_caps = vpx_codec_get_caps(vpx_codec_vp9_cx());
+ if ((codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) == 0) {
+ return nullptr;
+ }
+ }
return std::make_unique<media::VpxVideoEncoder>();
#else
return nullptr;
@@ -303,6 +314,11 @@ class SoftwareVideoEncoderTest
return diff_cnt;
}
+ VideoPixelFormat GetExpectedOutputPixelFormat(VideoCodecProfile profile) {
+ return profile == VP9PROFILE_PROFILE2 ? PIXEL_FORMAT_YUV420P10
+ : PIXEL_FORMAT_I420;
+ }
+
protected:
VideoCodec codec_;
VideoCodecProfile profile_;
@@ -488,7 +504,7 @@ TEST_P(SoftwareVideoEncoderTest, EncodeAndDecode) {
EXPECT_EQ(decoded_frame->timestamp(), original_frame->timestamp());
EXPECT_EQ(decoded_frame->visible_rect().size(),
original_frame->visible_rect().size());
- EXPECT_EQ(decoded_frame->format(), PIXEL_FORMAT_I420);
+ EXPECT_EQ(decoded_frame->format(), GetExpectedOutputPixelFormat(profile_));
if (decoded_frame->format() == original_frame->format()) {
EXPECT_LE(CountDifferentPixels(*decoded_frame, *original_frame),
original_frame->visible_rect().width());
@@ -890,6 +906,9 @@ SwVideoTestParams kVpxParams[] = {
{VideoCodec::kVP9, VP9PROFILE_PROFILE0, PIXEL_FORMAT_I420},
{VideoCodec::kVP9, VP9PROFILE_PROFILE0, PIXEL_FORMAT_NV12},
{VideoCodec::kVP9, VP9PROFILE_PROFILE0, PIXEL_FORMAT_XRGB},
+ {VideoCodec::kVP9, VP9PROFILE_PROFILE2, PIXEL_FORMAT_I420},
+ {VideoCodec::kVP9, VP9PROFILE_PROFILE2, PIXEL_FORMAT_NV12},
+ {VideoCodec::kVP9, VP9PROFILE_PROFILE2, PIXEL_FORMAT_XRGB},
{VideoCodec::kVP8, VP8PROFILE_ANY, PIXEL_FORMAT_I420},
{VideoCodec::kVP8, VP8PROFILE_ANY, PIXEL_FORMAT_XRGB}};
diff --git a/media/video/vpx_video_encoder.cc b/media/video/vpx_video_encoder.cc
index 7787b765899bc57395fea1a06d5c9c5a925b8910..c4ad642e453c9582b9ada11ad99c6b1c969b27b5 100644
--- a/media/video/vpx_video_encoder.cc
+++ b/media/video/vpx_video_encoder.cc
@@ -427,12 +427,20 @@ void VpxVideoEncoder::Encode(scoped_refptr<VideoFrame> frame,
}
}
- const bool is_yuv = IsYuvPlanar(frame->format());
- if (frame->visible_rect().size() != options_.frame_size || !is_yuv) {
+ // Unfortunately libyuv lacks direct NV12 to I010 conversion, and we
+ // have to do an extra conversion to I420.
+ // TODO(https://crbug.com/libyuv/954) Use NV12ToI010() when implemented
+ const bool vp9_p2_needs_nv12_to_i420 =
+ frame->format() == PIXEL_FORMAT_NV12 && profile_ == VP9PROFILE_PROFILE2;
+ const bool needs_conversion_to_i420 =
+ !IsYuvPlanar(frame->format()) || vp9_p2_needs_nv12_to_i420;
+ if (frame->visible_rect().size() != options_.frame_size ||
+ needs_conversion_to_i420) {
+ auto new_pixel_format =
+ needs_conversion_to_i420 ? PIXEL_FORMAT_I420 : frame->format();
auto resized_frame = frame_pool_.CreateFrame(
- is_yuv ? frame->format() : PIXEL_FORMAT_I420, options_.frame_size,
- gfx::Rect(options_.frame_size), options_.frame_size,
- frame->timestamp());
+ new_pixel_format, options_.frame_size, gfx::Rect(options_.frame_size),
+ options_.frame_size, frame->timestamp());
if (!resized_frame) {
std::move(done_cb).Run(
@@ -454,6 +462,7 @@ void VpxVideoEncoder::Encode(scoped_refptr<VideoFrame> frame,
switch (profile_) {
case VP9PROFILE_PROFILE2:
+ DCHECK_EQ(frame->format(), PIXEL_FORMAT_I420);
// Profile 2 uses 10bit color,
libyuv::I420ToI010(
frame->visible_data(VideoFrame::kYPlane),

View File

@@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dave Tapuska <dtapuska@chromium.org>
Date: Fri, 24 Mar 2023 19:32:54 +0000
Subject: Move the edit commands to an on stack variable
DevTools uses nested event loops and the usage of the class member can
be problematic for iteration because the nested loop can change the
variable's storage causing a UAF.
(cherry picked from commit d9b34f0f3a2d0dd73648eca3ef940fb66806227b)
Bug: 1420510
Change-Id: Ie08a71b60401fa4322cca0cc31062ba64672126a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4355811
Reviewed-by: David Bokan <bokan@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1120123}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4369603
Cr-Commit-Position: refs/branch-heads/5615@{#809}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 2779b0a23477d33e747cb0d97079b463b1060652..b4ca94c7b39a090b7d9700cd86f04a71ebdfcf1f 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -3182,11 +3182,18 @@ void WebFrameWidgetImpl::AddEditCommandForNextKeyEvent(const WebString& name,
}
bool WebFrameWidgetImpl::HandleCurrentKeyboardEvent() {
- bool did_execute_command = false;
+ if (edit_commands_.empty()) {
+ return false;
+ }
WebLocalFrame* frame = FocusedWebLocalFrameInWidget();
if (!frame)
frame = local_root_;
- for (const auto& command : edit_commands_) {
+ bool did_execute_command = false;
+ // Executing an edit command can run JS and we can end up reassigning
+ // `edit_commands_` so move it to a stack variable before iterating on it.
+ Vector<mojom::blink::EditCommandPtr> edit_commands =
+ std::move(edit_commands_);
+ for (const auto& command : edit_commands) {
// In gtk and cocoa, it's possible to bind multiple edit commands to one
// key (but it's the exception). Once one edit command is not executed, it
// seems safest to not execute the rest.

View File

@@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: kylechar <kylechar@chromium.org>
Date: Tue, 28 Feb 2023 21:02:51 +0000
Subject: Add CHECKs in HostFrameSinkManager
It looks like it's possible for a compromised renderer to get multiple
things to register the same FrameSinkId with HostFrameSinkManager. This
violates assumptions around ownership so turn DCHECKs here into CHECKs.
Also convert DCHECKs into CHECKs for registering/unregistering frame
sink hierarchy just in case.
(cherry picked from commit a707ac2d95e4726f4cf0267c9b0c038926c2a691)
Bug: 1414018
Change-Id: If948e758a8484024666f4066360620bc3a9cb493
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4283141
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1109533}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4298330
Cr-Commit-Position: refs/branch-heads/5615@{#69}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc
index 8d724edf1624b83f896a9d2200542fc981e4005e..3ac8a9c13b6655591bf737578d7f9b5aa5874e57 100644
--- a/components/viz/host/host_frame_sink_manager.cc
+++ b/components/viz/host/host_frame_sink_manager.cc
@@ -68,7 +68,7 @@ void HostFrameSinkManager::RegisterFrameSinkId(
DCHECK(client);
FrameSinkData& data = frame_sink_data_map_[frame_sink_id];
- DCHECK(!data.IsFrameSinkRegistered());
+ CHECK(!data.IsFrameSinkRegistered());
DCHECK(!data.has_created_compositor_frame_sink);
data.client = client;
data.report_activation = report_activation;
@@ -87,7 +87,7 @@ void HostFrameSinkManager::InvalidateFrameSinkId(
DCHECK(frame_sink_id.is_valid());
FrameSinkData& data = frame_sink_data_map_[frame_sink_id];
- DCHECK(data.IsFrameSinkRegistered());
+ CHECK(data.IsFrameSinkRegistered());
const bool destroy_synchronously =
data.has_created_compositor_frame_sink && data.wait_on_destruction;
@@ -227,14 +227,14 @@ bool HostFrameSinkManager::RegisterFrameSinkHierarchy(
return false;
}
+ FrameSinkData& parent_data = iter->second;
+ CHECK(!base::Contains(parent_data.children, child_frame_sink_id));
+ parent_data.children.push_back(child_frame_sink_id);
+
// Register and store the parent.
frame_sink_manager_->RegisterFrameSinkHierarchy(parent_frame_sink_id,
child_frame_sink_id);
- FrameSinkData& parent_data = iter->second;
- DCHECK(!base::Contains(parent_data.children, child_frame_sink_id));
- parent_data.children.push_back(child_frame_sink_id);
-
return true;
}
@@ -243,8 +243,9 @@ void HostFrameSinkManager::UnregisterFrameSinkHierarchy(
const FrameSinkId& child_frame_sink_id) {
// Unregister and clear the stored parent.
FrameSinkData& parent_data = frame_sink_data_map_[parent_frame_sink_id];
- DCHECK(base::Contains(parent_data.children, child_frame_sink_id));
- base::Erase(parent_data.children, child_frame_sink_id);
+ size_t num_erased = base::Erase(parent_data.children, child_frame_sink_id);
+ CHECK_EQ(num_erased, 1u);
+
if (parent_data.IsEmpty())
frame_sink_data_map_.erase(parent_frame_sink_id);
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
index 7c25edc433792408a7a285f9cc976289f6500398..20fa10b1e812b97337bfd57c2e4e18d03888c2f3 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -284,7 +284,7 @@ void FrameSinkManagerImpl::UnregisterFrameSinkHierarchy(
}
auto iter = frame_sink_source_map_.find(parent_frame_sink_id);
- DCHECK(iter != frame_sink_source_map_.end());
+ CHECK(iter != frame_sink_source_map_.end());
// Remove |child_frame_sink_id| from parents list of children.
auto& mapping = iter->second;

View File

@@ -0,0 +1,200 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kevin McNee <mcnee@chromium.org>
Date: Tue, 23 May 2023 15:46:16 +0000
Subject: M114: Compute all webview find options before cloning them
Compute all webview find options before cloning them
In WebViewFindHelper::Find, we're cloning the find options before we've
set the value for `new_session`. For requests that are part of the same
session, in WebViewFindHelper::FindReply, we're using the incorrect
value for `new_session` and we're destroying the FindInfo for what we
think is a previous session but is actually for the request we're
currently processing.
We now fully compute the options before cloning them.
(cherry picked from commit bb8e17b942b8b1de0a58b2dce34197e00a3b6525)
Bug: 1443401
Change-Id: Ife6747aedabaf74f9a4855a173349ffe612b6f95
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4533923
Reviewed-by: James Maclean <wjmaclean@chromium.org>
Commit-Queue: James Maclean <wjmaclean@chromium.org>
Auto-Submit: Kevin McNee <mcnee@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1145265}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4556646
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5735@{#941}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 4e6212397a183fdf494f271a255eaf2d536587e6..7159cf6af5cfd0ad5b9e5ba526043a4407a5399d 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -3851,6 +3851,11 @@ IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_testFindInMultipleWebViews) {
TestHelper("testFindInMultipleWebViews", "web_view/shim", NO_TEST_SERVER);
}
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestFindAfterTerminate) {
+ content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
+ TestHelper("testFindAfterTerminate", "web_view/shim", NO_TEST_SERVER);
+}
+
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPI) {
TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER);
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
index 5ed4f0223346b01d83cc04c8cda6c0e92e1a72e3..4a1543d1751cc817a511594d0123deacc0e61ebb 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -2859,6 +2859,20 @@ function testFindInMultipleWebViews() {
});
}
+function testFindAfterTerminate() {
+ let webview = new WebView();
+ webview.src = 'data:text/html,<body><iframe></iframe></body>';
+ webview.addEventListener('loadstop', () => {
+ webview.find('A');
+ webview.terminate();
+ webview.find('B', {'backward': true});
+ webview.find('B', {'backward': true}, (results) => {
+ embedder.test.succeed();
+ });
+ });
+ document.body.appendChild(webview);
+}
+
function testLoadDataAPI() {
var webview = new WebView();
webview.src = 'about:blank';
@@ -3600,6 +3614,7 @@ embedder.test.testList = {
'testFindAPI': testFindAPI,
'testFindAPI_findupdate': testFindAPI_findupdate,
'testFindInMultipleWebViews': testFindInMultipleWebViews,
+ 'testFindAfterTerminate': testFindAfterTerminate,
'testLoadDataAPI': testLoadDataAPI,
'testLoadDataAPIAccessibleResources': testLoadDataAPIAccessibleResources,
'testResizeEvents': testResizeEvents,
diff --git a/extensions/browser/guest_view/web_view/web_view_find_helper.cc b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
index 07b8a6975907190741267e3f92c2e9bde5d9c5d6..f7e5c7c6ece05fa59374735cb1757d1918d1597c 100644
--- a/extensions/browser/guest_view/web_view/web_view_find_helper.cc
+++ b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
@@ -36,12 +36,12 @@ void WebViewFindHelper::CancelAllFindSessions() {
void WebViewFindHelper::DispatchFindUpdateEvent(bool canceled,
bool final_update) {
- DCHECK(find_update_event_.get());
+ CHECK(find_update_event_);
std::unique_ptr<base::DictionaryValue> args(new base::DictionaryValue());
find_update_event_->PrepareResults(args.get());
args->SetBoolKey(webview::kFindCanceled, canceled);
args->SetBoolKey(webview::kFindFinalUpdate, final_update);
- DCHECK(webview_guest_);
+ CHECK(webview_guest_);
webview_guest_->DispatchEventToView(std::make_unique<GuestViewEvent>(
webview::kEventFindReply, std::move(args)));
}
@@ -94,6 +94,17 @@ void WebViewFindHelper::Find(
// Need a new request_id for each new find request.
++current_find_request_id_;
+ if (current_find_session_) {
+ const std::u16string& current_search_text =
+ current_find_session_->search_text();
+ bool current_match_case = current_find_session_->options()->match_case;
+ options->new_session = current_search_text.empty() ||
+ current_search_text != search_text ||
+ current_match_case != options->match_case;
+ } else {
+ options->new_session = true;
+ }
+
// Stores the find request information by request_id so that its callback
// function can be called when the find results are available.
std::pair<FindInfoMap::iterator, bool> insert_result =
@@ -102,32 +113,19 @@ void WebViewFindHelper::Find(
base::MakeRefCounted<FindInfo>(current_find_request_id_, search_text,
options.Clone(), find_function)));
// No duplicate insertions.
- DCHECK(insert_result.second);
-
- blink::mojom::FindOptionsPtr full_options =
- insert_result.first->second->options().Clone();
-
- if (current_find_session_) {
- const std::u16string& current_search_text =
- current_find_session_->search_text();
- bool current_match_case = current_find_session_->options()->match_case;
- full_options->new_session = current_search_text.empty() ||
- current_search_text != search_text ||
- current_match_case != options->match_case;
- } else {
- full_options->new_session = true;
- }
+ CHECK(insert_result.second);
// Link find requests that are a part of the same find session.
- if (!full_options->new_session && current_find_session_) {
- DCHECK(current_find_request_id_ != current_find_session_->request_id());
+ if (!options->new_session && current_find_session_) {
+ CHECK(current_find_request_id_ != current_find_session_->request_id());
current_find_session_->AddFindNextRequest(
insert_result.first->second->AsWeakPtr());
}
// Update the current find session, if necessary.
- if (full_options->new_session)
+ if (options->new_session) {
current_find_session_ = insert_result.first->second;
+ }
// Handle the empty |search_text| case internally.
if (search_text.empty()) {
@@ -137,7 +135,7 @@ void WebViewFindHelper::Find(
}
guest_web_contents->Find(current_find_request_id_, search_text,
- std::move(full_options), /*skip_delay=*/true);
+ std::move(options), /*skip_delay=*/true);
}
void WebViewFindHelper::FindReply(int request_id,
@@ -152,14 +150,14 @@ void WebViewFindHelper::FindReply(int request_id,
return;
// This find request must be a part of an existing find session.
- DCHECK(current_find_session_);
+ CHECK(current_find_session_);
WebViewFindHelper::FindInfo* find_info = find_iterator->second.get();
// Handle canceled find requests.
if (find_info->options()->new_session &&
find_info_map_.begin()->first < request_id) {
- DCHECK_NE(current_find_session_->request_id(),
- find_info_map_.begin()->first);
+ CHECK_NE(current_find_session_->request_id(),
+ find_info_map_.begin()->first);
if (find_update_event_)
DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
EndFindSession(find_info_map_.begin()->first, true /* canceled */);
@@ -174,11 +172,12 @@ void WebViewFindHelper::FindReply(int request_id,
// Aggregate the find results.
find_info->AggregateResults(number_of_matches, selection_rect,
active_match_ordinal, final_update);
- find_update_event_->AggregateResults(number_of_matches, selection_rect,
- active_match_ordinal, final_update);
-
- // Propagate incremental results to the |findupdate| event.
- DispatchFindUpdateEvent(false /* canceled */, final_update);
+ if (find_update_event_) {
+ find_update_event_->AggregateResults(number_of_matches, selection_rect,
+ active_match_ordinal, final_update);
+ // Propagate incremental results to the |findupdate| event.
+ DispatchFindUpdateEvent(false /* canceled */, final_update);
+ }
// Call the callback functions of completed find requests.
if (final_update)

View File

@@ -0,0 +1,127 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrey Kosyakov <caseq@chromium.org>
Date: Thu, 13 Apr 2023 03:55:24 +0000
Subject: Retain DevToolsAgentHost after ForceDetachAllSessions()
(cherry picked from commit 8c4aee2a90d08535cfb1bf0a59e00cae956b1762)
Bug: 1424337
Change-Id: Ie0ebe2a49ffbd2356b896c39446b93e09cd81f5a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4378100
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1123772}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4420271
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
Cr-Commit-Position: refs/branch-heads/5615@{#1244}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/content/browser/devtools/auction_worklet_devtools_agent_host.cc b/content/browser/devtools/auction_worklet_devtools_agent_host.cc
index 20a989999b6da5d269bca3d6c9bf181eea7180e7..34a13a884885926e3985098315fd9121902099e9 100644
--- a/content/browser/devtools/auction_worklet_devtools_agent_host.cc
+++ b/content/browser/devtools/auction_worklet_devtools_agent_host.cc
@@ -96,7 +96,7 @@ AuctionWorkletDevToolsAgentHost::~AuctionWorkletDevToolsAgentHost() = default;
void AuctionWorkletDevToolsAgentHost::WorkletDestroyed() {
worklet_ = nullptr;
- ForceDetachAllSessions();
+ auto retain_this = ForceDetachAllSessionsImpl();
associated_agent_remote_.reset();
}
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
index 46314287ac23017f597c8f63d41cab7e46e2a53a..33f8676e811f3f5684bbd7dabae392668f34f20b 100644
--- a/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -350,12 +350,18 @@ bool DevToolsAgentHostImpl::Inspect() {
}
void DevToolsAgentHostImpl::ForceDetachAllSessions() {
- scoped_refptr<DevToolsAgentHostImpl> protect(this);
+ std::ignore = ForceDetachAllSessionsImpl();
+}
+
+scoped_refptr<DevToolsAgentHost>
+DevToolsAgentHostImpl::ForceDetachAllSessionsImpl() {
+ scoped_refptr<DevToolsAgentHost> retain_this(this);
while (!sessions_.empty()) {
DevToolsAgentHostClient* client = (*sessions_.begin())->GetClient();
DetachClient(client);
client->AgentHostClosed(this);
}
+ return retain_this;
}
void DevToolsAgentHostImpl::ForceDetachRestrictedSessions(
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
index 4c54b9100ef287d5ac5c45235d3a93187df2ca14..f29b5323c4555a96c069377df2b7f126abd029af 100644
--- a/content/browser/devtools/devtools_agent_host_impl.h
+++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -119,15 +119,24 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
void NotifyCreated();
void NotifyNavigated();
void NotifyCrashed(base::TerminationStatus status);
- void ForceDetachAllSessions();
void ForceDetachRestrictedSessions(
const std::vector<DevToolsSession*>& restricted_sessions);
DevToolsIOContext* GetIOContext() { return &io_context_; }
DevToolsRendererChannel* GetRendererChannel() { return &renderer_channel_; }
const std::vector<DevToolsSession*>& sessions() const { return sessions_; }
+ // Returns refptr retaining `this`. All other references may be removed
+ // at this point, so `this` will become invalid as soon as returned refptr
+ // gets destroyed.
+ [[nodiscard]] scoped_refptr<DevToolsAgentHost> ForceDetachAllSessionsImpl();
private:
+ // Note that calling this may result in the instance being deleted,
+ // as instance may be owned by client sessions. This should not be
+ // used by methods of derived classes, use `ForceDetachAllSessionsImpl()`
+ // above instead.
+ void ForceDetachAllSessions();
+
friend class DevToolsAgentHost; // for static methods
friend class DevToolsSession;
friend class DevToolsRendererChannel;
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 2441cbcc429b9458af7743f1a2c5040b91163e4f..71607bffebc49b0a9b898e5ef1ac652190e8eb4f 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -541,9 +541,9 @@ void RenderFrameDevToolsAgentHost::RenderFrameDeleted(RenderFrameHost* rfh) {
}
void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() {
- scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
+ scoped_refptr<DevToolsAgentHost> retain_this;
if (IsAttached()) {
- ForceDetachAllSessions();
+ retain_this = ForceDetachAllSessionsImpl();
UpdateRawHeadersAccess(frame_host_);
}
ChangeFrameHostAndObservedProcess(nullptr);
diff --git a/content/browser/devtools/web_contents_devtools_agent_host.cc b/content/browser/devtools/web_contents_devtools_agent_host.cc
index 20976a4f189446f0cf3b0a0ab168ceb4a92eebe1..7d12f4f8b030200b49350d379f25d4b64b0d1a06 100644
--- a/content/browser/devtools/web_contents_devtools_agent_host.cc
+++ b/content/browser/devtools/web_contents_devtools_agent_host.cc
@@ -299,7 +299,7 @@ DevToolsAgentHostImpl* WebContentsDevToolsAgentHost::GetPrimaryFrameAgent() {
void WebContentsDevToolsAgentHost::WebContentsDestroyed() {
DCHECK_EQ(this, FindAgentHost(web_contents()));
- ForceDetachAllSessions();
+ auto retain_this = ForceDetachAllSessionsImpl();
auto_attacher_.reset();
g_agent_host_instances.Get().erase(web_contents());
Observe(nullptr);
diff --git a/content/browser/devtools/worker_devtools_agent_host.cc b/content/browser/devtools/worker_devtools_agent_host.cc
index db788e7298d6696ec5a354cb387dfdc4030d8ce0..0984b3ae35459d8676b903394577cc6a43601ac8 100644
--- a/content/browser/devtools/worker_devtools_agent_host.cc
+++ b/content/browser/devtools/worker_devtools_agent_host.cc
@@ -87,7 +87,7 @@ void WorkerDevToolsAgentHost::ChildWorkerCreated(
}
void WorkerDevToolsAgentHost::Disconnected() {
- ForceDetachAllSessions();
+ auto retain_this = ForceDetachAllSessionsImpl();
GetRendererChannel()->SetRenderer(mojo::NullRemote(), mojo::NullReceiver(),
ChildProcessHost::kInvalidUniqueID);
std::move(destroyed_callback_).Run(this);

View File

@@ -0,0 +1,98 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Date: Tue, 11 Apr 2023 07:12:34 +0000
Subject: Stop supporting { handleEvent }.
Make the code aligned with the following specification update:
https://github.com/w3c/ServiceWorker/pull/1676
With the previous specification and code, event listener vector
can be modified during the GetEffectiveFunction execution, which may
bring unexpected vector state.
(cherry picked from commit 5105ce37a6853d52ec97894bf6969b3c29a23afd)
Change-Id: I732c4c9ab2caebc49a7f4ef52640df7b8476d838
Bug: 1429201
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4394402
Commit-Queue: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Reviewed-by: Domenic Denicola <domenic@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1126483}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4408837
Reviewed-by: Shunya Shishido <sisidovski@chromium.org>
Reviewed-by: Minoru Chikamune <chikamune@chromium.org>
Cr-Commit-Position: refs/branch-heads/5615@{#1203}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc
index 0435c5a1850dd3ed16197bbc40c1e276e4613a60..a9ad30764c578d1e6cf15bd114ca46e169012039 100644
--- a/content/browser/service_worker/service_worker_version_browsertest.cc
+++ b/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -988,6 +988,17 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
version_->fetch_handler_type());
}
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
+ RemoveFetchEventListenersInGet) {
+ StartServerAndNavigateToSetup();
+ ASSERT_EQ(Install("/service_worker/fetch_event_object_removing_itself.js"),
+ blink::ServiceWorkerStatusCode::kOk);
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::EXISTS,
+ version_->fetch_handler_existence());
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerType::kNotSkippable,
+ version_->fetch_handler_type());
+}
+
// Check that fetch event handler added in the install event should result in a
// service worker that doesn't count as having a fetch event handler.
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
diff --git a/content/test/data/service_worker/fetch_event_object_removing_itself.js b/content/test/data/service_worker/fetch_event_object_removing_itself.js
new file mode 100644
index 0000000000000000000000000000000000000000..110bc4821fae3a63a374d3dc6ca954d4bd744952
--- /dev/null
+++ b/content/test/data/service_worker/fetch_event_object_removing_itself.js
@@ -0,0 +1,19 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+let obj = {};
+function victim() {}
+
+Object.defineProperty(obj, 'handleEvent', {
+ get: () => {
+ // Remove the victim function from the listener vector to break the loop.
+ self.removeEventListener('fetch', victim);
+ return () => {};
+ },
+ configurable: true,
+ enumerable: true,
+});
+
+self.addEventListener('fetch', obj);
+self.addEventListener('fetch', victim);
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index b3a9f691a0fabf14bf6f319173f400c31c664c12..9523aa1ee53aeabe03281a34b4a290a68f6a7dc4 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -2604,7 +2604,7 @@ ServiceWorkerGlobalScope::FetchHandlerType() {
}
ScriptState* script_state = ScriptController()->GetScriptState();
- // Do not remove this, |scope| is needed by `GetEffectiveFunction`.
+ // Do not remove this, |scope| is needed by `GetListenerObject`.
ScriptState::Scope scope(script_state);
// TODO(crbug.com/1349613): revisit the way to implement this.
@@ -2612,8 +2612,8 @@ ServiceWorkerGlobalScope::FetchHandlerType() {
for (RegisteredEventListener& e : *elv) {
EventTarget* et = EventTarget::Create(script_state);
v8::Local<v8::Value> v =
- To<JSBasedEventListener>(e.Callback())->GetEffectiveFunction(*et);
- if (!v->IsFunction() ||
+ To<JSBasedEventListener>(e.Callback())->GetListenerObject(*et);
+ if (v.IsEmpty() || !v->IsFunction() ||
!v.As<v8::Function>()->Experimental_IsNopFunction()) {
return mojom::blink::ServiceWorkerFetchHandlerType::kNotSkippable;
}

View File

@@ -0,0 +1,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Bokan <bokan@chromium.org>
Date: Fri, 3 Mar 2023 21:54:38 +0000
Subject: Fix crash in AnnotationAgentImpl
This crash was occurring because the EphemeralRangeInFlatTree didn't
produce a Node. This is surprising since the RangeInFlatTree that it
comes from is checked for !IsCollapsed().
It turns out it's possible for RangeInFlatTree to be !IsCollapsed but
converting to EphemeralRangeInFlatTree causes IsCollapsed.
This CL ensures we early-out in the case that's tripping the CHECK. It
keeps the early-out exactly matching the CHECK since it must be merged
so we want to be extra sure. A followup will change this condition to
!EphemeralRangeInFlatTree::IsCollapsed which should be equivalent.
(cherry picked from commit 92782b6d34b7a5e26d184e217f8f44e97539686e)
Bug: 1419712
Change-Id: Id1d66a7a67711d463780b37c00600183d6c14f32
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4304486
Reviewed-by: Khushal Sagar <khushalsagar@chromium.org>
Commit-Queue: David Bokan <bokan@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1112568}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4305328
Commit-Queue: Krishna Govind <govind@chromium.org>
Reviewed-by: David Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/branch-heads/5481@{#1321}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
index 9e9181677fb676100ff2a20890e902f298b16644..a5553945fb5923b93dbdf37c6b7b539049018dbb 100644
--- a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
+++ b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
@@ -117,7 +117,11 @@ void AnnotationAgentImpl::ScrollIntoView() const {
EphemeralRangeInFlatTree range = attached_range_->ToEphemeralRange();
- CHECK(range.Nodes().begin() != range.Nodes().end());
+ // TODO(bokan): This should be checked in IsAttached.
+ bool range_has_nodes = range.Nodes().begin() != range.Nodes().end();
+ if (!range_has_nodes) {
+ return;
+ }
Node& first_node = *range.Nodes().begin();
diff --git a/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc b/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc
index 08b6bc177e684c83f51227dc41dc0b894be8a2a7..fbb6f5f1f34b4b26459450ebe35e917e02e47f10 100644
--- a/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc
+++ b/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc
@@ -643,4 +643,54 @@ TEST_F(AnnotationAgentImplTest, AgentScrollIntoViewZoomed) {
EXPECT_TRUE(ExpectInViewport(*element_foo));
}
+// Degenerate case but make sure it doesn't crash. This constructs a
+// RangeInFlatTree that isn't collapsed but turns into a collapsed
+// EphmemeralRangeInFlatTree.
+TEST_F(AnnotationAgentImplTest, ScrollIntoViewCollapsedRange) {
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ p {
+ position: absolute;
+ top: 2000px;
+ }
+ </style>
+ <p id='text'>a</p>
+
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ Element* element_text = GetDocument().getElementById("text");
+
+ const auto& range_start =
+ Position(element_text->firstChild(), PositionAnchorType::kBeforeAnchor);
+ const auto& range_end = Position(element_text, 0);
+
+ RangeInFlatTree* range = MakeGarbageCollected<RangeInFlatTree>(
+ ToPositionInFlatTree(range_start), ToPositionInFlatTree(range_end));
+
+ // TODO(bokan): Is this an editing bug?
+ ASSERT_FALSE(range->IsCollapsed());
+ ASSERT_TRUE(range->ToEphemeralRange().IsCollapsed());
+
+ auto* agent = CreateAgentForRange(range);
+ ASSERT_TRUE(agent);
+
+ ASSERT_EQ(GetDocument().View()->GetRootFrameViewport()->GetScrollOffset(),
+ ScrollOffset());
+
+ MockAnnotationAgentHost host;
+ host.BindToAgent(*agent);
+ agent->Attach();
+
+ // Ensure calling ScrollIntoView doesn't crash.
+ host.agent_->ScrollIntoView();
+ host.FlushForTesting();
+ EXPECT_EQ(GetDocument().View()->GetRootFrameViewport()->GetScrollOffset().y(),
+ 0);
+}
+
} // namespace blink

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Will Harris <wfh@chromium.org>
Date: Thu, 2 Mar 2023 17:01:49 +0000
Subject: Do not register browser_watcher activity report with crashpad
BUG=1415328
(cherry picked from commit f93c88303ccbb64014a575b8ae093aa166832922)
Change-Id: I109f6dac083a69a26841ee5e975e02093ca4cbf6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4257669
Commit-Queue: Will Harris <wfh@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1106253}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4279942
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Zakhar Voit <voit@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1401}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/components/crash/core/app/BUILD.gn b/components/crash/core/app/BUILD.gn
index 09219dd91f4205b38b36d3f62483cf2e9fc3782b..a45dec6b0708a0b0df1fc0f62283c730611b93b7 100644
--- a/components/crash/core/app/BUILD.gn
+++ b/components/crash/core/app/BUILD.gn
@@ -159,7 +159,6 @@ if (is_win) {
deps = [
"//base",
"//build:chromeos_buildflags",
- "//components/browser_watcher:activity_report",
"//components/gwp_asan/buildflags",
"//third_party/crashpad/crashpad/client",
"//third_party/crashpad/crashpad/handler",
diff --git a/components/crash/core/app/DEPS b/components/crash/core/app/DEPS
index 9717215396c918c46e683321115ed55ebcf6534d..9053a97a7068d5c3a240c9c7e99b0f7c2c2c038d 100644
--- a/components/crash/core/app/DEPS
+++ b/components/crash/core/app/DEPS
@@ -3,7 +3,6 @@ include_rules = [
"+third_party/breakpad",
"+components/crash/android/jni_headers",
- "+components/browser_watcher/activity_report_user_stream_data_source.h",
"+components/gwp_asan/buildflags/buildflags.h",
"+components/gwp_asan/crash_handler/crash_handler.h",
"+content/public/common/content_descriptors.h",
diff --git a/components/crash/core/app/run_as_crashpad_handler_win.cc b/components/crash/core/app/run_as_crashpad_handler_win.cc
index 5ae2702540dd635fa208f01ee84e92b2c2f1e220..ac2a160a172a75e6e4d12033b62c73551fb3e288 100644
--- a/components/crash/core/app/run_as_crashpad_handler_win.cc
+++ b/components/crash/core/app/run_as_crashpad_handler_win.cc
@@ -16,7 +16,6 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
-#include "components/browser_watcher/activity_report_user_stream_data_source.h"
#include "components/gwp_asan/buildflags/buildflags.h"
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
#include "third_party/crashpad/crashpad/client/simple_string_dictionary.h"
@@ -81,15 +80,6 @@ int RunAsCrashpadHandler(const base::CommandLine& command_line,
argv.clear();
crashpad::UserStreamDataSources user_stream_data_sources;
- // Interpret an empty user data directory as a missing value.
- if (!user_data_dir.empty()) {
- // Register an extension to collect stability information. The extension
- // will be invoked for any registered process' crashes, but information only
- // exists for instrumented browser processes.
- user_stream_data_sources.push_back(
- std::make_unique<browser_watcher::ActivityReportUserStreamDataSource>(
- user_data_dir));
- }
#if BUILDFLAG(ENABLE_GWP_ASAN)
user_stream_data_sources.push_back(

View File

@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Will Harris <wfh@chromium.org>
Date: Thu, 2 Mar 2023 17:21:30 +0000
Subject: Prevent potential integer overflow in PersistentMemoryAllocator (2/2)
https://crrev.com/c/4250177 added an extra check for potential
integer overflow in GetAllocSize but forgot to add the same
check in GetBlock.
This meant that it was possible to get a pointer to a block
but calling GetAllocSize on the same block would return zero.
This change makes the two functions consistent with each other
so calling GetBlock on invalid data will return nullptr.
BUG=1417317,1415328
(cherry picked from commit 81be8e8f2e13a9f1fe6d3150205a3c13af1db6e9)
Change-Id: I8eb3d91bae4528fc97517d202baf337536a4c81f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4264177
Commit-Queue: Alexei Svitkine <asvitkine@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1107105}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4280124
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Zakhar Voit <voit@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1402}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index b7edfc04c307662450f3a39c20142c3593fbacde..85b5290d8955240f8044054a280105e3f8362714 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -884,8 +884,13 @@ PersistentMemoryAllocator::GetBlock(Reference ref,
if (ref % kAllocAlignment != 0)
return nullptr;
size += sizeof(BlockHeader);
- if (ref + size > mem_size_)
+ uint32_t total_size;
+ if (!base::CheckAdd(ref, size).AssignIfValid(&total_size)) {
+ return nullptr;
+ }
+ if (total_size > mem_size_) {
return nullptr;
+ }
// Validation of referenced block-header.
if (!free_ok) {
@@ -895,8 +900,13 @@ PersistentMemoryAllocator::GetBlock(Reference ref,
return nullptr;
if (block->size < size)
return nullptr;
- if (ref + block->size > mem_size_)
+ uint32_t block_size;
+ if (!base::CheckAdd(ref, block->size).AssignIfValid(&block_size)) {
return nullptr;
+ }
+ if (block_size > mem_size_) {
+ return nullptr;
+ }
if (type_id != 0 &&
block->type_id.load(std::memory_order_relaxed) != type_id) {
return nullptr;

View File

@@ -0,0 +1,142 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rakina Zata Amni <rakina@chromium.org>
Date: Tue, 30 May 2023 16:24:26 +0000
Subject: Return after ReadyCommitNavigation call in CommitErrorPage if it
deletes NavigationRequest
M108 merge issue:
content/browser/renderer_host/navigation_request.cc:
topics_eligible_ isn't present in M108
NavigationRequest::ReadyToCommitNavigation() can cause deletion of the
NavigationRequest, so callers should check for that possibility after
calling the function. A caller in CommitErrorPage is missing that
check, which this CL adds, along with a regression test.
(cherry picked from commit 42db806805ef2be64ee92803d3a784631b2a7df0)
Bug: 1444360
Change-Id: I3964da4909a6709b7730d25d6497b19c098f4f21
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4520493
Commit-Queue: Charlie Reis <creis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1143298}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4567848
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1460}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index f6f25544bd36fceb60ada013178cc8fb67e7b10a..ebc0a0c57fb78b3f0044979cca115c78f98f8c2d 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -4913,7 +4913,13 @@ void NavigationRequest::CommitErrorPage(
}
}
+ base::WeakPtr<NavigationRequest> weak_self(weak_factory_.GetWeakPtr());
ReadyToCommitNavigation(true /* is_error */);
+ // The caller above might result in the deletion of `this`. Return immediately
+ // if so.
+ if (!weak_self) {
+ return;
+ }
PopulateDocumentTokenForCrossDocumentNavigation();
// Use a separate cache shard, and no cookies, for error pages.
diff --git a/content/browser/renderer_host/navigation_request_browsertest.cc b/content/browser/renderer_host/navigation_request_browsertest.cc
index 486a6871d9ff5256123c47accf9f714b67bc30fc..cc4f9acf9e5ec5f8c8dfa8a812a2cc6fb4505526 100644
--- a/content/browser/renderer_host/navigation_request_browsertest.cc
+++ b/content/browser/renderer_host/navigation_request_browsertest.cc
@@ -43,6 +43,7 @@
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_service.mojom.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
@@ -3850,4 +3851,83 @@ IN_PROC_BROWSER_TEST_P(NavigationRequestMPArchBrowserTest,
}
}
+// Tests that when trying to commit an error page for a failed navigation, but
+// the renderer process of the, the navigation won't commit and won't crash.
+// Regression test for https://crbug.com/1444360.
+IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest,
+ RendererCrashedBeforeCommitErrorPage) {
+ // Navigate to `url_a` first.
+ GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ ASSERT_TRUE(NavigateToURL(shell(), url_a));
+
+ // Set up an URLLoaderInterceptor which will cause future navigations to fail.
+ auto url_loader_interceptor = std::make_unique<URLLoaderInterceptor>(
+ base::BindRepeating([](URLLoaderInterceptor::RequestParams* params) {
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::ERR_NOT_IMPLEMENTED;
+ params->client->OnComplete(status);
+ return true;
+ }));
+
+ // Do a navigation to `url_b1` that will fail and commit an error page. This
+ // is important so that the next error page navigation won't need to create a
+ // speculative RenderFrameHost (unless RenderDocument is enabled) and won't
+ // get cancelled earlier than commit time due to speculative RFH deletion.
+ GURL url_b1(embedded_test_server()->GetURL("b.com", "/title1.html"));
+ EXPECT_FALSE(NavigateToURL(shell(), url_b1));
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
+ EXPECT_TRUE(
+ shell()->web_contents()->GetPrimaryMainFrame()->IsErrorDocument());
+
+ // For the next navigation, set up a throttle that will be used to wait for
+ // WillFailRequest() and then defer the navigation, so that we can crash the
+ // error page process first.
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(),
+ NavigationThrottle::PROCEED /* will_start_result */,
+ NavigationThrottle::PROCEED /* will_redirect_result */,
+ NavigationThrottle::DEFER /* will_fail_result */,
+ NavigationThrottle::PROCEED /* will_process_result */);
+
+ // Start a navigation to `url_b2` that will also fail, but before it commits
+ // an error page, cause the error page process to crash.
+ GURL url_b2(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ TestNavigationManager manager(shell()->web_contents(), url_b2);
+ shell()->LoadURL(url_b2);
+ EXPECT_TRUE(manager.WaitForRequestStart());
+
+ // Resume the navigation and wait for WillFailRequest(). After this point, we
+ // will have picked the final RenderFrameHost & RenderProcessHost for the
+ // failed navigation.
+ manager.ResumeNavigation();
+ installer.WaitForThrottleWillFail();
+
+ // Kill the error page process. This will cause for the navigation to `url_b2`
+ // to return early in `NavigationRequest::ReadyToCommitNavigation()` and not
+ // commit a new error page.
+ RenderProcessHost* process_to_kill =
+ manager.GetNavigationHandle()->GetRenderFrameHost()->GetProcess();
+ ASSERT_TRUE(process_to_kill->IsInitializedAndNotDead());
+ {
+ // Trigger a renderer kill by calling DoSomething() which will cause a bad
+ // message to be reported.
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(process_to_kill);
+ mojo::Remote<mojom::TestService> service;
+ process_to_kill->BindReceiver(service.BindNewPipeAndPassReceiver());
+ service->DoSomething(base::DoNothing());
+ EXPECT_EQ(bad_message::RPH_MOJO_PROCESS_ERROR, kill_waiter.Wait());
+ }
+ ASSERT_FALSE(process_to_kill->IsInitializedAndNotDead());
+
+ // Resume the navigation, which won't commit.
+ if (!ShouldCreateNewHostForAllFrames()) {
+ installer.navigation_throttle()->ResumeNavigation();
+ }
+ manager.WaitForNavigationFinished();
+ EXPECT_FALSE(WaitForLoadStop(shell()->web_contents()));
+
+ // The tab stayed at `url_b1` as the `url_b2` navigation didn't commit.
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
+}
+
} // namespace content

View File

@@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joey Arhar <jarhar@chromium.org>
Date: Fri, 21 Apr 2023 20:53:40 +0000
Subject: M112: Cherry pick libxml CVE fix
This patch cherry-picks a fix for [CVE-2023-29469] from libxml:
https://gitlab.gnome.org/GNOME/libxml2/-/commit/547edbf1cbdccd46b2e8ff322a456eaa5931c5df
I cherry-picked these by going into my libxml checkout, checking out the
commit that libxml is at for this M112 branch, cherry-picking the CVE
fixes, then running the roll script on all platforms.
Bug: 1433328
Change-Id: Iaee58b0890f7190386cca3e430286f39ccbbdb02
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4456592
Commit-Queue: David Baron <dbaron@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Auto-Submit: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/branch-heads/5615@{#1325}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium
index 9813d7cd51b62164cd9cad86b57a0b660d22a223..182f0a73439a5e549aed0fa01b22bdca94a8ccbc 100644
--- a/third_party/libxml/README.chromium
+++ b/third_party/libxml/README.chromium
@@ -25,5 +25,6 @@ Modifications:
in chromium's copy of maldoca. See https://github.com/google/maldoca/issues/87
- Add helper classes in the chromium/ subdirectory.
- Delete various unused files, see chromium/roll.py
+- Cherry picked fix for CVE-2023-29469
This import was generated by the chromium/roll.py script.
diff --git a/third_party/libxml/src/dict.c b/third_party/libxml/src/dict.c
index 5c9ca71940ceea9f4aec9f1e7dfb6c3ba6bd8c76..300df7a55638f4c6728a88c336b3c3197ab05676 100644
--- a/third_party/libxml/src/dict.c
+++ b/third_party/libxml/src/dict.c
@@ -455,7 +455,8 @@ static unsigned long
xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
unsigned long value = seed;
- if (name == NULL) return(0);
+ if ((name == NULL) || (namelen <= 0))
+ return(value);
value += *name;
value <<= 5;
if (namelen > 10) {

View File

@@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Keren Zhu <kerenzhu@chromium.org>
Date: Mon, 24 Apr 2023 15:36:21 +0000
Subject: Fix ScopedObservation UaF in
BubbleDialogDelegate::AnchorWidgetObserver
A ScopedObservation can outlive the aura::Window it observes, leading to
a use-after-free error in ~ScopedObservation(). The problem occurs in
BubbleDialogDelegate::AnchorWidgetObserver. This fix listens for
OnWindowDestroying() and resets the observation to prevent the UaF.
(cherry picked from commit 72bd6a1018548ee63a2ec06d6c7714d3a8cdf8a8)
Bug: 1423360
Change-Id: I742b4624b2664dea3fd97db7b399fcd15e45c8fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4455016
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Reviewed-by: Elly Fong-Jones <ellyjones@chromium.org>
Commit-Queue: Keren Zhu <kerenzhu@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1133511}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4466947
Reviewed-by: Allen Bauer <kylixrd@chromium.org>
Cr-Commit-Position: refs/branch-heads/5615@{#1353}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc
index 2a84e8f5a7078e76dd40208c0265df3db06a7621..ad7f33ebcb5a09dc5ca97ddbcd5b8bc21a9fb529 100644
--- a/ui/views/bubble/bubble_dialog_delegate_view.cc
+++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -318,6 +318,13 @@ class BubbleDialogDelegate::AnchorWidgetObserver : public WidgetObserver,
owner_->OnAnchorBoundsChanged();
}
}
+
+ // If the native window is closed by the OS, OnWidgetDestroying() won't
+ // fire. Instead, OnWindowDestroying() will fire before aura::Window
+ // destruction. See //docs/ui/views/widget_destruction.md.
+ void OnWindowDestroying(aura::Window* window) override {
+ window_observation_.Reset();
+ }
#endif
private:

View File

@@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maggie Chen <magchen@chromium.org>
Date: Thu, 18 May 2023 00:20:34 +0000
Subject: Fix a crash caused by calling TRACE_EVENT
Now use literal constant for TRACE_EVENT. Passing a pointer instead of
string content to TRACE_EVENT causes a crash in ScopedTracer.
(cherry picked from commit 6f2e587807aff2306309025db1c15fc59290eb6f)
Bug: 1444195
Change-Id: I02aa1148d61e7596e9293ffc866135e99991e42e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4522164
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Maggie Chen <magchen@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1144352}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4544885
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5735@{#749}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/ui/gl/swap_chain_presenter.cc b/ui/gl/swap_chain_presenter.cc
index 31deec1168cd438c0a37edc9230484ba2181b525..5cf91faf97a2a6f4f130d9e62678d972f55756ec 100644
--- a/ui/gl/swap_chain_presenter.cc
+++ b/ui/gl/swap_chain_presenter.cc
@@ -1635,10 +1635,8 @@ bool SwapChainPresenter::ReallocateSwapChain(
}
}
if (!use_yuv_swap_chain) {
- std::ostringstream trace_event_stream;
- trace_event_stream << "SwapChainPresenter::ReallocateSwapChain::"
- << DxgiFormatToString(swap_chain_format);
- TRACE_EVENT0("gpu", trace_event_stream.str().c_str());
+ TRACE_EVENT1("gpu", "SwapChainPresenter::ReallocateSwapChain::BGRA",
+ "format", DxgiFormatToString(swap_chain_format));
desc.Format = swap_chain_format;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO;

View File

@@ -0,0 +1,99 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Wed, 21 Jun 2023 17:57:52 +0000
Subject: webcodecs: Fix crash when changing temporal layer count in AV1
encoder
(cherry picked from commit f312efac1b90117729e8961b58c643fc0eae1fbd)
Bug: 1447568
Change-Id: I4ecb02ed956707571573a65ade17fdffe676b502
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4554300
Auto-Submit: Eugene Zemtsov <eugene@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1148041}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4610718
Cr-Commit-Position: refs/branch-heads/5735@{#1360}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/media/video/av1_video_encoder.cc b/media/video/av1_video_encoder.cc
index 71e4fa09a650183c3cd2ef84520d9493f2655bba..266170a524bc8f4317bec941714fe0be9333de37 100644
--- a/media/video/av1_video_encoder.cc
+++ b/media/video/av1_video_encoder.cc
@@ -118,6 +118,7 @@ EncoderStatus SetUpAomConfig(const VideoEncoder::Options& opts,
svc_params = {};
svc_params.framerate_factor[0] = 1;
svc_params.number_spatial_layers = 1;
+ svc_params.number_temporal_layers = 1;
if (opts.scalability_mode.has_value()) {
switch (opts.scalability_mode.value()) {
case SVCScalabilityMode::kL1T2:
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc
index 318c743bddcf9bec3a994f125ea329d45f8c4376..7a27b9326a5df556b1a6bacdad71081d46bcc781 100644
--- a/media/video/software_video_encoder_test.cc
+++ b/media/video/software_video_encoder_test.cc
@@ -602,6 +602,63 @@ TEST_P(SVCVideoEncoderTest, EncodeClipTemporalSvc) {
}
}
+TEST_P(SVCVideoEncoderTest, ChangeLayers) {
+ VideoEncoder::Options options;
+ options.frame_size = gfx::Size(640, 480);
+ options.bitrate = Bitrate::ConstantBitrate(1000000u); // 1Mbps
+ options.framerate = 25;
+ options.scalability_mode = GetParam().scalability_mode;
+ std::vector<scoped_refptr<VideoFrame>> frames_to_encode;
+
+ std::vector<VideoEncoderOutput> chunks;
+ size_t total_frames_count = 80;
+
+ // Encoder all frames with 3 temporal layers and put all outputs in |chunks|
+ auto frame_duration = base::Seconds(1.0 / options.framerate.value());
+
+ VideoEncoder::OutputCB encoder_output_cb = base::BindLambdaForTesting(
+ [&](VideoEncoderOutput output,
+ absl::optional<VideoEncoder::CodecDescription> desc) {
+ chunks.push_back(std::move(output));
+ });
+
+ encoder_->Initialize(profile_, options, /*info_cb=*/base::DoNothing(),
+ std::move(encoder_output_cb),
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+
+ uint32_t color = 0x964050;
+ for (auto frame_index = 0u; frame_index < total_frames_count; frame_index++) {
+ auto timestamp = frame_index * frame_duration;
+
+ const bool reconfigure = (frame_index == total_frames_count / 2);
+ if (reconfigure) {
+ encoder_->Flush(ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+
+ // Ask encoder to change SVC mode, empty output callback
+ // means the encoder should keep the old one.
+ options.scalability_mode = SVCScalabilityMode::kL1T1;
+ encoder_->ChangeOptions(
+ options, VideoEncoder::OutputCB(),
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+ }
+
+ auto frame =
+ CreateFrame(options.frame_size, pixel_format_, timestamp, color);
+ color = (color << 1) + frame_index;
+ frames_to_encode.push_back(frame);
+ encoder_->Encode(frame, VideoEncoder::EncodeOptions(false),
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+ }
+
+ encoder_->Flush(ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+ EXPECT_EQ(chunks.size(), total_frames_count);
+}
+
TEST_P(H264VideoEncoderTest, ReconfigureWithResize) {
VideoEncoder::Options options;
gfx::Size size1(320, 200), size2(400, 240);

View File

@@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kenichi Ishibashi <bashi@chromium.org>
Date: Sat, 8 Apr 2023 04:16:50 +0000
Subject: Check SpdyProxyClientSocket is alive after write callback
To ensure that we don't use any member field.
(cherry picked from commit b71541b22ca19d5c3a7c01fedffe521b26577b72)
Bug: 1428820
Change-Id: Icf6677c652a47dc2fd2d01675e94cda031a015f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4394863
Reviewed-by: Adam Rice <ricea@chromium.org>
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1125634}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4410322
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Kenichi Ishibashi <bashi@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5615@{#1172}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
index 173fc5cdbb67958cc9ca43284ff989196b287a8e..d9b67febc27cc99e5b3383a372451345cec6daaa 100644
--- a/net/spdy/spdy_proxy_client_socket.cc
+++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -279,7 +279,14 @@ int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
void SpdyProxyClientSocket::RunWriteCallback(int result) {
CHECK(write_callback_);
+
+ base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr();
std::move(write_callback_).Run(result);
+ if (!weak_ptr) {
+ // `this` was already destroyed while running `write_callback_`. Must
+ // return immediately without touching any field member.
+ return;
+ }
if (end_stream_state_ == EndStreamState::kEndStreamReceived) {
base::ThreadTaskRunnerHandle::Get()->PostTask(

View File

@@ -0,0 +1,94 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kenichi Ishibashi <bashi@chromium.org>
Date: Sat, 8 Apr 2023 01:56:25 +0000
Subject: Remove the second WeakPtrFactory from SpdyProxyClientSocket
It was introduced [1] to work around an old issue that wouldn't happen
any more since we store a write callback in the class. Instead of having
the second WeakPtrFactory and moving the callback, we can just keep it
until RunWriteCallback() is called.
This is a speculative fix for the linked bug.
[1] https://codereview.chromium.org/338583003/
(cherry picked from commit 01b25615896b911e21103dd381fafc1f85886d91)
Bug: 1428820
Change-Id: I0b5af2675b68188e208c2ecd42293251b2722b28
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4393905
Reviewed-by: Adam Rice <ricea@chromium.org>
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1125216}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4410320
Auto-Submit: Kenichi Ishibashi <bashi@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5615@{#1171}
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
index 5984ecedb3a14274bc33efe20b407dd33bc8a410..173fc5cdbb67958cc9ca43284ff989196b287a8e 100644
--- a/net/spdy/spdy_proxy_client_socket.cc
+++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -123,7 +123,6 @@ void SpdyProxyClientSocket::Disconnect() {
write_buffer_len_ = 0;
write_callback_.Reset();
- write_callback_weak_factory_.InvalidateWeakPtrs();
next_state_ = STATE_DISCONNECTED;
@@ -278,9 +277,9 @@ int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
return spdy_stream_->GetLocalAddress(address);
}
-void SpdyProxyClientSocket::RunWriteCallback(CompletionOnceCallback callback,
- int result) const {
- std::move(callback).Run(result);
+void SpdyProxyClientSocket::RunWriteCallback(int result) {
+ CHECK(write_callback_);
+ std::move(write_callback_).Run(result);
if (end_stream_state_ == EndStreamState::kEndStreamReceived) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -517,8 +516,7 @@ void SpdyProxyClientSocket::OnDataSent() {
// stream's write callback chain to unwind (see crbug.com/355511).
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&SpdyProxyClientSocket::RunWriteCallback,
- write_callback_weak_factory_.GetWeakPtr(),
- std::move(write_callback_), rv));
+ weak_factory_.GetWeakPtr(), rv));
}
void SpdyProxyClientSocket::OnTrailers(const spdy::Http2HeaderBlock& trailers) {
diff --git a/net/spdy/spdy_proxy_client_socket.h b/net/spdy/spdy_proxy_client_socket.h
index cbb961a68c93b9485bd0bf1c5e31014bdc95a84e..98b9e74427f48399bbc53bfad5b45a8dc18ab84b 100644
--- a/net/spdy/spdy_proxy_client_socket.h
+++ b/net/spdy/spdy_proxy_client_socket.h
@@ -121,9 +121,9 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
STATE_CLOSED
};
- // Calls |callback.Run(result)|. Used to run a callback posted to the
+ // Calls `write_callback_(result)`. Used to run a callback posted to the
// message loop.
- void RunWriteCallback(CompletionOnceCallback callback, int result) const;
+ void RunWriteCallback(int result);
void OnIOComplete(int result);
@@ -195,13 +195,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
};
EndStreamState end_stream_state_ = EndStreamState::kNone;
- // The default weak pointer factory.
base::WeakPtrFactory<SpdyProxyClientSocket> weak_factory_{this};
-
- // Only used for posting write callbacks. Weak pointers created by this
- // factory are invalidated in Disconnect().
- base::WeakPtrFactory<SpdyProxyClientSocket> write_callback_weak_factory_{
- this};
};
} // namespace net

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Will Harris <wfh@chromium.org>
Date: Thu, 2 Mar 2023 16:49:42 +0000
Subject: Prevent potential integer overflow in PersistentMemoryAllocator (1/2)
BUG=1415328
(cherry picked from commit 19de280a0c28065acf2a7e001af5c981698a461c)
Change-Id: I66dcae6a1aacc1310ddd715033b3704c932b9800
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250177
Commit-Queue: Will Harris <wfh@chromium.org>
Commit-Queue: Alexei Svitkine <asvitkine@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1105177}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4279513
Commit-Queue: Zakhar Voit <voit@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1400}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index bc4618bf30832d010570e8a490d3d893f064237b..b7edfc04c307662450f3a39c20142c3593fbacde 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -531,7 +531,10 @@ size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const {
uint32_t size = block->size;
// Header was verified by GetBlock() but a malicious actor could change
// the value between there and here. Check it again.
- if (size <= sizeof(BlockHeader) || ref + size > mem_size_) {
+ uint32_t total_size;
+ if (size <= sizeof(BlockHeader) ||
+ !base::CheckAdd(ref, size).AssignIfValid(&total_size) ||
+ total_size > mem_size_) {
SetCorrupt();
return 0;
}

View File

@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Anderson <thomasanderson@chromium.org>
Date: Tue, 13 Dec 2022 22:49:47 +0000
Subject: Ensure DND buffer size is a multiple of scale
When using a scale factor of 2.0 on Sway ToT, this fixes a crash when
trying to DND an image or text that happens to have an odd width or
height. The issue is Wlroots will not allow attaching a buffer to a
surface when the buffer's size isn't a multiple of the surface's scale
factor.
R=nickdiego
Bug: 578890
Change-Id: I283ed27a7d0051b895e0eed3b9a74d83feac3a37
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4099423
Reviewed-by: Nick Yamane <nickdiego@igalia.com>
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1082777}
diff --git a/ui/ozone/platform/wayland/common/wayland_util.cc b/ui/ozone/platform/wayland/common/wayland_util.cc
index 4e8aa4b1e5530311338fbb43483e16d845707d2f..9b5806895a92cc92176644a0477d48bf79a35606 100644
--- a/ui/ozone/platform/wayland/common/wayland_util.cc
+++ b/ui/ozone/platform/wayland/common/wayland_util.cc
@@ -115,7 +115,8 @@ uint32_t IdentifyDirection(const ui::WaylandConnection& connection,
bool DrawBitmap(const SkBitmap& bitmap, ui::WaylandShmBuffer* out_buffer) {
DCHECK(out_buffer);
DCHECK(out_buffer->GetMemory());
- DCHECK_EQ(out_buffer->size(), gfx::Size(bitmap.width(), bitmap.height()));
+ DCHECK(gfx::Rect(out_buffer->size())
+ .Contains(gfx::Rect(bitmap.width(), bitmap.height())));
auto* mapped_memory = out_buffer->GetMemory();
auto size = out_buffer->size();
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
index f2123ec8bac3f6afe9f46ba358cb9c829b2e9325..2bb7d0f4de6f8c50cc2bbaba6baaa0b684531115 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -140,7 +140,8 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
icon_surface_ = std::make_unique<WaylandSurface>(connection_, nullptr);
if (icon_surface_->Initialize()) {
// Corresponds to actual scale factor of the origin surface.
- icon_surface_->set_surface_buffer_scale(origin_window->window_scale());
+ icon_surface_buffer_scale_ = origin_window->window_scale();
+ icon_surface_->set_surface_buffer_scale(icon_surface_buffer_scale_);
// Icon surface do not need input.
const gfx::Rect empty_region_px;
icon_surface_->set_input_region(&empty_region_px);
@@ -153,6 +154,7 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
} else {
LOG(ERROR) << "Failed to create drag icon surface.";
icon_surface_.reset();
+ icon_surface_buffer_scale_ = 1.0f;
}
}
@@ -225,21 +227,28 @@ void WaylandDataDragController::DrawIconInternal() {
return;
DCHECK(!icon_bitmap_->empty());
- gfx::Size size(icon_bitmap_->width(), icon_bitmap_->height());
+ // The protocol expects the attached buffer to have a pixel size that is a
+ // multiple of the surface's scale factor. Some compositors (eg. Wlroots) will
+ // refuse to attach the buffer if this condition is not met.
+ const gfx::Size size_dip =
+ gfx::ScaleToCeiledSize({icon_bitmap_->width(), icon_bitmap_->height()},
+ 1.0f / icon_surface_buffer_scale_);
+ const gfx::Size size_px =
+ gfx::ScaleToCeiledSize(size_dip, icon_surface_buffer_scale_);
icon_buffer_ = std::make_unique<WaylandShmBuffer>(
- connection_->wayland_buffer_factory(), size);
+ connection_->wayland_buffer_factory(), size_px);
if (!icon_buffer_->IsValid()) {
LOG(ERROR) << "Failed to create drag icon buffer.";
return;
}
- DVLOG(3) << "Drawing drag icon. size=" << size.ToString();
+ DVLOG(3) << "Drawing drag icon. size_px=" << size_px.ToString();
wl::DrawBitmap(*icon_bitmap_, icon_buffer_.get());
auto* const surface = icon_surface_->surface();
wl_surface_attach(surface, icon_buffer_->get(), icon_offset_.x(),
icon_offset_.y());
- wl_surface_damage(surface, 0, 0, size.width(), size.height());
+ wl_surface_damage(surface, 0, 0, size_px.width(), size_px.height());
wl_surface_commit(surface);
}
@@ -370,6 +379,7 @@ void WaylandDataDragController::OnDataSourceFinish(bool completed) {
data_offer_.reset();
icon_buffer_.reset();
icon_surface_.reset();
+ icon_surface_buffer_scale_ = 1.0f;
icon_bitmap_ = nullptr;
icon_frame_callback_.reset();
offered_exchange_data_provider_.reset();
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
index 9912f1e0aebaf8289d2cdcdbff472a0baa91a981..39acda6bae9eb3a3f7837f6c93fafcee493bf78b 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
@@ -224,6 +224,7 @@ class WaylandDataDragController : public WaylandDataDevice::DragDelegate,
// Drag icon related variables.
std::unique_ptr<WaylandSurface> icon_surface_;
+ float icon_surface_buffer_scale_ = 1.0f;
std::unique_ptr<WaylandShmBuffer> icon_buffer_;
raw_ptr<const SkBitmap> icon_bitmap_ = nullptr;
gfx::Point icon_offset_;

View File

@@ -21,5 +21,13 @@
"src/electron/patches/Mantle": "src/third_party/squirrel.mac/vendor/Mantle",
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC"
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"src/electron/patches/pdfium": "src/third_party/pdfium",
"src/electron/patches/skia": "src/third_party/skia",
"src/electron/patches/dawn": "src/third_party/dawn",
"src/electron/patches/webrtc": "src/third_party/webrtc"
}

1
patches/dawn/.patches Normal file
View File

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

View File

@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brandon Jones <brandon1.jones@intel.com>
Date: Fri, 5 May 2023 18:02:42 +0000
Subject: Change D3D12 Descriptor Allocator To Invalidate Submitted Descriptors
Changes D3D12 descriptor allocator to invalidate existing descriptors
after the descriptor heap was submitted for use. This fixes a
synchonization issue where stale descriptors were seen as valid because
command list execution ran long.
Bug: dawn:1701
Bug: chromium:1442263
No-Try: true
Change-Id: Ibfd450b3be6cf91d66e8dce4ffd19ecf1a37f7f5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129920
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com>
(cherry picked from commit df6cb236493da101dad79fe50d4e6df0d5d1e915)
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131508
Kokoro: Austin Eng <enga@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
index fe99a63ac9d2d082c2c23eb7940a733a9d13846a..aedb28ad58a0a972879f07a6037499f901fcf04a 100644
--- a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
@@ -237,9 +237,11 @@ bool ShaderVisibleDescriptorAllocator::IsLastShaderVisibleHeapInLRUForTesting()
bool ShaderVisibleDescriptorAllocator::IsAllocationStillValid(
const GPUDescriptorHeapAllocation& allocation) const {
- // Consider valid if allocated for the pending submit and the shader visible heaps
- // have not switched over.
- return (allocation.GetLastUsageSerial() > mDevice->GetCompletedCommandSerial() &&
+ // Descriptor allocations are only valid for the serial they were created for and are
+ // re-allocated every submit. For this reason, we view any descriptors allocated prior to the
+ // pending submit as invalid. We must also verify the descriptor heap has not switched (because
+ // a larger descriptor heap was needed).
+ return (allocation.GetLastUsageSerial() == mDevice->GetPendingCommandSerial() &&
allocation.GetHeapSerial() == mHeapSerial);
}

View File

@@ -30,7 +30,7 @@ index 93d85d46dc6b3b30795b88ffa8070253f62e51bd..05f8232c4b38f51e8059e8d01b0eb247
if ((s.flags & SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK) == 0) {
auto* promise_reject_cb = s.promise_reject_callback ?
diff --git a/src/node.h b/src/node.h
index 38bbb20968772a4ba6bceddb04a83589f8582fc8..a5ee97ae83149a1924e9d6198ad4b2a7fd8b876d 100644
index b5e4d42035a23b49fd144d563f5716fcaed2b45c..f2e2acc98c1165430e46351fe07637315cc2c38e 100644
--- a/src/node.h
+++ b/src/node.h
@@ -374,6 +374,8 @@ struct IsolateSettings {

View File

@@ -52,7 +52,7 @@ index 08894bf3908916d1cb639810c5e1b2afae74ff4d..19cbde58df38009258db145c5f7dbe73
o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
diff --git a/src/node.h b/src/node.h
index b6a26f8adf11959f94a00de0cbf9016fcc8707cb..38bbb20968772a4ba6bceddb04a83589f8582fc8 100644
index b6a26f8adf11959f94a00de0cbf9016fcc8707cb..b5e4d42035a23b49fd144d563f5716fcaed2b45c 100644
--- a/src/node.h
+++ b/src/node.h
@@ -22,6 +22,12 @@
@@ -61,7 +61,7 @@ index b6a26f8adf11959f94a00de0cbf9016fcc8707cb..38bbb20968772a4ba6bceddb04a83589
+#ifdef ELECTRON_ENSURE_CONFIG_GYPI
+#ifndef USING_ELECTRON_CONFIG_GYPI
+#error "It looks like you are building this native module without using the right config.gypi. This normally means that you need to update electron-rebuild (>=3.2.8) or node-gyp (>=8.4.0) if you're building modules directly."
+#error "It looks like you are building this native module without using the right config.gypi. This normally means that you need to update electron-rebuild (>=3.2.8) or node-gyp (>=9.0.0) if you're building modules directly."
+#endif
+#endif
+

View File

@@ -7,7 +7,7 @@ Wc++98-compat-extra-semi is turned on for Electron so this
patch fixes that error in node.
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
index 92d5020f293c98c81d3891a82f7320629bf9f926..2e815154ddbbd687e9c823cb7d42f11b7cb48000 100644
index 573c185465407bbe34ef1c4ec5f58f6add596d42..b64333132d5c2322d29ad087fe60e0bbe24bebe2 100644
--- a/src/node_serdes.cc
+++ b/src/node_serdes.cc
@@ -32,7 +32,7 @@ namespace serdes {

View File

@@ -155,7 +155,7 @@ index f7314c906e580664be445a8912030e17a3ac2fa4..99258ad0aa1e15ea1ba139fd0e83111e
// Delegate to V8's allocator for compatibility with the V8 memory cage.
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
index f6f0034bc24d09e3ad65491c7d6be0b9c9db1581..92d5020f293c98c81d3891a82f7320629bf9f926 100644
index f6f0034bc24d09e3ad65491c7d6be0b9c9db1581..573c185465407bbe34ef1c4ec5f58f6add596d42 100644
--- a/src/node_serdes.cc
+++ b/src/node_serdes.cc
@@ -29,6 +29,11 @@ using v8::ValueSerializer;
@@ -219,17 +219,32 @@ index f6f0034bc24d09e3ad65491c7d6be0b9c9db1581..92d5020f293c98c81d3891a82f732062
Maybe<bool> SerializerContext::WriteHostObject(Isolate* isolate,
Local<Object> input) {
MaybeLocal<Value> ret;
@@ -211,7 +240,12 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
@@ -209,9 +238,14 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
// Note: Both ValueSerializer and this Buffer::New() variant use malloc()
// as the underlying allocator.
std::pair<uint8_t*, size_t> ret = ctx->serializer_.Release();
auto buf = Buffer::New(ctx->env(),
reinterpret_cast<char*>(ret.first),
- auto buf = Buffer::New(ctx->env(),
- reinterpret_cast<char*>(ret.first),
- ret.second);
+ ret.second,
+ [](char* data, void* hint){
+ if (data)
+ GetAllocator()->Free(data, reinterpret_cast<size_t>(hint));
+ },
+ reinterpret_cast<void*>(ctx->last_length_));
+ std::unique_ptr<v8::BackingStore> bs =
+ v8::ArrayBuffer::NewBackingStore(reinterpret_cast<char*>(ret.first), ret.second,
+ [](void* data, size_t length, void* deleter_data) {
+ if (data) GetAllocator()->Free(reinterpret_cast<char*>(data), length);
+ }, nullptr);
+ Local<ArrayBuffer> ab = v8::ArrayBuffer::New(ctx->env()->isolate(), std::move(bs));
+
+ auto buf = Buffer::New(ctx->env(), ab, 0, ret.second);
if (!buf.IsEmpty()) {
args.GetReturnValue().Set(buf.ToLocalChecked());
diff --git a/test/parallel/test-v8-serialize-leak.js b/test/parallel/test-v8-serialize-leak.js
index a90c398adcdaf30491a0fecdcf00895038d62e69..f5b8a1430ad2033eae06ca0157af2fb51d3f36a5 100644
--- a/test/parallel/test-v8-serialize-leak.js
+++ b/test/parallel/test-v8-serialize-leak.js
@@ -23,5 +23,5 @@ const after = process.memoryUsage.rss();
if (process.config.variables.asan) {
assert(after < before * 10, `asan: before=${before} after=${after}`);
} else {
- assert(after < before * 2, `before=${before} after=${after}`);
+ assert(after < before * 3, `before=${before} after=${after}`);
}

4
patches/pdfium/.patches Normal file
View File

@@ -0,0 +1,4 @@
cherry-pick-a0d16d18d072.patch
m114_observe_cpwl_combobox_across_all_on_methods.patch
m114_observe_widget_across_setoptionselection_calls.patch
m114_always_check_return_code_from_cpwl_combobox_setpopup.patch

View File

@@ -0,0 +1,164 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Tue, 14 Mar 2023 21:18:45 +0000
Subject: M110: Observe CPWL_* object destruction across CPDFSDK_Widget methods
This is a simple fix to stop the symptoms while we investigate
how to avoid mutations at these points in the first place.
-- fix some nearby braces and annoying blank lines while at it.
Bug: chromium:1419831
Change-Id: I20c38806b91c7c0c9016bb1b567a04ce319243d8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/104397
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
(cherry picked from commit 63e3719f1ec20ee6db804b2b2d4b00680db18d9c)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/104833
Auto-Submit: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/formfiller/cffl_checkbox.cpp b/fpdfsdk/formfiller/cffl_checkbox.cpp
index 2cea0e0ad0d13149a6e7e499c5ea3366d84c9aaa..7c875486016b0b4205b31b9db077850663bc33af 100644
--- a/fpdfsdk/formfiller/cffl_checkbox.cpp
+++ b/fpdfsdk/formfiller/cffl_checkbox.cpp
@@ -65,9 +65,13 @@ bool CFFL_CheckBox::OnChar(CPDFSDK_Widget* pWidget,
CFFL_FormField::OnChar(pWidget, nChar, nFlags);
CPWL_CheckBox* pWnd = CreateOrUpdatePWLCheckBox(pPageView);
- if (pWnd && !pWnd->IsReadOnly())
- pWnd->SetCheck(!pWidget->IsChecked());
-
+ if (pWnd && !pWnd->IsReadOnly()) {
+ ObservedPtr<CPWL_CheckBox> pObservedBox(pWnd);
+ const bool is_checked = pWidget->IsChecked();
+ if (pObservedBox) {
+ pObservedBox->SetCheck(!is_checked);
+ }
+ }
return CommitData(pPageView, nFlags);
}
default:
@@ -80,14 +84,17 @@ bool CFFL_CheckBox::OnLButtonUp(CPDFSDK_PageView* pPageView,
Mask<FWL_EVENTFLAG> nFlags,
const CFX_PointF& point) {
CFFL_Button::OnLButtonUp(pPageView, pWidget, nFlags, point);
-
- if (!IsValid())
+ if (!IsValid()) {
return true;
-
+ }
CPWL_CheckBox* pWnd = CreateOrUpdatePWLCheckBox(pPageView);
- if (pWnd)
- pWnd->SetCheck(!pWidget->IsChecked());
-
+ if (pWnd) {
+ ObservedPtr<CPWL_CheckBox> pObservedBox(pWnd);
+ const bool is_checked = pWidget->IsChecked();
+ if (pObservedBox) {
+ pObservedBox->SetCheck(!is_checked);
+ }
+ }
return CommitData(pPageView, nFlags);
}
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
index 96b4aea8e74a629d201cd780d631d4e82d5b284c..4bb100014c804adcfc7f1f2023cd1870f81c85e8 100644
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
@@ -105,11 +105,15 @@ bool CFFL_ListBox::IsDataChanged(const CPDFSDK_PageView* pPageView) {
void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
CPWL_ListBox* pListBox = GetPWLListBox(pPageView);
- if (!pListBox)
+ if (!pListBox) {
return;
-
+ }
int32_t nNewTopIndex = pListBox->GetTopVisibleIndex();
+ ObservedPtr<CPWL_ListBox> observed_box(pListBox);
m_pWidget->ClearSelection();
+ if (!observed_box) {
+ return;
+ }
if (m_pWidget->GetFieldFlags() & pdfium::form_flags::kChoiceMultiSelect) {
for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
if (pListBox->IsItemSelected(i))
@@ -121,17 +125,17 @@ void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget.Get());
ObservedPtr<CFFL_ListBox> observed_this(this);
m_pWidget->SetTopVisibleIndex(nNewTopIndex);
- if (!observed_widget)
+ if (!observed_widget) {
return;
-
+ }
m_pWidget->ResetFieldAppearance();
- if (!observed_widget)
+ if (!observed_widget) {
return;
-
+ }
m_pWidget->UpdateField();
- if (!observed_widget || !observed_this)
+ if (!observed_widget || !observed_this) {
return;
-
+ }
SetChangeMark();
}
diff --git a/fpdfsdk/formfiller/cffl_textfield.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp
index 5ae3e94cd185e56d759cb99dbc90997caa606283..2ceedde4a765e765e75e478ebee43204fe440fe4 100644
--- a/fpdfsdk/formfiller/cffl_textfield.cpp
+++ b/fpdfsdk/formfiller/cffl_textfield.cpp
@@ -142,26 +142,29 @@ bool CFFL_TextField::IsDataChanged(const CPDFSDK_PageView* pPageView) {
}
void CFFL_TextField::SaveData(const CPDFSDK_PageView* pPageView) {
- CPWL_Edit* pWnd = GetPWLEdit(pPageView);
- if (!pWnd)
+ ObservedPtr<CPWL_Edit> observed_edit(GetPWLEdit(pPageView));
+ if (!observed_edit) {
return;
-
+ }
WideString sOldValue = m_pWidget->GetValue();
- WideString sNewValue = pWnd->GetText();
+ if (!observed_edit) {
+ return;
+ }
+ WideString sNewValue = observed_edit->GetText();
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget.Get());
ObservedPtr<CFFL_TextField> observed_this(this);
m_pWidget->SetValue(sNewValue);
- if (!observed_widget)
+ if (!observed_widget) {
return;
-
+ }
m_pWidget->ResetFieldAppearance();
- if (!observed_widget)
+ if (!observed_widget) {
return;
-
+ }
m_pWidget->UpdateField();
- if (!observed_widget || !observed_this)
+ if (!observed_widget || !observed_this) {
return;
-
+ }
SetChangeMark();
}
@@ -172,9 +175,7 @@ void CFFL_TextField::GetActionData(const CPDFSDK_PageView* pPageView,
case CPDF_AAction::kKeyStroke:
if (CPWL_Edit* pWnd = GetPWLEdit(pPageView)) {
fa.bFieldFull = pWnd->IsTextFull();
-
fa.sValue = pWnd->GetText();
-
if (fa.bFieldFull) {
fa.sChange.clear();
fa.sChangeEx.clear();

View File

@@ -0,0 +1,236 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Fri, 19 May 2023 18:41:31 +0000
Subject: Always check return code from CPWL_ComboBox::SetPopup().
Operation must not continue when false is returned.
Bug: chromium:1444238
Change-Id: Ic8c29653ac185ac80b6248203649ce05d0e10f06
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107390
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
(cherry picked from commit 3eb3c4d77d4f9372f77aa4895b85a1d4e4755c89)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107812
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
index 4d834e698ee1b08bcc81d20e062e029620438b7e..fdcc2ef1b2fba4257aab3835f58c5ec0913663cf 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -400,7 +400,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
// options.
switch (nChar) {
case pdfium::ascii::kReturn:
- SetPopup(!IsPopup());
+ if (!SetPopup(!IsPopup())) {
+ return false;
+ }
SetSelectText();
return true;
case pdfium::ascii::kSpace:
@@ -408,7 +410,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
// editable
if (!HasFlag(PCBS_ALLOWCUSTOMTEXT)) {
if (!IsPopup()) {
- SetPopup(/*bPopUp=*/true);
+ if (!SetPopup(/*bPopUp=*/true)) {
+ return false;
+ }
SetSelectText();
}
return true;
@@ -438,7 +442,7 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
if (child == m_pButton) {
- SetPopup(!m_bPopup);
+ (void)SetPopup(!m_bPopup);
// Note, |this| may no longer be viable at this point. If more work needs to
// be done, check the return value of SetPopup().
}
@@ -451,7 +455,7 @@ void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
SetSelectText();
SelectAllText();
m_pEdit->SetFocus();
- SetPopup(false);
+ (void)SetPopup(false);
// Note, |this| may no longer be viable at this point. If more work needs to
// be done, check the return value of SetPopup().
}
diff --git a/fpdfsdk/pwl/cpwl_combo_box.h b/fpdfsdk/pwl/cpwl_combo_box.h
index 0d13b40b7a1fa1410070a14a3f9f4ef5ad625181..4b97394996d0fb1212e8f7e54f3513e1e93b6b80 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.h
+++ b/fpdfsdk/pwl/cpwl_combo_box.h
@@ -64,7 +64,7 @@ class CPWL_ComboBox final : public CPWL_Wnd {
void CreateListBox(const CreateParams& cp);
// Returns |true| iff this instance is still allocated.
- bool SetPopup(bool bPopup);
+ [[nodiscard]] bool SetPopup(bool bPopup);
UnownedPtr<CPWL_Edit> m_pEdit;
UnownedPtr<CPWL_CBButton> m_pButton;
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.evt b/testing/resources/javascript/xfa_specific/bug_1444238.evt
new file mode 100644
index 0000000000000000000000000000000000000000..adca35aa0d756e76eb395c5d60ba41b86c3d0090
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.evt
@@ -0,0 +1,3 @@
+mousedown,left,91,539
+mouseup,left,91,539
+charcode,32
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.in b/testing/resources/javascript/xfa_specific/bug_1444238.in
new file mode 100644
index 0000000000000000000000000000000000000000..675178c9446b0181c3633a4b5c9bc664bb4c127d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.in
@@ -0,0 +1,149 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm 4 0 R
+ /OpenAction 40 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 2
+ /Kids [
+ 32 0 R
+ 34 0 R
+ ]
+>>
+endobj
+% Forms
+{{object 4 0}} <<
+ /XFA 43 0 R
+ /Fields [
+ 10 0 R
+ 11 0 R
+ ]
+>>
+endobj
+% Fields
+{{object 10 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Tx
+ /T (MyField5)
+ /V (myfield_5)
+ /Rect [0 500 600 600]
+>>
+% Fields
+{{object 11 0}} <<
+ /T (MyField3)
+ /Parent 4 0 R
+ /Kids [12 0 R]
+ /Opt [(a) (b) (c) (d)]
+ /V [(a) (b) (c)]
+>>
+endobj
+% Fields
+{{object 12 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Ch
+ /Ff 131072
+ /Parent 11 0 R
+ /Kids [13 0 R]
+>>
+endobj
+% Fields
+{{object 13 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /Parent 12 0 R
+ /Rect [0 400 600 600]
+>>
+endobj
+% Fields
+{{object 14 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /Parent 12 0 R
+ /Rect [100 400 500 500]
+>>
+endobj
+% Page number 2.
+{{object 32 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [13 0 R]
+
+>>
+endobj
+{{object 34 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [10 0 R]
+>>
+endobj
+% Document JS Action
+{{object 40 0}} <<
+ /Type /Action
+ /S /JavaScript
+ /JS 41 0 R
+>>
+endobj
+% JS program to exexute
+{{object 41 0}} <<
+>>
+stream
+var f5 = this.getField("MyField5");
+var f3 = this.getField("MyField3");
+f3.setFocus();
+this.__defineGetter__("pageNum",function o(){f5.setFocus(); f3.borderStyle="dashed"; f3.setFocus();});
+endstream
+endobj
+{{object 43 0}} <<
+ {{streamlen}}
+>>
+stream
+<?xml version="1.0" encoding="UTF-8"?>
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+<config></config>
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.8/">
+ <subform layout="tb" locale="en_US">
+ <pageSet>
+ <pageArea id="Page1" name="Page1">
+ <contentArea h="268.939mm" w="203.2mm" x="6.35mm" y="6.35mm"/>
+ <medium long="792pt" short="612pt" stock="default"/>
+ </pageArea>
+ </pageSet>
+ <field h="9.0001mm" name="MyField3" w="47.625mm" x="120mm" y="120mm">
+ <ui>
+ <choiceList open="onEntry">
+ <border>
+ <edge/>
+ </border>
+ </choiceList>
+ </ui>
+ <items save="1">
+ <text>apples</text>
+ <text>bananas</text>
+ <text>pears</text>
+ </items>
+ <value>
+ <text>apples</text>
+ </value>
+ <event activity="preOpen">
+ <script contentType="application/x-javascript">
+ var aa = this.pageNum;
+ </script>
+ </event>
+ </field>
+ </subform>
+</template>
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF

View File

@@ -0,0 +1,213 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Fri, 19 May 2023 20:05:10 +0000
Subject: Observe CPWL_ComboBox across all On* methods
Bug: chromium:1445426
Change-Id: I1d7ebf66fe170ca016c27a0df3ac4574e75c763c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107650
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
(cherry picked from commit 29c665ea4c61b089746c3f502c30fcb5f4b11486)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107811
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
index 6f89e7df41ea6691e805a4dd3942d5cb89787db3..4d834e698ee1b08bcc81d20e062e029620438b7e 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -339,31 +339,42 @@ bool CPWL_ComboBox::OnKeyDown(FWL_VKEYCODE nKeyCode,
if (!m_pEdit)
return false;
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
m_nSelectItem = -1;
switch (nKeyCode) {
case FWL_VKEY_Up:
if (m_pList->GetCurSel() > 0) {
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
+ }
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
+ }
if (m_pList->IsMovementKey(nKeyCode)) {
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
return false;
+ }
SetSelectText();
}
}
return true;
case FWL_VKEY_Down:
if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
+ }
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
+ }
if (m_pList->IsMovementKey(nKeyCode)) {
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
return false;
+ }
SetSelectText();
}
}
@@ -411,10 +422,15 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
return m_pEdit->OnChar(nChar, nFlag);
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
+ }
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
+ }
if (!m_pList->IsChar(nChar, nFlag))
return false;
return m_pList->OnCharNotify(nChar, nFlag);
diff --git a/testing/resources/javascript/bug_1445426.evt b/testing/resources/javascript/bug_1445426.evt
new file mode 100644
index 0000000000000000000000000000000000000000..265e85b0471b33509568238ccae30d2395b4b4ab
--- /dev/null
+++ b/testing/resources/javascript/bug_1445426.evt
@@ -0,0 +1,3 @@
+mousedown,left,202,697
+mouseup,left,202,697
+keycode,40
diff --git a/testing/resources/javascript/bug_1445426.in b/testing/resources/javascript/bug_1445426.in
new file mode 100644
index 0000000000000000000000000000000000000000..1483da72f5759e9f2c8fdb538d5c6fa0cd1611c5
--- /dev/null
+++ b/testing/resources/javascript/bug_1445426.in
@@ -0,0 +1,114 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm 4 0 R
+ /OpenAction 40 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 2
+ /Kids [
+ 32 0 R
+ 34 0 R
+ ]
+>>
+endobj
+% Forms
+{{object 4 0}} <<
+ /Fields [
+ 10 0 R
+ 11 0 R
+ ]
+>>
+endobj
+% Fields
+{{object 10 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Tx
+ /T (Field_TextEdit)
+ /Rect [0 0 612 792]
+>>
+{{object 11 0}} <<
+ /T (Field_ComboBox)
+ /Parent 4 0 R
+ /Kids [12 0 R]
+ /Opt [(a) (b) (c) (d)]
+ /V [(a)]
+>>
+endobj
+{{object 12 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Ch
+ /Ff 131072
+ /Parent 11 0 R
+ /Kids [13 0 R]
+>>
+endobj
+{{object 13 0}} <<
+ /Parent 12 0 R
+ /Type /Annot
+ /Subtype /Widget
+ /Rect [0 0 612 792]
+ /AA << /K 20 0 R >>
+>>
+endobj
+% Pages
+{{object 32 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [13 0 R]
+
+>>
+endobj
+{{object 34 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [10 0 R]
+>>
+endobj
+% Document JS Action
+{{object 40 0}} <<
+ /Type /Action
+ /S /JavaScript
+ /JS 41 0 R
+>>
+endobj
+% JS program to exexute
+{{object 41 0}} <<
+ {{streamlen}}
+>>
+stream
+var field_text = this.getField("Field_TextEdit");
+var field_combobox = this.getField("Field_ComboBox");
+field_combobox.setFocus();
+this.__defineGetter__("filesize", function new_getter(){
+ field_text.setFocus();
+ field_combobox.borderStyle="dashed";
+ field_combobox.setFocus();
+ });
+endstream
+endobj
+% OpenAction action
+{{object 20 0}} <<
+ /S /JavaScript
+ /JS 21 0 R
+>>
+endobj
+% JS program to exexute
+{{object 21 0}} <<
+ {{streamlen}}
+>>
+stream
+var t = this.filesize;
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Thu, 18 May 2023 18:37:17 +0000
Subject: Observe widget across SetOptionSelection() calls.
Call may re-enter JavaScript.
Bug: chromium:1444581
Change-Id: Id7a2f17b3b81f822ca8f4496ac08c19b7794c48a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107394
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
(cherry picked from commit a9ff918a86d700c3bdf9b5820faed35490c0cd25)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107735
Auto-Submit: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
index 4bb100014c804adcfc7f1f2023cd1870f81c85e8..6fe5d91a2472a7aaadf13399b4e6075c2a9617c7 100644
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
@@ -116,11 +116,18 @@ void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
}
if (m_pWidget->GetFieldFlags() & pdfium::form_flags::kChoiceMultiSelect) {
for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
- if (pListBox->IsItemSelected(i))
+ if (pListBox->IsItemSelected(i)) {
m_pWidget->SetOptionSelection(i);
+ if (!observed_box) {
+ return;
+ }
+ }
}
} else {
m_pWidget->SetOptionSelection(pListBox->GetCurSel());
+ if (!observed_box) {
+ return;
+ }
}
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget.Get());
ObservedPtr<CFFL_ListBox> observed_this(this);

2
patches/skia/.patches Normal file
View File

@@ -0,0 +1,2 @@
enforce_program_stack_limits_on_function_parameters.patch
enforce_size_limits_on_struct_and_array_declarations.patch

View File

@@ -0,0 +1,152 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Stiles <johnstiles@google.com>
Date: Wed, 12 Apr 2023 14:56:54 -0400
Subject: Enforce program stack limits on function parameters.
M108 merge issues:
resources/sksl/BUILD.bazel:
File doesn't exist in M108, tests are added manually to gn/sksl_tests.gni.
gn/sksl_tests.gni:
Conflicting rts entries
src/sksl/ir/SkSLFunctionDefinition.cpp:
- Conflicting includes
- visitStatement():
Conflicting declarations of const Variable* var (const Variable& var
on 108)
Previously, a function's parameter list did not count against its
stack size limit.
Bug: chromium:1432603
Change-Id: If49dce98f3155f3144a766c26b5a3a39401ce1b2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/670236
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
(cherry picked from commit 4dc748f14c6650cb45c7086a39af1760bfda41d2)
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index 2f0100b8b617d3d101660a34c183bcf51a39c11c..6af1a84c6ef8a8853b259815eb17e02cb5027541 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -283,6 +283,7 @@ sksl_error_tests = [
"/sksl/errors/VoidInStruct.rts",
"/sksl/errors/VoidVariable.rts",
"/sksl/errors/WhileTypeMismatch.sksl",
+ "/sksl/errors/ProgramTooLarge_Parameters.rts",
]
sksl_glsl_tests = [
diff --git a/resources/sksl/errors/ProgramTooLarge_Parameters.rts b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
new file mode 100644
index 0000000000000000000000000000000000000000..cced977be40620ffc3b145837bd5ffe16b40295b
--- /dev/null
+++ b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
@@ -0,0 +1,14 @@
+struct S {
+ half4 ah4[1];
+ half ah[99999];
+ half4 h4;
+ half h;
+};
+
+void func(int small,
+ S big_chungus,
+ S no_report /*we don't need to report overflows past the first*/) {}
+
+/*%%*
+variable 'big_chungus' exceeds the stack size limit
+*%%*/
diff --git a/src/sksl/ir/SkSLFunctionDefinition.cpp b/src/sksl/ir/SkSLFunctionDefinition.cpp
index 45695a1effe1f98d4185aa4c17d6add29281044c..adfe62dfd22e2810c316cd806aaef16a05aca4ad 100644
--- a/src/sksl/ir/SkSLFunctionDefinition.cpp
+++ b/src/sksl/ir/SkSLFunctionDefinition.cpp
@@ -37,6 +37,7 @@
#include <forward_list>
#include <string_view>
#include <type_traits>
+#include <vector>
namespace SkSL {
@@ -88,9 +89,29 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
bool builtin) {
class Finalizer : public ProgramWriter {
public:
- Finalizer(const Context& context, const FunctionDeclaration& function)
+ Finalizer(const Context& context, const FunctionDeclaration& function, Position pos)
: fContext(context)
- , fFunction(function) {}
+ , fFunction(function) {
+ // Function parameters count as local variables.
+ for (const Variable* var : function.parameters()) {
+ this->addLocalVariable(var, pos);
+ }
+ }
+
+ void addLocalVariable(const Variable* var, Position pos) {
+ // We count the number of slots used, but don't consider the precision of the base type.
+ // In practice, this reflects what GPUs actually do pretty well. (i.e., RelaxedPrecision
+ // math doesn't mean your variable takes less space.) We also don't attempt to reclaim
+ // slots at the end of a Block.
+ size_t prevSlotsUsed = fSlotsUsed;
+ fSlotsUsed = SkSafeMath::Add(fSlotsUsed, var->type().slotCount());
+ // To avoid overzealous error reporting, only trigger the error at the first
+ // place where the stack limit is exceeded.
+ if (prevSlotsUsed < kVariableSlotLimit && fSlotsUsed >= kVariableSlotLimit) {
+ fContext.fErrors->error(pos, "variable '" + std::string(var->name()) +
+ "' exceeds the stack size limit");
+ }
+ }
~Finalizer() override {
SkASSERT(fBreakableLevel == 0);
@@ -109,24 +130,12 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
bool visitStatement(Statement& stmt) override {
switch (stmt.kind()) {
case Statement::Kind::kVarDeclaration: {
- // We count the number of slots used, but don't consider the precision of the
- // base type. In practice, this reflects what GPUs really do pretty well.
- // (i.e., RelaxedPrecision math doesn't mean your variable takes less space.)
- // We also don't attempt to reclaim slots at the end of a Block.
- size_t prevSlotsUsed = fSlotsUsed;
const Variable& var = stmt.as<VarDeclaration>().var();
if (var.type().isOrContainsUnsizedArray()) {
fContext.fErrors->error(stmt.fPosition,
"unsized arrays are not permitted here");
- break;
- }
- fSlotsUsed = SkSafeMath::Add(fSlotsUsed, var.type().slotCount());
- // To avoid overzealous error reporting, only trigger the error at the first
- // place where the stack limit is exceeded.
- if (prevSlotsUsed < kVariableSlotLimit && fSlotsUsed >= kVariableSlotLimit) {
- fContext.fErrors->error(stmt.fPosition,
- "variable '" + std::string(var.name()) +
- "' exceeds the stack size limit");
+ } else {
+ this->addLocalVariable(&var, stmt.fPosition);
}
break;
}
@@ -219,7 +228,7 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
using INHERITED = ProgramWriter;
};
- Finalizer(context, function).visitStatement(*body);
+ Finalizer(context, function, pos).visitStatement(*body);
if (function.isMain() && ProgramConfig::IsVertex(context.fConfig->fKind)) {
append_rtadjust_fixup_to_vertex_main(context, function, body->as<Block>());
}
diff --git a/tests/sksl/errors/ProgramTooLarge_Parameters.glsl b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..d92c3256e82d52115621cf96d6dba99f62cdd945
--- /dev/null
+++ b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
@@ -0,0 +1,6 @@
+### Compilation failed:
+
+error: 10: variable 'big_chungus' exceeds the stack size limit
+ S no_report /*we don't need to report overflows past the first*/) {}
+ ^^
+1 error

View File

@@ -0,0 +1,291 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Stiles <johnstiles@google.com>
Date: Thu, 13 Apr 2023 17:58:24 -0400
Subject: Enforce size limits on struct and array declarations.
M108 merge issues:
resources/sksl/BUILD.bazel:
File doesn't exist in M108, tests are added manually to gn/sksl_tests.gni.
gn/sksl_tests.gni:
Conflicting rts entries
tests/sksl/shared/Ossfuzz37900.*
Not present in 108, skipped.
src/sksl/ir/SkSLType.cpp:
- Conflicting includes
- MakeStructType():
- Conflicting function signature
- context isn't a parameter, used ThreadContext::Context() directly.
This improves error reporting by more clearly attaching the error
message to the oversized type.
Bug: chromium:1432603
Change-Id: I26511f08aff22072cf4913abf7be2c49940a732c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/671377
Commit-Queue: John Stiles <johnstiles@google.com>
(cherry picked from commit 1cbd33ecd73523f8d4bf88e9c5576303b39e5556)
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index 6af1a84c6ef8a8853b259815eb17e02cb5027541..20c2026322bf6f6ae6d19d4f649ddb0f5ed048ed 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -284,6 +284,7 @@ sksl_error_tests = [
"/sksl/errors/VoidVariable.rts",
"/sksl/errors/WhileTypeMismatch.sksl",
"/sksl/errors/ProgramTooLarge_Parameters.rts",
+ "/sksl/errors/ProgramTooLarge_Struct.rts",
]
sksl_glsl_tests = [
diff --git a/resources/sksl/errors/ProgramTooLarge_Globals.rts b/resources/sksl/errors/ProgramTooLarge_Globals.rts
index af0ad17ce7a591d99a9cbb062278b99046bd2fe8..ee2556bb1a99404ebe53641064bceff3a553ea9a 100644
--- a/resources/sksl/errors/ProgramTooLarge_Globals.rts
+++ b/resources/sksl/errors/ProgramTooLarge_Globals.rts
@@ -6,11 +6,10 @@ struct S {
};
int small;
-S medium;
-S large[10];
-S extra_large[100];
-S xxl[50000];
-
+S medium[30];
+S large[50];
+S extra_large[70];
+S xxl[90];
/*%%*
global variable 'extra_large' exceeds the size limit
diff --git a/resources/sksl/errors/ProgramTooLarge_Parameters.rts b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
index cced977be40620ffc3b145837bd5ffe16b40295b..4e15ebd53e683f2078efed6771202e61d7b7bdc5 100644
--- a/resources/sksl/errors/ProgramTooLarge_Parameters.rts
+++ b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
@@ -1,11 +1,14 @@
struct S {
half4 ah4[1];
- half ah[99999];
+ half ah[99990];
half4 h4;
half h;
};
void func(int small,
+ int parameters,
+ int are,
+ int allowed,
S big_chungus,
S no_report /*we don't need to report overflows past the first*/) {}
diff --git a/resources/sksl/errors/ProgramTooLarge_Stack.rts b/resources/sksl/errors/ProgramTooLarge_Stack.rts
index 4f004368a17b79d960e5cc142db35d82fb627cbd..a8f5217359ad9dab1fdcfcaac862938c1d205f0a 100644
--- a/resources/sksl/errors/ProgramTooLarge_Stack.rts
+++ b/resources/sksl/errors/ProgramTooLarge_Stack.rts
@@ -1,12 +1,12 @@
struct S {
half4 ah4[1];
- half ah[99999];
+ half ah[99990];
half4 h4;
half h;
};
void func() {
- int small;
+ int small, variables, are, allowed;
S big_chungus;
S no_report; // we don't need to report overflows past the first
}
diff --git a/resources/sksl/errors/ProgramTooLarge_Struct.rts b/resources/sksl/errors/ProgramTooLarge_Struct.rts
new file mode 100644
index 0000000000000000000000000000000000000000..690e1d37311b5d0745d20d71b48738a69c5c3ecb
--- /dev/null
+++ b/resources/sksl/errors/ProgramTooLarge_Struct.rts
@@ -0,0 +1,24 @@
+struct A {
+ int4 big[25001]; // 100,004 slots
+};
+
+struct B {
+ int4 a[12500]; // 50,000 slots
+ int b[49999]; // 99,999 slots
+ int c; // 100,000 slots
+};
+
+struct C {
+ int a[99999]; // 99,999 slots (safe)
+};
+
+struct D {
+ C a; // 99,999 slots
+ int b; // 100,000 slots
+};
+
+/*%%*
+array size is too large
+struct is too large
+struct is too large
+*%%*/
diff --git a/src/sksl/dsl/DSLType.cpp b/src/sksl/dsl/DSLType.cpp
index 5648c51c92b61430d31497f71cea73ff19ef8a97..aacdfb000527105ea4fff8b6dc3ba2c38d0e33f4 100644
--- a/src/sksl/dsl/DSLType.cpp
+++ b/src/sksl/dsl/DSLType.cpp
@@ -266,7 +266,7 @@ DSLExpression DSLType::Construct(DSLType type, SkSpan<DSLExpression> argArray) {
DSLType Array(const DSLType& base, int count, Position pos) {
count = base.skslType().convertArraySize(ThreadContext::Context(), pos,
- DSLExpression(count, pos).release());
+ DSLExpression(count, pos).release());
if (!count) {
return DSLType(kPoison_Type);
}
@@ -278,7 +278,7 @@ DSLType UnsizedArray(const DSLType& base, Position pos) {
return DSLType(kPoison_Type);
}
return ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(),
- SkSL::Type::kUnsizedArray);
+ SkSL::Type::kUnsizedArray);
}
DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos) {
diff --git a/src/sksl/ir/SkSLType.cpp b/src/sksl/ir/SkSLType.cpp
index 04c1946509ee263ca1c591cab6353765a84a28d0..c474db149f5e4844cc873b1746a0b103f209390f 100644
--- a/src/sksl/ir/SkSLType.cpp
+++ b/src/sksl/ir/SkSLType.cpp
@@ -12,10 +12,12 @@
#include "include/private/SkTFitsIn.h"
#include "include/sksl/SkSLErrorReporter.h"
#include "src/core/SkMathPriv.h"
+#include "src/core/SkSafeMath.h"
#include "src/sksl/SkSLBuiltinTypes.h"
#include "src/sksl/SkSLConstantFolder.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLProgramSettings.h"
+#include "src/sksl/SkSLThreadContext.h"
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLConstructorCompoundCast.h"
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
@@ -648,6 +650,17 @@ std::unique_ptr<Type> Type::MakeScalarType(std::string_view name, const char* ab
std::unique_ptr<Type> Type::MakeStructType(Position pos, std::string_view name,
std::vector<Field> fields, bool interfaceBlock) {
+ size_t slots = 0;
+ for (const Field& field : fields) {
+ if (field.fType->isUnsizedArray()) {
+ continue;
+ }
+ slots = SkSafeMath::Add(slots, field.fType->slotCount());
+ if (slots >= kVariableSlotLimit) {
+ ThreadContext::Context().fErrors->error(pos, "struct is too large");
+ break;
+ }
+ }
return std::make_unique<StructType>(pos, name, std::move(fields), interfaceBlock);
}
@@ -1120,8 +1133,9 @@ bool Type::checkIfUsableInArray(const Context& context, Position arrayPos) const
return true;
}
-SKSL_INT Type::convertArraySize(const Context& context, Position arrayPos,
- std::unique_ptr<Expression> size) const {
+SKSL_INT Type::convertArraySize(const Context& context,
+ Position arrayPos,
+ std::unique_ptr<Expression> size) const {
size = context.fTypes.fInt->coerceExpression(std::move(size), context);
if (!size) {
return 0;
@@ -1138,7 +1152,7 @@ SKSL_INT Type::convertArraySize(const Context& context, Position arrayPos,
context.fErrors->error(size->fPosition, "array size must be positive");
return 0;
}
- if (!SkTFitsIn<int32_t>(count)) {
+ if (SkSafeMath::Mul(this->slotCount(), count) > kVariableSlotLimit) {
context.fErrors->error(size->fPosition, "array size is too large");
return 0;
}
diff --git a/tests/sksl/errors/ProgramTooLarge_Globals.glsl b/tests/sksl/errors/ProgramTooLarge_Globals.glsl
index 406949ad38ecb6ea80bbba505cdf5ad9346c9446..ccb7706c3a66a7b41fd5c6444ea1e9967f314282 100644
--- a/tests/sksl/errors/ProgramTooLarge_Globals.glsl
+++ b/tests/sksl/errors/ProgramTooLarge_Globals.glsl
@@ -1,6 +1,6 @@
### Compilation failed:
error: 11: global variable 'extra_large' exceeds the size limit
-S extra_large[100];
-^^^^^^^^^^^^^^^^^^
+S extra_large[70];
+^^^^^^^^^^^^^^^^^
1 error
diff --git a/tests/sksl/errors/ProgramTooLarge_Parameters.glsl b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
index d92c3256e82d52115621cf96d6dba99f62cdd945..3ece6f379c8ab64dd846d856301217f95eb3e7ff 100644
--- a/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
+++ b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
@@ -1,6 +1,6 @@
### Compilation failed:
-error: 10: variable 'big_chungus' exceeds the stack size limit
+error: 13: variable 'big_chungus' exceeds the stack size limit
S no_report /*we don't need to report overflows past the first*/) {}
^^
1 error
diff --git a/tests/sksl/errors/ProgramTooLarge_Struct.glsl b/tests/sksl/errors/ProgramTooLarge_Struct.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..ebe47f700dfad807fbd7b774f5f2ce851ff28e64
--- /dev/null
+++ b/tests/sksl/errors/ProgramTooLarge_Struct.glsl
@@ -0,0 +1,12 @@
+### Compilation failed:
+
+error: 2: array size is too large
+ int4 big[25001]; // 100,004 slots
+ ^^^^^^^^^^^^^^^
+error: 5: struct is too large
+struct B {
+^^^^^^^^^^...
+error: 15: struct is too large
+struct D {
+^^^^^^^^^^...
+3 errors
diff --git a/tests/sksl/shared/Ossfuzz37900.asm.frag b/tests/sksl/shared/Ossfuzz37900.asm.frag
index 9751821fc01e704a2f2851c52d1e9489b204c4f7..5fb2b3c5fd467857b653f617976cc3b8af3a15fb 100644
--- a/tests/sksl/shared/Ossfuzz37900.asm.frag
+++ b/tests/sksl/shared/Ossfuzz37900.asm.frag
@@ -1,6 +1,6 @@
### Compilation failed:
-error: 2: variable 'a' exceeds the stack size limit
+error: 2: array size is too large
int[2147483646] a, b=a, c=a, d=a, e=a, f=a, g=a, h=a, i=a, j=a, k=a;
- ^^^^^^^^^^^^^^^^^
+ ^^^^^^^^^^^^^^^
1 error
diff --git a/tests/sksl/shared/Ossfuzz37900.glsl b/tests/sksl/shared/Ossfuzz37900.glsl
index 9751821fc01e704a2f2851c52d1e9489b204c4f7..5fb2b3c5fd467857b653f617976cc3b8af3a15fb 100644
--- a/tests/sksl/shared/Ossfuzz37900.glsl
+++ b/tests/sksl/shared/Ossfuzz37900.glsl
@@ -1,6 +1,6 @@
### Compilation failed:
-error: 2: variable 'a' exceeds the stack size limit
+error: 2: array size is too large
int[2147483646] a, b=a, c=a, d=a, e=a, f=a, g=a, h=a, i=a, j=a, k=a;
- ^^^^^^^^^^^^^^^^^
+ ^^^^^^^^^^^^^^^
1 error
diff --git a/tests/sksl/shared/Ossfuzz37900.metal b/tests/sksl/shared/Ossfuzz37900.metal
index 9751821fc01e704a2f2851c52d1e9489b204c4f7..5fb2b3c5fd467857b653f617976cc3b8af3a15fb 100644
--- a/tests/sksl/shared/Ossfuzz37900.metal
+++ b/tests/sksl/shared/Ossfuzz37900.metal
@@ -1,6 +1,6 @@
### Compilation failed:
-error: 2: variable 'a' exceeds the stack size limit
+error: 2: array size is too large
int[2147483646] a, b=a, c=a, d=a, e=a, f=a, g=a, h=a, i=a, j=a, k=a;
- ^^^^^^^^^^^^^^^^^
+ ^^^^^^^^^^^^^^^
1 error

View File

@@ -10,5 +10,18 @@ revert_runtime_dhceck_terminating_exception_in_microtasks.patch
chore_disable_is_execution_terminating_dcheck.patch
force_cppheapcreateparams_to_be_noncopyable.patch
cherry-pick-e17eee4894be.patch
cherry-pick-aeceeb2187a6.patch
cherry-pick-546e00df97ac.patch
cherry-pick-f6ddbf42b1ea.patch
cherry-pick-c605df24af3c.patch
cherry-pick-f4b66ae451c2.patch
cherry-pick-3b0607d14060.patch
cherry-pick-9c6dfc733fce.patch
merged_ic_fix_store_handler_selection_for_arguments_objects.patch
cherry-pick-73af1a19a901.patch
merged_regexp_fix_clobbered_register_in_global_unicode_special.patch
m108-lts_api_fix_v8_object_setaccessorproperty.patch
cherry-pick-2e76270cf65e.patch
utf-8_q_shared-struct_20fix_20using_20shared_20objects_20as.patch
merged_runtime_set_instance_prototypes_directly_on_maps.patch
merged_compiler_stackcheck_can_have_side_effects.patch

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Mon, 5 Jun 2023 16:05:52 -0700
Subject: Merged: Check for encoding when appending in string builder
Fixed: chromium:1450114
(cherry picked from commit a7e2bef27b72f187a7dcdf95714df686f56d9e0b)
Change-Id: I5838383b6b12d137e84c8a36863ef88000e85c76
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4604652
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#41}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/strings/string-builder.cc b/src/strings/string-builder.cc
index 9d1e3a95746b47b99c15f18ec593549d79e10b8c..c7e98e55763aba2d64f4070e25759489f850f589 100644
--- a/src/strings/string-builder.cc
+++ b/src/strings/string-builder.cc
@@ -306,12 +306,21 @@ bool IncrementalStringBuilder::CanAppendByCopy(Handle<String> string) {
void IncrementalStringBuilder::AppendStringByCopy(Handle<String> string) {
DCHECK(CanAppendByCopy(string));
- Handle<SeqOneByteString> part =
- Handle<SeqOneByteString>::cast(current_part());
{
DisallowGarbageCollection no_gc;
- String::WriteToFlat(*string, part->GetChars(no_gc) + current_index_, 0,
- string->length());
+ if (encoding_ == String::ONE_BYTE_ENCODING) {
+ String::WriteToFlat(
+ *string,
+ Handle<SeqOneByteString>::cast(current_part())->GetChars(no_gc) +
+ current_index_,
+ 0, string->length());
+ } else {
+ String::WriteToFlat(
+ *string,
+ Handle<SeqTwoByteString>::cast(current_part())->GetChars(no_gc) +
+ current_index_,
+ 0, string->length());
+ }
}
current_index_ += string->length();
DCHECK(current_index_ <= part_length_);

View File

@@ -0,0 +1,186 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Wed, 17 May 2023 13:47:36 +0200
Subject: Merged: [runtime] Remove redundant calls to GetPropertyAttributes
... when defining properties in favour of CheckIfCanDefine.
Drive-by: move JSReceiver::CheckIfCanDefine to
JSObject::CheckIfCanDefineAsConfigurable and fix handling of
absent properties.
Bug: chromium:1443452
(cherry picked from commit e98baa3526426c0219bb0474028ca301b8bd0677)
Change-Id: Ia1fd617778be608accee99dcee37f7d1ce3460b8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545762
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#22}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index fff21e90bad3451e2d942ec327cb02f394fecc46..32039f9888d3cb54699c6aefd0bcc3573044995e 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -1812,14 +1812,14 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
// been thrown if the private field already exists in the object.
if (IsAnyDefineOwn() && !name->IsPrivateName() && !object->IsJSProxy() &&
!Handle<JSObject>::cast(object)->HasNamedInterceptor()) {
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
isolate(), &it, value, Nothing<ShouldThrow>());
MAYBE_RETURN_NULL(can_define);
if (!can_define.FromJust()) {
return isolate()->factory()->undefined_value();
}
- // Restart the lookup iterator updated by CheckIfCanDefine() for
- // UpdateCaches() to handle access checks.
+ // Restart the lookup iterator updated by CheckIfCanDefineAsConfigurable()
+ // for UpdateCaches() to handle access checks.
if (use_ic && object->IsAccessCheckNeeded()) {
it.Restart();
}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 15356b6c58d2f7355fa8b0dce4d3ea779a2884f9..e86fdec6a57e08bbcd229b7866f22ba3441f608c 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -243,27 +243,6 @@ Maybe<bool> JSReceiver::CheckPrivateNameStore(LookupIterator* it,
return Just(true);
}
-// static
-Maybe<bool> JSReceiver::CheckIfCanDefine(Isolate* isolate, LookupIterator* it,
- Handle<Object> value,
- Maybe<ShouldThrow> should_throw) {
- if (it->IsFound()) {
- Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
- MAYBE_RETURN(attributes, Nothing<bool>());
- if ((attributes.FromJust() & DONT_DELETE) != 0) {
- RETURN_FAILURE(
- isolate, GetShouldThrow(isolate, should_throw),
- NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
- }
- } else if (!JSObject::IsExtensible(
- Handle<JSObject>::cast(it->GetReceiver()))) {
- RETURN_FAILURE(
- isolate, GetShouldThrow(isolate, should_throw),
- NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
- }
- return Just(true);
-}
-
namespace {
bool HasExcludedProperty(
@@ -3639,7 +3618,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
if (semantics == EnforceDefineSemantics::kDefine) {
it->Restart();
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
it->isolate(), it, value, should_throw);
if (can_define.IsNothing() || !can_define.FromJust()) {
return can_define;
@@ -4068,17 +4047,16 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
Handle<Object> value,
Maybe<ShouldThrow> should_throw) {
DCHECK(it->GetReceiver()->IsJSObject());
- MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
Isolate* isolate = receiver->GetIsolate();
- Maybe<bool> can_define =
- JSReceiver::CheckIfCanDefine(isolate, it, value, should_throw);
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
+ isolate, it, value, should_throw);
if (can_define.IsNothing() || !can_define.FromJust()) {
return can_define;
}
- RETURN_ON_EXCEPTION_VALUE(it->isolate(),
+ RETURN_ON_EXCEPTION_VALUE(isolate,
DefineOwnPropertyIgnoreAttributes(it, value, NONE),
Nothing<bool>());
@@ -4707,19 +4685,42 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
return it.factory()->undefined_value();
}
- CHECK(GetPropertyAttributes(&it).IsJust());
-
- // ES5 forbids turning a property into an accessor if it's not
- // configurable. See 8.6.1 (Table 5).
- if (it.IsFound() && !it.IsConfigurable()) {
- return it.factory()->undefined_value();
- }
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
+ isolate, &it, info, Nothing<ShouldThrow>());
+ MAYBE_RETURN_NULL(can_define);
+ if (!can_define.FromJust()) return it.factory()->undefined_value();
it.TransitionToAccessorPair(info, attributes);
return object;
}
+// static
+Maybe<bool> JSObject::CheckIfCanDefineAsConfigurable(
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
+ Maybe<ShouldThrow> should_throw) {
+ DCHECK(it->GetReceiver()->IsJSObject());
+ if (it->IsFound()) {
+ Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
+ MAYBE_RETURN(attributes, Nothing<bool>());
+ if (attributes.FromJust() != ABSENT) {
+ if ((attributes.FromJust() & DONT_DELETE) != 0) {
+ RETURN_FAILURE(
+ isolate, GetShouldThrow(isolate, should_throw),
+ NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
+ }
+ return Just(true);
+ }
+ // Property does not exist, check object extensibility.
+ }
+ if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
+ RETURN_FAILURE(
+ isolate, GetShouldThrow(isolate, should_throw),
+ NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
+ }
+ return Just(true);
+}
+
Object JSObject::SlowReverseLookup(Object value) {
if (HasFastProperties()) {
DescriptorArray descs = map().instance_descriptors();
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index 06489c2b7bae61ecadbd8f020060e86ef50e11b6..f663af6ed8a445f8ef30a67bac176a1abe6c85f8 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -167,12 +167,6 @@ class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> {
V8_WARN_UNUSED_RESULT static Maybe<bool> CheckPrivateNameStore(
LookupIterator* it, bool is_define);
- // Check if a data property can be created on the object. It will fail with
- // an error when it cannot.
- V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefine(
- Isolate* isolate, LookupIterator* it, Handle<Object> value,
- Maybe<ShouldThrow> should_throw);
-
// ES6 7.3.4 (when passed kDontThrow)
V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key,
@@ -544,6 +538,12 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
PropertyAttributes attributes);
+ // Check if a data property can be created on the object. It will fail with
+ // an error when it cannot.
+ V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefineAsConfigurable(
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
+ Maybe<ShouldThrow> should_throw);
+
// The result must be checked first for exceptions. If there's no exception,
// the output parameter |done| indicates whether the interceptor has a result
// or not.

View File

@@ -0,0 +1,257 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Thu, 1 Jun 2023 10:59:39 +0200
Subject: Merged: [lookup] Robustify LookupIterator against own lookups
... on non-JSReceiver objects.
Bug: chromium:1447430
(cherry picked from commit 515f187ba067ee4a99fdf5198cca2c97abd342fd)
Change-Id: Ib9382d90ce19d6b55ee0b236dd299ded03ade04d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4575069
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#35}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
index 642d83ff070d6b631a755af78627989878f685a2..22960729c64062b9e8a4abaf6b5ed8d44ccaa2de 100644
--- a/src/objects/lookup-inl.h
+++ b/src/objects/lookup-inl.h
@@ -190,7 +190,7 @@ Handle<Name> PropertyKey::GetName(Isolate* isolate) {
}
Handle<Name> LookupIterator::name() const {
- DCHECK(!IsElement(*holder_));
+ DCHECK_IMPLIES(!holder_.is_null(), !IsElement(*holder_));
return name_;
}
@@ -281,6 +281,7 @@ void LookupIterator::UpdateProtector() {
}
InternalIndex LookupIterator::descriptor_number() const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(has_property_);
DCHECK(holder_->HasFastProperties(isolate_));
@@ -288,6 +289,7 @@ InternalIndex LookupIterator::descriptor_number() const {
}
InternalIndex LookupIterator::dictionary_entry() const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(has_property_);
DCHECK(!holder_->HasFastProperties(isolate_));
@@ -302,13 +304,14 @@ LookupIterator::Configuration LookupIterator::ComputeConfiguration(
}
// static
-Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
- Handle<Object> lookup_start_object,
- size_t index) {
+MaybeHandle<JSReceiver> LookupIterator::GetRoot(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration) {
if (lookup_start_object->IsJSReceiver(isolate)) {
return Handle<JSReceiver>::cast(lookup_start_object);
}
- return GetRootForNonJSReceiver(isolate, lookup_start_object, index);
+ return GetRootForNonJSReceiver(isolate, lookup_start_object, index,
+ configuration);
}
template <class T>
diff --git a/src/objects/lookup.cc b/src/objects/lookup.cc
index e08ebaff089f8ab0a1b347f9eb5befd85e3c115b..920d28ffa81798c2e5fe9e15db016501d72728c6 100644
--- a/src/objects/lookup.cc
+++ b/src/objects/lookup.cc
@@ -42,27 +42,20 @@ PropertyKey::PropertyKey(Isolate* isolate, Handle<Object> key, bool* success) {
}
}
-LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
- Handle<Name> name, Handle<Map> transition_map,
- PropertyDetails details, bool has_property)
- : configuration_(DEFAULT),
- state_(TRANSITION),
- has_property_(has_property),
- interceptor_state_(InterceptorState::kUninitialized),
- property_details_(details),
- isolate_(isolate),
- name_(name),
- transition_(transition_map),
- receiver_(receiver),
- lookup_start_object_(receiver),
- index_(kInvalidIndex) {
- holder_ = GetRoot(isolate, lookup_start_object_);
-}
-
template <bool is_element>
void LookupIterator::Start() {
// GetRoot might allocate if lookup_start_object_ is a string.
- holder_ = GetRoot(isolate_, lookup_start_object_, index_);
+ MaybeHandle<JSReceiver> maybe_holder =
+ GetRoot(isolate_, lookup_start_object_, index_, configuration_);
+ if (!maybe_holder.ToHandle(&holder_)) {
+ // This is an attempt to perform an own property lookup on a non-JSReceiver
+ // that doesn't have any properties.
+ DCHECK(!lookup_start_object_->IsJSReceiver());
+ DCHECK(!check_prototype_chain());
+ has_property_ = false;
+ state_ = NOT_FOUND;
+ return;
+ }
{
DisallowGarbageCollection no_gc;
@@ -135,19 +128,27 @@ template void LookupIterator::RestartInternal<true>(InterceptorState);
template void LookupIterator::RestartInternal<false>(InterceptorState);
// static
-Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
- Isolate* isolate, Handle<Object> lookup_start_object, size_t index) {
- // Strings are the only objects with properties (only elements) directly on
- // the wrapper. Hence we can skip generating the wrapper for all other cases.
- if (lookup_start_object->IsString(isolate) &&
- index <
- static_cast<size_t>(String::cast(*lookup_start_object).length())) {
- // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the native
- // context, ensuring that we don't leak it into JS?
- Handle<JSFunction> constructor = isolate->string_function();
- Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
- Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
- return result;
+MaybeHandle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration) {
+ // Strings are the only non-JSReceiver objects with properties (only elements
+ // and 'length') directly on the wrapper. Hence we can skip generating
+ // the wrapper for all other cases.
+ bool own_property_lookup = (configuration & kPrototypeChain) == 0;
+ if (lookup_start_object->IsString(isolate)) {
+ if (own_property_lookup ||
+ index <
+ static_cast<size_t>(String::cast(*lookup_start_object).length())) {
+ // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the
+ // native context, ensuring that we don't leak it into JS?
+ Handle<JSFunction> constructor = isolate->string_function();
+ Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
+ Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
+ return result;
+ }
+ } else if (own_property_lookup) {
+ // Signal that the lookup will not find anything.
+ return {};
}
Handle<HeapObject> root(
lookup_start_object->GetPrototypeChainRootMap(isolate).prototype(isolate),
@@ -903,6 +904,7 @@ Handle<Object> LookupIterator::FetchValue(
}
bool LookupIterator::IsConstFieldValueEqualTo(Object value) const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
@@ -944,6 +946,7 @@ bool LookupIterator::IsConstFieldValueEqualTo(Object value) const {
}
bool LookupIterator::IsConstDictValueEqualTo(Object value) const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(!holder_->HasFastProperties(isolate_));
DCHECK(!holder_->IsJSGlobalObject());
@@ -994,6 +997,7 @@ int LookupIterator::GetAccessorIndex() const {
FieldIndex LookupIterator::GetFieldIndex() const {
DCHECK(has_property_);
+ DCHECK(!holder_.is_null());
DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
DCHECK(!IsElement(*holder_));
@@ -1001,6 +1005,7 @@ FieldIndex LookupIterator::GetFieldIndex() const {
}
Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
return handle(holder->global_dictionary(isolate_, kAcquireLoad)
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
index 67a8bac22e6e29df2d7df36937565e4cc0acde45..78a00d7ca0fab1ab8b2b1e49e3ffb92473b21cc9 100644
--- a/src/objects/lookup.h
+++ b/src/objects/lookup.h
@@ -222,11 +222,6 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Handle<Object> lookup_start_object,
Configuration configuration);
- // For |ForTransitionHandler|.
- LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
- Handle<Map> transition_map, PropertyDetails details,
- bool has_property);
-
static void InternalUpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name);
@@ -286,12 +281,12 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Configuration configuration,
Handle<Name> name);
- static Handle<JSReceiver> GetRootForNonJSReceiver(
- Isolate* isolate, Handle<Object> lookup_start_object,
- size_t index = kInvalidIndex);
- static inline Handle<JSReceiver> GetRoot(Isolate* isolate,
- Handle<Object> lookup_start_object,
- size_t index = kInvalidIndex);
+ static MaybeHandle<JSReceiver> GetRootForNonJSReceiver(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration);
+ static inline MaybeHandle<JSReceiver> GetRoot(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration);
State NotFound(JSReceiver const holder) const;
diff --git a/test/mjsunit/regress/regress-crbug-1447430.js b/test/mjsunit/regress/regress-crbug-1447430.js
new file mode 100644
index 0000000000000000000000000000000000000000..c7bb3e72e3af1b9f8c2fa82faeeb2d813fe6ab3c
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-1447430.js
@@ -0,0 +1,34 @@
+// Copyright 2023 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var s = %CreatePrivateSymbol('x');
+
+(function TestSmi() {
+ function f(o, p) {
+ o[p] = 153;
+ }
+ (1).__proto__[s] = 42;
+ %PrepareFunctionForOptimization(f);
+ assertEquals(f(42, s), undefined);
+}());
+
+(function TestString() {
+ function f(o, p) {
+ o[p] = 153;
+ }
+ ('xyz').__proto__[s] = 42;
+ %PrepareFunctionForOptimization(f);
+ assertEquals(f('abc', s), undefined);
+}());
+
+(function TestSymbol() {
+ function f(o, p) {
+ o[p] = 153;
+ }
+ Symbol('xyz').__proto__[s] = 42;
+ %PrepareFunctionForOptimization(f);
+ assertEquals(f(Symbol('abc'), s), undefined);
+}());

View File

@@ -0,0 +1,150 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Tue, 16 May 2023 16:01:49 +0200
Subject: Merged: [runtime] Fix handling of interceptors
Drive-by: simplify creation of LookupIterator copies.
Bug: chromium:1440695
(cherry picked from commit d125c7329f6e22af4523de3c55de3a22f168acc9)
Change-Id: I58416531b9af3456f53264566ec1eb7457328f94
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545763
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#23}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index e86fdec6a57e08bbcd229b7866f22ba3441f608c..b938d82667498d4ff3505d455a7ed3a299cd5247 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -3629,10 +3629,8 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
// own property without the interceptor.
Isolate* isolate = it->isolate();
Handle<Object> receiver = it->GetReceiver();
- LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
- LookupIterator own_lookup =
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
- : LookupIterator(isolate, receiver, it->name(), c);
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
+ LookupIterator::OWN_SKIP_INTERCEPTOR);
return JSObject::DefineOwnPropertyIgnoreAttributes(
&own_lookup, value, attributes, should_throw, handling, semantics,
store_origin);
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
index ff30fcc4f211f49d244e8431cfdb5cba29484329..642d83ff070d6b631a755af78627989878f685a2 100644
--- a/src/objects/lookup-inl.h
+++ b/src/objects/lookup-inl.h
@@ -130,6 +130,29 @@ PropertyKey::PropertyKey(Isolate* isolate, double index) {
#endif
}
+PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name, size_t index)
+ : name_(name), index_(index) {
+ DCHECK_IMPLIES(index_ == LookupIterator::kInvalidIndex, !name_.is_null());
+#if V8_TARGET_ARCH_32_BIT
+ DCHECK_IMPLIES(index_ != LookupIterator::kInvalidIndex,
+ index_ <= JSObject::kMaxElementIndex);
+#endif
+#if DEBUG
+ if (index_ != LookupIterator::kInvalidIndex && !name_.is_null()) {
+ // If both valid index and name are given then the name is a string
+ // representation of the same index.
+ size_t integer_index;
+ CHECK(name_->AsIntegerIndex(&integer_index));
+ CHECK_EQ(index_, integer_index);
+ } else if (index_ == LookupIterator::kInvalidIndex) {
+ // If only name is given it must not be a string representing an integer
+ // index.
+ size_t integer_index;
+ CHECK(!name_->AsIntegerIndex(&integer_index));
+ }
+#endif
+}
+
PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name) {
if (name->AsIntegerIndex(&index_)) {
name_ = name;
@@ -179,6 +202,10 @@ Handle<Name> LookupIterator::GetName() {
return name_;
}
+PropertyKey LookupIterator::GetKey() const {
+ return PropertyKey(isolate_, name_, index_);
+}
+
bool LookupIterator::IsElement(JSReceiver object) const {
return index_ <= JSObject::kMaxElementIndex ||
(index_ != kInvalidIndex &&
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
index 782a09225c17a92ee8f08d20ede0902613158c27..67a8bac22e6e29df2d7df36937565e4cc0acde45 100644
--- a/src/objects/lookup.h
+++ b/src/objects/lookup.h
@@ -36,6 +36,11 @@ class PropertyKey {
inline Handle<Name> GetName(Isolate* isolate);
private:
+ friend LookupIterator;
+
+ // Shortcut for constructing PropertyKey from an active LookupIterator.
+ inline PropertyKey(Isolate* isolate, Handle<Name> name, size_t index);
+
Handle<Name> name_;
size_t index_;
};
@@ -108,6 +113,9 @@ class V8_EXPORT_PRIVATE LookupIterator final {
return static_cast<uint32_t>(index_);
}
+ // Helper method for creating a copy of of the iterator.
+ inline PropertyKey GetKey() const;
+
// Returns true if this LookupIterator has an index in the range
// [0, size_t::max).
bool IsElement() const { return index_ != kInvalidIndex; }
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index c15ac8656adeaf92773a0c4049f7e903ecd2e07f..a7e1833f730e6e5869cd4925cca6dc908859000c 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -2668,11 +2668,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
// Note, the callers rely on the fact that this code is redoing the full own
// lookup from scratch.
- LookupIterator::Configuration c = LookupIterator::OWN;
- LookupIterator own_lookup =
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
- : LookupIterator(isolate, receiver, it->name(), c);
-
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
+ LookupIterator::OWN);
for (; own_lookup.IsFound(); own_lookup.Next()) {
switch (own_lookup.state()) {
case LookupIterator::ACCESS_CHECK:
@@ -2709,6 +2706,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
MAYBE_RETURN(owned, Nothing<bool>());
if (!owned.FromJust()) {
+ // |own_lookup| might become outdated at this point anyway.
+ own_lookup.Restart();
if (!CheckContextualStoreToJSGlobalObject(&own_lookup,
should_throw)) {
return Nothing<bool>();
diff --git a/test/unittests/api/interceptor-unittest.cc b/test/unittests/api/interceptor-unittest.cc
index 635bf6a0b72f8d49591be333b1314846c9c47269..416f9bd1eb4c59160eb03031e6011ae02dcf021e 100644
--- a/test/unittests/api/interceptor-unittest.cc
+++ b/test/unittests/api/interceptor-unittest.cc
@@ -174,8 +174,10 @@ TEST_F(InterceptorLoggingTest, DispatchTest) {
EXPECT_EQ(Run("obj.foo"), "named getter");
EXPECT_EQ(Run("obj[42]"), "indexed getter");
- EXPECT_EQ(Run("obj.foo = null"), "named setter, named descriptor");
- EXPECT_EQ(Run("obj[42] = null"), "indexed setter, indexed descriptor");
+ EXPECT_EQ(Run("obj.foo = null"),
+ "named setter, named descriptor, named query");
+ EXPECT_EQ(Run("obj[42] = null"),
+ "indexed setter, indexed descriptor, indexed query");
EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
"named descriptor");

View File

@@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marja=20H=C3=B6ltt=C3=A4?= <marja@chromium.org>
Date: Tue, 21 Feb 2023 13:38:34 +0100
Subject: Merged [valueserializer] Fix map transition chain following w/
dictionary maps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Map::Update might return a dictionary map, and the calling code didn't
take it into account.
Bug: chromium:1412487
(cherry picked from commit b0db6637936a88807b5512a4de68145d0a9d6f02)
Change-Id: Ib5e55aa60719e4ac2f14d993a3fc3e908cd43d2e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4290145
Reviewed-by: Marja Hölttä <marja@chromium.org>
Reviewed-by: Lutz Vahl <vahl@chromium.org>
Commit-Queue: Lutz Vahl <vahl@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.0@{#35}
Cr-Branched-From: 06097c6f0c5af54fd5d6965d37027efb72decd4f-refs/heads/11.0.226@{#1}
Cr-Branched-From: 6bf3344f5d9940de1ab253f1817dcb99c641c9d3-refs/heads/main@{#84857}
diff --git a/src/objects/value-serializer.cc b/src/objects/value-serializer.cc
index 61a7cae8e8a900694ba22637d04368dac56ebd5f..640f8621719fa5dee4909e215ae788b09f1b0ba5 100644
--- a/src/objects/value-serializer.cc
+++ b/src/objects/value-serializer.cc
@@ -2408,37 +2408,38 @@ Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
// Deserializaton of |value| might have deprecated current |target|,
// ensure we are working with the up-to-date version.
target = Map::Update(isolate_, target);
-
- InternalIndex descriptor(properties.size());
- PropertyDetails details =
- target->instance_descriptors(isolate_).GetDetails(descriptor);
- Representation expected_representation = details.representation();
- if (value->FitsRepresentation(expected_representation)) {
- if (expected_representation.IsHeapObject() &&
- !target->instance_descriptors(isolate_)
- .GetFieldType(descriptor)
- .NowContains(value)) {
- Handle<FieldType> value_type =
- value->OptimalType(isolate_, expected_representation);
- MapUpdater::GeneralizeField(isolate_, target, descriptor,
- details.constness(),
- expected_representation, value_type);
- }
- DCHECK(target->instance_descriptors(isolate_)
+ if (!target->is_dictionary_map()) {
+ InternalIndex descriptor(properties.size());
+ PropertyDetails details =
+ target->instance_descriptors(isolate_).GetDetails(descriptor);
+ Representation expected_representation = details.representation();
+ if (value->FitsRepresentation(expected_representation)) {
+ if (expected_representation.IsHeapObject() &&
+ !target->instance_descriptors(isolate_)
.GetFieldType(descriptor)
- .NowContains(value));
- properties.push_back(value);
- map = target;
- continue;
- } else {
- transitioning = false;
+ .NowContains(value)) {
+ Handle<FieldType> value_type =
+ value->OptimalType(isolate_, expected_representation);
+ MapUpdater::GeneralizeField(isolate_, target, descriptor,
+ details.constness(),
+ expected_representation, value_type);
+ }
+ DCHECK(target->instance_descriptors(isolate_)
+ .GetFieldType(descriptor)
+ .NowContains(value));
+ properties.push_back(value);
+ map = target;
+ continue;
+ }
}
+ transitioning = false;
}
// Fell out of transitioning fast path. Commit the properties gathered so
// far, and then start setting properties slowly instead.
DCHECK(!transitioning);
CHECK_LT(properties.size(), std::numeric_limits<uint32_t>::max());
+ CHECK(!map->is_dictionary_map());
CommitProperties(object, map, properties);
num_properties = static_cast<uint32_t>(properties.size());

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Wed, 12 Apr 2023 16:12:16 +0200
Subject: Make Error.captureStackTrace() a no-op for global object
(cherry picked from commit fa81078cca6964def7a3833704e0dba7b05065d8)
Bug: chromium:1432210
Change-Id: I8aa4c3f1d9ecbfffce503085c2879416ff916c69
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4417690
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Auto-Submit: Igor Sheludko <ishell@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#87045}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4419050
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Lutz Vahl <vahl@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.2@{#31}
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
diff --git a/src/builtins/builtins-error.cc b/src/builtins/builtins-error.cc
index adb180fba89b61279895e0427caa71703769e28a..4a8dec419d3f483826467a7244b89ad03fa7ff1f 100644
--- a/src/builtins/builtins-error.cc
+++ b/src/builtins/builtins-error.cc
@@ -35,6 +35,9 @@ BUILTIN(ErrorCaptureStackTrace) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kInvalidArgument, object_obj));
}
+ if (object_obj->IsJSGlobalProxy()) {
+ return ReadOnlyRoots(isolate).undefined_value();
+ }
Handle<JSObject> object = Handle<JSObject>::cast(object_obj);
Handle<Object> caller = args.atOrUndefined(isolate, 2);

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darius M <dmercadier@chromium.org>
Date: Mon, 27 Mar 2023 13:39:50 +0200
Subject: Merged: [compiler] Prevent constant folding of TypeGuard
TypeGuard are used to prevent operations from floating before a
preceding check, and thus shouldn't be constant-folded.
Bug: chromium:1427388
(cherry picked from commit 867716437273c16dc6ef5bc85b9c18affa1fb242)
Change-Id: Ia334d079707f13974235f8c04ccb468ac16ff794
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4386487
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.2@{#23}
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
diff --git a/src/compiler/constant-folding-reducer.cc b/src/compiler/constant-folding-reducer.cc
index 5e74ba75352cc3e7bf29a83ee72273e45720907b..4059e47c2db00e0df82296fa63e09147095f7ba7 100644
--- a/src/compiler/constant-folding-reducer.cc
+++ b/src/compiler/constant-folding-reducer.cc
@@ -66,7 +66,8 @@ ConstantFoldingReducer::~ConstantFoldingReducer() = default;
Reduction ConstantFoldingReducer::Reduce(Node* node) {
if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
node->op()->HasProperty(Operator::kEliminatable) &&
- node->opcode() != IrOpcode::kFinishRegion) {
+ node->opcode() != IrOpcode::kFinishRegion &&
+ node->opcode() != IrOpcode::kTypeGuard) {
Node* constant = TryGetConstant(jsgraph(), node);
if (constant != nullptr) {
DCHECK(NodeProperties::IsTyped(constant));

View File

@@ -0,0 +1,366 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Thu, 27 Apr 2023 11:11:32 +0200
Subject: Fix v8::Object::SetAccessorProperty
... by using JavaScript spec compliant JSReceiver::DefineOwnProperty.
Drive-by:
- cleanup comments in include/v8-object.h, insert links to
respective pages of https://tc39.es/ecma262/ when referencing spec,
- rename JSObject::DefineAccessor() to
JSObject::DefineOwnAccessorIgnoreAttributes().
(cherry picked from commit b8020e1973d7d3a50b17c076cd948f079e59f9e5)
Bug: chromium:1433211
Change-Id: Ia9edaadd68f1986f18581156ad8f79c438b77744
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4458947
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#87302}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4573392
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.8@{#62}
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
diff --git a/include/v8-object.h b/include/v8-object.h
index d7332ba0c88d12e8086f56117631dfb3e1e514b4..dfeda2d39431d481dbeab6698c3d3e7f02a1b19c 100644
--- a/include/v8-object.h
+++ b/include/v8-object.h
@@ -247,13 +247,16 @@ class V8_EXPORT Object : public Value {
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
Local<Value> value);
- // Implements CreateDataProperty (ECMA-262, 7.3.4).
- //
- // Defines a configurable, writable, enumerable property with the given value
- // on the object unless the property already exists and is not configurable
- // or the object is not extensible.
- //
- // Returns true on success.
+ /**
+ * Implements CreateDataProperty(O, P, V), see
+ * https://tc39.es/ecma262/#sec-createdataproperty.
+ *
+ * Defines a configurable, writable, enumerable property with the given value
+ * on the object unless the property already exists and is not configurable
+ * or the object is not extensible.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
Local<Name> key,
Local<Value> value);
@@ -261,29 +264,35 @@ class V8_EXPORT Object : public Value {
uint32_t index,
Local<Value> value);
- // Implements DefineOwnProperty.
- //
- // In general, CreateDataProperty will be faster, however, does not allow
- // for specifying attributes.
- //
- // Returns true on success.
+ /**
+ * Implements [[DefineOwnProperty]] for data property case, see
+ * https://tc39.es/ecma262/#table-essential-internal-methods.
+ *
+ * In general, CreateDataProperty will be faster, however, does not allow
+ * for specifying attributes.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
Local<Context> context, Local<Name> key, Local<Value> value,
PropertyAttribute attributes = None);
- // Implements Object.DefineProperty(O, P, Attributes), see Ecma-262 19.1.2.4.
- //
- // The defineProperty function is used to add an own property or
- // update the attributes of an existing own property of an object.
- //
- // Both data and accessor descriptors can be used.
- //
- // In general, CreateDataProperty is faster, however, does not allow
- // for specifying attributes or an accessor descriptor.
- //
- // The PropertyDescriptor can change when redefining a property.
- //
- // Returns true on success.
+ /**
+ * Implements Object.defineProperty(O, P, Attributes), see
+ * https://tc39.es/ecma262/#sec-object.defineproperty.
+ *
+ * The defineProperty function is used to add an own property or
+ * update the attributes of an existing own property of an object.
+ *
+ * Both data and accessor descriptors can be used.
+ *
+ * In general, CreateDataProperty is faster, however, does not allow
+ * for specifying attributes or an accessor descriptor.
+ *
+ * The PropertyDescriptor can change when redefining a property.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(
Local<Context> context, Local<Name> key, PropertyDescriptor& descriptor);
@@ -302,14 +311,15 @@ class V8_EXPORT Object : public Value {
Local<Context> context, Local<Value> key);
/**
- * Returns Object.getOwnPropertyDescriptor as per ES2016 section 19.1.2.6.
+ * Implements Object.getOwnPropertyDescriptor(O, P), see
+ * https://tc39.es/ecma262/#sec-object.getownpropertydescriptor.
*/
V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetOwnPropertyDescriptor(
Local<Context> context, Local<Name> key);
/**
- * Object::Has() calls the abstract operation HasProperty(O, P) described
- * in ECMA-262, 7.3.10. Has() returns
+ * Object::Has() calls the abstract operation HasProperty(O, P), see
+ * https://tc39.es/ecma262/#sec-hasproperty. Has() returns
* true, if the object has the property, either own or on the prototype chain.
* Interceptors, i.e., PropertyQueryCallbacks, are called if present.
*
@@ -347,7 +357,7 @@ class V8_EXPORT Object : public Value {
void SetAccessorProperty(Local<Name> name, Local<Function> getter,
Local<Function> setter = Local<Function>(),
- PropertyAttribute attribute = None,
+ PropertyAttribute attributes = None,
AccessControl settings = DEFAULT);
/**
diff --git a/src/api/api-natives.cc b/src/api/api-natives.cc
index 8624c279d66e4fa54a7a20681e1398c453b6cdbd..742d3c17a3e7def43813f44b004c8dc41a27ed68 100644
--- a/src/api/api-natives.cc
+++ b/src/api/api-natives.cc
@@ -92,10 +92,10 @@ MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
Handle<FunctionTemplateInfo>::cast(setter)),
Object);
}
- RETURN_ON_EXCEPTION(
- isolate,
- JSObject::DefineAccessor(object, name, getter, setter, attributes),
- Object);
+ RETURN_ON_EXCEPTION(isolate,
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, getter, setter, attributes),
+ Object);
return object;
}
diff --git a/src/api/api.cc b/src/api/api.cc
index 0bc26565403fa1a9827ced3bc6a49ca87bbf46c0..29e163c2e3073ae1f9a86e88f317e9fd44c6c112 100644
--- a/src/api/api.cc
+++ b/src/api/api.cc
@@ -4932,7 +4932,7 @@ Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
Local<Function> setter,
- PropertyAttribute attribute,
+ PropertyAttribute attributes,
AccessControl settings) {
// TODO(verwaest): Remove |settings|.
DCHECK_EQ(v8::DEFAULT, settings);
@@ -4944,9 +4944,20 @@ void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
if (setter_i.is_null()) setter_i = i_isolate->factory()->null_value();
- i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
- v8::Utils::OpenHandle(*name), getter_i, setter_i,
- static_cast<i::PropertyAttributes>(attribute));
+
+ i::PropertyDescriptor desc;
+ desc.set_enumerable(!(attributes & v8::DontEnum));
+ desc.set_configurable(!(attributes & v8::DontDelete));
+ desc.set_get(getter_i);
+ desc.set_set(setter_i);
+
+ i::Handle<i::Name> name_i = v8::Utils::OpenHandle(*name);
+ // DefineOwnProperty might still throw if the receiver is a JSProxy and it
+ // might fail if the receiver is non-extensible or already has this property
+ // as non-configurable.
+ Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
+ i_isolate, self, name_i, &desc, Just(i::kDontThrow));
+ USE(success);
}
Maybe<bool> Object::SetNativeDataProperty(
diff --git a/src/init/bootstrapper.cc b/src/init/bootstrapper.cc
index fc7b17d582e79b956362e0db46a7aefebd594ed0..8a81c4acda9a92b1d25491aa00278a0e929da695 100644
--- a/src/init/bootstrapper.cc
+++ b/src/init/bootstrapper.cc
@@ -634,7 +634,9 @@ V8_NOINLINE void SimpleInstallGetterSetter(Isolate* isolate,
Handle<JSFunction> setter =
SimpleCreateFunction(isolate, setter_name, call_setter, 1, true);
- JSObject::DefineAccessor(base, name, getter, setter, DONT_ENUM).Check();
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, name, getter, setter,
+ DONT_ENUM)
+ .Check();
}
void SimpleInstallGetterSetter(Isolate* isolate, Handle<JSObject> base,
@@ -658,7 +660,8 @@ V8_NOINLINE Handle<JSFunction> SimpleInstallGetter(Isolate* isolate,
Handle<Object> setter = isolate->factory()->undefined_value();
- JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM)
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, property_name, getter,
+ setter, DONT_ENUM)
.Check();
return getter;
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index b938d82667498d4ff3505d455a7ed3a299cd5247..e51264eef22c9fc91c89ef6fe0d223c97ccf7fa9 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -1498,7 +1498,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
? desc->set()
: Handle<Object>::cast(isolate->factory()->null_value()));
MaybeHandle<Object> result =
- JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
+ JSObject::DefineOwnAccessorIgnoreAttributes(it, getter, setter,
+ desc->ToAttributes());
if (result.is_null()) return Nothing<bool>();
}
}
@@ -1679,8 +1680,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
: current->has_set()
? current->set()
: Handle<Object>::cast(isolate->factory()->null_value()));
- MaybeHandle<Object> result =
- JSObject::DefineAccessor(it, getter, setter, attrs);
+ MaybeHandle<Object> result = JSObject::DefineOwnAccessorIgnoreAttributes(
+ it, getter, setter, attrs);
if (result.is_null()) return Nothing<bool>();
}
}
@@ -4611,22 +4612,19 @@ bool JSObject::HasEnumerableElements() {
UNREACHABLE();
}
-MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes) {
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
+ Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
+ Handle<Object> setter, PropertyAttributes attributes) {
Isolate* isolate = object->GetIsolate();
PropertyKey key(isolate, name);
LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
- return DefineAccessor(&it, getter, setter, attributes);
+ return DefineOwnAccessorIgnoreAttributes(&it, getter, setter, attributes);
}
-MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes) {
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
+ PropertyAttributes attributes) {
Isolate* isolate = it->isolate();
it->UpdateProtector();
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index f663af6ed8a445f8ef30a67bac176a1abe6c85f8..5e7326eb1c99115829c358cd4069e1f6835f972b 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -525,13 +525,14 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
// Defines an AccessorPair property on the given object.
- V8_EXPORT_PRIVATE static MaybeHandle<Object> DefineAccessor(
- Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
- Handle<Object> setter, PropertyAttributes attributes);
- static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes);
+ V8_EXPORT_PRIVATE static MaybeHandle<Object>
+ DefineOwnAccessorIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
+ Handle<Object> getter,
+ Handle<Object> setter,
+ PropertyAttributes attributes);
+ static MaybeHandle<Object> DefineOwnAccessorIgnoreAttributes(
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
+ PropertyAttributes attributes);
// Defines an AccessorInfo property on the given object.
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
index 56e58bea3e1c7add75729e590b628d9a78558ce6..01111be8d6ea28ed1e1e81255b29da5a77ab1e39 100644
--- a/src/runtime/runtime-object.cc
+++ b/src/runtime/runtime-object.cc
@@ -1109,7 +1109,8 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
auto attrs = PropertyAttributesFromInt(args.smi_value_at(4));
RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
+ isolate, JSObject::DefineOwnAccessorIgnoreAttributes(obj, name, getter,
+ setter, attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1215,8 +1216,8 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
RETURN_FAILURE_ON_EXCEPTION(
isolate,
- JSObject::DefineAccessor(object, name, getter,
- isolate->factory()->null_value(), attrs));
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, getter, isolate->factory()->null_value(), attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1360,8 +1361,8 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
RETURN_FAILURE_ON_EXCEPTION(
isolate,
- JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
- setter, attrs));
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, isolate->factory()->null_value(), setter, attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
diff --git a/src/sandbox/testing.cc b/src/sandbox/testing.cc
index fead4aa222ceb81d76f6dfec7e7797e337e7ba94..aab72a18015bf7ac1d0949e9497e85d9d089b4b8 100644
--- a/src/sandbox/testing.cc
+++ b/src/sandbox/testing.cc
@@ -156,7 +156,8 @@ void InstallGetter(Isolate* isolate, Handle<JSObject> object,
Handle<String> property_name = factory->NewStringFromAsciiChecked(name);
Handle<JSFunction> getter = CreateFunc(isolate, func, property_name, false);
Handle<Object> setter = factory->null_value();
- JSObject::DefineAccessor(object, property_name, getter, setter, FROZEN);
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, property_name, getter,
+ setter, FROZEN);
}
void InstallFunction(Isolate* isolate, Handle<JSObject> holder,
diff --git a/test/cctest/test-code-stub-assembler.cc b/test/cctest/test-code-stub-assembler.cc
index 53ad0a95e2e63f32610a77ee7195d15f7037898d..4152456d1a7962da4a0d88e15bc68107da585613 100644
--- a/test/cctest/test-code-stub-assembler.cc
+++ b/test/cctest/test-code-stub-assembler.cc
@@ -1179,7 +1179,9 @@ void AddProperties(Handle<JSObject> object, Handle<Name> names[],
Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value);
Handle<Object> getter(pair->getter(), isolate);
Handle<Object> setter(pair->setter(), isolate);
- JSObject::DefineAccessor(object, names[i], getter, setter, NONE).Check();
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, names[i], getter,
+ setter, NONE)
+ .Check();
} else {
JSObject::AddProperty(isolate, object, names[i], value, NONE);
}

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Tue, 13 Jun 2023 17:08:59 +0200
Subject: Merged: [compiler] StackCheck can have side effects
Bug: chromium:1452137
(cherry picked from commit e548943e473b020fdc1de6e5543ca31b24d8b7f9)
Change-Id: Ibd7c9b02efd12341b452e4c34a635a58a817649f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4637129
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Auto-Submit: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#49}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc
index 8af8e7d32fb68fdcaedaf08427103c893d23098d..e60c8a2c78970c89c4f52a6dc34a97d56e602e26 100644
--- a/src/compiler/js-operator.cc
+++ b/src/compiler/js-operator.cc
@@ -1396,7 +1396,7 @@ const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback,
const Operator* JSOperatorBuilder::StackCheck(StackCheckKind kind) {
return zone()->New<Operator1<StackCheckKind>>( // --
IrOpcode::kJSStackCheck, // opcode
- Operator::kNoWrite, // properties
+ Operator::kNoProperties, // properties
"JSStackCheck", // name
0, 1, 1, 0, 1, 2, // counts
kind); // parameter

View File

@@ -0,0 +1,122 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Fri, 2 Jun 2023 18:13:01 +0200
Subject: Merged: [ic] Fix store handler selection for arguments objects
Drive-by: fix printing of handlers in --trace-feedback-updates mode.
(cherry picked from commit e144f3b71e64e01d6ffd247eb15ca1ff56f6287b)
Bug: chromium:1450481
Change-Id: Ifbb97d694b8520584df0610aad30805713b29c00
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4584889
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.9@{#32}
Cr-Branched-From: 8ade6bf1fa237ad30dd9a05cc6ffe548131699e8-refs/heads/10.9.194@{#1}
Cr-Branched-From: 9ff2515271f11cab783f0e82678ae0b925d77dd0-refs/heads/main@{#84164}
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
index 71604afa7a067e14a891057de4011416f45f4f19..3f94e8aa7701eef49d5a35fd552742279b5e8586 100644
--- a/src/diagnostics/objects-printer.cc
+++ b/src/diagnostics/objects-printer.cc
@@ -1308,8 +1308,18 @@ void FeedbackNexus::Print(std::ostream& os) {
case FeedbackSlotKind::kSetKeyedStrict: {
os << InlineCacheState2String(ic_state());
if (ic_state() == InlineCacheState::MONOMORPHIC) {
- os << "\n " << Brief(GetFeedback()) << ": ";
- StoreHandler::PrintHandler(GetFeedbackExtra().GetHeapObjectOrSmi(), os);
+ HeapObject feedback = GetFeedback().GetHeapObject();
+ HeapObject feedback_extra = GetFeedbackExtra().GetHeapObject();
+ if (feedback.IsName()) {
+ os << " with name " << Brief(feedback);
+ WeakFixedArray array = WeakFixedArray::cast(feedback_extra);
+ os << "\n " << Brief(array.Get(0)) << ": ";
+ Object handler = array.Get(1).GetHeapObjectOrSmi();
+ StoreHandler::PrintHandler(handler, os);
+ } else {
+ os << "\n " << Brief(feedback) << ": ";
+ StoreHandler::PrintHandler(feedback_extra, os);
+ }
} else if (ic_state() == InlineCacheState::POLYMORPHIC) {
WeakFixedArray array =
WeakFixedArray::cast(GetFeedback().GetHeapObject());
diff --git a/src/ic/handler-configuration.cc b/src/ic/handler-configuration.cc
index 43511407e0eb54e2ce22ee132d8a4d37c52b13a7..cd6d834d6b7ec84c1d46105449ca775cd970f4f2 100644
--- a/src/ic/handler-configuration.cc
+++ b/src/ic/handler-configuration.cc
@@ -584,8 +584,11 @@ void StoreHandler::PrintHandler(Object handler, std::ostream& os) {
os << ", validity cell = ";
store_handler.validity_cell().ShortPrint(os);
os << ")" << std::endl;
+ } else if (handler.IsMap()) {
+ os << "StoreHandler(field transition to " << Brief(handler) << ")"
+ << std::endl;
} else {
- os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")";
+ os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")" << std::endl;
}
}
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 32039f9888d3cb54699c6aefd0bcc3573044995e..0a7794de93dc6ba2a20f106ccf2d5f4b30319167 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -2296,10 +2296,18 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
receiver_map->has_sealed_elements() ||
receiver_map->has_nonextensible_elements() ||
receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
+ // TODO(jgruber): Update counter name.
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
- code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
- if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
- return code;
+ if (receiver_map->IsJSArgumentsObjectMap() &&
+ receiver_map->has_fast_packed_elements()) {
+ // Allow fast behaviour for in-bounds stores while making it miss and
+ // properly handle the out of bounds store case.
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), STANDARD_STORE);
+ } else {
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
+ if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
+ return code;
+ }
}
} else if (IsStoreInArrayLiteralIC()) {
// TODO(jgruber): Update counter name.
@@ -2310,7 +2318,7 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
DCHECK(DICTIONARY_ELEMENTS == receiver_map->elements_kind() ||
receiver_map->has_frozen_elements());
- code = StoreHandler::StoreSlow(isolate(), store_mode);
+ return StoreHandler::StoreSlow(isolate(), store_mode);
}
if (IsAnyDefineOwn() || IsStoreInArrayLiteralIC()) return code;
diff --git a/src/objects/map-inl.h b/src/objects/map-inl.h
index 04cdb99e103c5ab51c22a91fd7ba0712b757556c..5f93c39b652946a5ad8f23235f958dde4b84cbb4 100644
--- a/src/objects/map-inl.h
+++ b/src/objects/map-inl.h
@@ -589,6 +589,10 @@ bool Map::has_fast_elements() const {
return IsFastElementsKind(elements_kind());
}
+bool Map::has_fast_packed_elements() const {
+ return IsFastPackedElementsKind(elements_kind());
+}
+
bool Map::has_sloppy_arguments_elements() const {
return IsSloppyArgumentsElementsKind(elements_kind());
}
diff --git a/src/objects/map.h b/src/objects/map.h
index 6914a51150f4235386f5dca7af0d8103bc64f9e2..8311850f82bc32b794873689789c510376f67233 100644
--- a/src/objects/map.h
+++ b/src/objects/map.h
@@ -422,6 +422,7 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
inline bool has_fast_smi_or_object_elements() const;
inline bool has_fast_double_elements() const;
inline bool has_fast_elements() const;
+ inline bool has_fast_packed_elements() const;
inline bool has_sloppy_arguments_elements() const;
inline bool has_fast_sloppy_arguments_elements() const;
inline bool has_fast_string_wrapper_elements() const;

View File

@@ -0,0 +1,304 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Wed, 26 Apr 2023 10:56:03 -0700
Subject: Merged: [regexp] Fix clobbered register in global Unicode special
case
Bug: chromium:1439691
(cherry picked from commit 2c8a019f39d29b403f881d9b5932e3219fdcc832)
Change-Id: Ia418ae04bf4352e3618700c55ecd37447023e6eb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4503810
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.2@{#43}
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
diff --git a/src/regexp/arm/regexp-macro-assembler-arm.cc b/src/regexp/arm/regexp-macro-assembler-arm.cc
index 2658068b6f94b97f024b1400c8c0b20eefdc5143..5de110c8495ef5bd261df92ca8f459c5f0cc7e5b 100644
--- a/src/regexp/arm/regexp-macro-assembler-arm.cc
+++ b/src/regexp/arm/regexp-macro-assembler-arm.cc
@@ -877,19 +877,18 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
__ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
__ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare r0 to initialize registers with its value in the next run.
- __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), r2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// r4: capture start index
__ cmp(current_input_offset(), r4);
// Not a zero-length match, restart.
- __ b(ne, &load_char_start_regexp);
+ __ b(ne, &reload_string_start_minus_one);
// Offset from the end is zero if we already reached the end.
__ cmp(current_input_offset(), Operand::Zero());
__ b(eq, &exit_label_);
@@ -901,6 +900,11 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare r0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ b(&load_char_start_regexp);
} else {
__ mov(r0, Operand(SUCCESS));
diff --git a/src/regexp/ia32/regexp-macro-assembler-ia32.cc b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
index 600234542042ce9a06ceb3b415fece83f6f271bf..6c3df5da7d6c28619902b20419c9cf437325c1d1 100644
--- a/src/regexp/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
@@ -915,19 +915,18 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ add(Operand(ebp, kRegisterOutput),
Immediate(num_saved_registers_ * kSystemPointerSize));
- // Prepare eax to initialize registers with its value in the next run.
- __ mov(eax, Operand(ebp, kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), ebx);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// edx: capture start index
__ cmp(edi, edx);
// Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
+ __ j(not_equal, &reload_string_start_minus_one);
// edi (offset from the end) is zero if we already reached the end.
__ test(edi, edi);
__ j(zero, &exit_label_, Label::kNear);
@@ -941,6 +940,12 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
}
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+
+ __ bind(&reload_string_start_minus_one);
+ // Prepare eax to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ mov(eax, Operand(ebp, kStringStartMinusOne));
+
__ jmp(&load_char_start_regexp);
} else {
__ mov(eax, Immediate(SUCCESS));
diff --git a/src/regexp/loong64/regexp-macro-assembler-loong64.cc b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
index 35fd95bd0f2d210419b4057ced6e16ffd5aec051..d5c52b4134ccbfecef85328e181dae1bbda7bf63 100644
--- a/src/regexp/loong64/regexp-macro-assembler-loong64.cc
+++ b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
@@ -850,18 +850,17 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
__ Add_d(a2, a2, num_saved_registers_ * kIntSize);
__ St_d(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// t3: capture start index
// Not a zero-length match, restart.
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
Operand(t3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
@@ -874,6 +873,11 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(a0, Operand(SUCCESS));
diff --git a/src/regexp/mips64/regexp-macro-assembler-mips64.cc b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
index 456e166adefc72b7bcaa9245798f3885c2a4c2e7..6ee4c709cf96f68a32a0b3c1ebdc42817293bf29 100644
--- a/src/regexp/mips64/regexp-macro-assembler-mips64.cc
+++ b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
@@ -898,19 +898,18 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ Daddu(a2, a2, num_saved_registers_ * kIntSize);
__ Sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// t3: capture start index
// Not a zero-length match, restart.
- __ Branch(
- &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
+ Operand(t3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
Operand(zero_reg));
@@ -922,6 +921,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(v0, Operand(SUCCESS));
diff --git a/src/regexp/riscv/regexp-macro-assembler-riscv.cc b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
index c8f3eb551e05805003d30a1786acdd9aab96d906..c03be100849c50f471d6839d4cd960e5a78d67d3 100644
--- a/src/regexp/riscv/regexp-macro-assembler-riscv.cc
+++ b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
@@ -869,18 +869,17 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
__ AddWord(a2, a2, num_saved_registers_ * kIntSize);
__ StoreWord(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ LoadWord(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// s3: capture start index
// Not a zero-length match, restart.
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
Operand(s3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
@@ -893,6 +892,12 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ LoadWord(a0,
+ MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(a0, Operand(SUCCESS));
diff --git a/src/regexp/s390/regexp-macro-assembler-s390.cc b/src/regexp/s390/regexp-macro-assembler-s390.cc
index a61bc379ba6c265ecb0c5cd7aa8d7a2e35ca6c1e..de184b95862e7f2e64d69cff6b60d866eb212f36 100644
--- a/src/regexp/s390/regexp-macro-assembler-s390.cc
+++ b/src/regexp/s390/regexp-macro-assembler-s390.cc
@@ -947,19 +947,18 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
__ AddS64(r4, Operand(num_saved_registers_ * kIntSize));
__ StoreU64(r4, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare r2 to initialize registers with its value in the next run.
- __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), r4);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// r6: capture start index
__ CmpS64(current_input_offset(), r6);
// Not a zero-length match, restart.
- __ bne(&load_char_start_regexp);
+ __ bne(&reload_string_start_minus_one);
// Offset from the end is zero if we already reached the end.
__ CmpS64(current_input_offset(), Operand::Zero());
__ beq(&exit_label_);
@@ -970,6 +969,11 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare r2 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ b(&load_char_start_regexp);
} else {
__ mov(r2, Operand(SUCCESS));
diff --git a/src/regexp/x64/regexp-macro-assembler-x64.cc b/src/regexp/x64/regexp-macro-assembler-x64.cc
index 89fd2e34f1296113c43f16896d8f35d741782709..7c59534aa46c4c1c6fed151d7dad13070d133f47 100644
--- a/src/regexp/x64/regexp-macro-assembler-x64.cc
+++ b/src/regexp/x64/regexp-macro-assembler-x64.cc
@@ -951,19 +951,18 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ addq(Operand(rbp, kRegisterOutput),
Immediate(num_saved_registers_ * kIntSize));
- // Prepare rax to initialize registers with its value in the next run.
- __ movq(rax, Operand(rbp, kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), kScratchRegister);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// rdx: capture start index
__ cmpq(rdi, rdx);
// Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
+ __ j(not_equal, &reload_string_start_minus_one);
// rdi (offset from the end) is zero if we already reached the end.
__ testq(rdi, rdi);
__ j(zero, &exit_label_, Label::kNear);
@@ -978,6 +977,11 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare rax to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ movq(rax, Operand(rbp, kStringStartMinusOne));
+
__ jmp(&load_char_start_regexp);
} else {
__ Move(rax, SUCCESS);
diff --git a/test/mjsunit/regress/regress-crbug-1439691.js b/test/mjsunit/regress/regress-crbug-1439691.js
new file mode 100644
index 0000000000000000000000000000000000000000..6c55835535ab4f42ef0446abf863986962df9e9b
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-1439691.js
@@ -0,0 +1,7 @@
+// Copyright 2023 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f0() {
+}
+/(?!(a))\1/gudyi[Symbol.replace]("f\uD83D\uDCA9ba\u2603", f0);

View File

@@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Toon Verwaest <verwaest@chromium.org>
Date: Fri, 16 Jun 2023 17:13:52 +0200
Subject: Merged: [runtime] Set instance prototypes directly on maps
Bug: chromium:1452137
(cherry picked from commit c7c447735f762f6d6d0878e229371797845ef4ab)
Change-Id: I611c41f942e2e51f3c4b4f1d119c18410617188e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4637888
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Auto-Submit: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#47}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/objects/js-function.cc b/src/objects/js-function.cc
index 62fe309a471b323c1cb2a9a872380563bbdc369f..878ef8fd6b49debcd46f8d4f3693630fb02fef17 100644
--- a/src/objects/js-function.cc
+++ b/src/objects/js-function.cc
@@ -672,6 +672,10 @@ void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
// At that point, a new initial map is created and the prototype is put
// into the initial map where it belongs.
function->set_prototype_or_initial_map(*value, kReleaseStore);
+ if (value->IsJSObjectThatCanBeTrackedAsPrototype()) {
+ // Optimize as prototype to detach it from its transition tree.
+ JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
+ }
} else {
Handle<Map> new_map =
Map::Copy(isolate, initial_map, "SetInstancePrototype");
@@ -796,8 +800,10 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
Handle<HeapObject> prototype;
if (function->has_instance_prototype()) {
prototype = handle(function->instance_prototype(), isolate);
+ map->set_prototype(*prototype);
} else {
prototype = isolate->factory()->NewFunctionPrototype(function);
+ Map::SetPrototype(isolate, map, prototype);
}
DCHECK(map->has_fast_object_elements());

View File

@@ -0,0 +1,78 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Pedro Pontes <pepontes@microsoft.com>
Date: Thu, 29 Jun 2023 01:16:50 -0700
Subject: Fix using shared objects as prototypes more (Partial backport)
The previous fix from
https://chromium-review.googlesource.com/c/v8/v8/+/4086127 was
insufficient. It prevented shared objects from being optimized as
prototypes, but callers of OptimizeAsPrototype also assume that all
JSObjects can track prototype users via prototype_info on the map.
This CL attempts a broader fix where shared objects are not considered
optimizable as prototypes at all. When used as a prototype, shared
objects are treated like non-JSObjects (e.g. JSProxy, WasmObject).
Bug: chromium:1401295, v8:12547
Change-Id: I9886e9ccac9e597e7dd34a09083a096ff4e3bf16
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4112150
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84916}
diff --git a/src/objects/heap-object.h b/src/objects/heap-object.h
index 806b34b969eeaccc7f16cfd0ac734d667b165943..b2d401ba823231f939b8d1ae4f44660360276053 100644
--- a/src/objects/heap-object.h
+++ b/src/objects/heap-object.h
@@ -113,6 +113,8 @@ class HeapObject : public Object {
STRUCT_LIST(DECL_STRUCT_PREDICATE)
#undef DECL_STRUCT_PREDICATE
+ V8_INLINE bool IsJSObjectThatCanBeTrackedAsPrototype() const;
+
// Converts an address to a HeapObject pointer.
static inline HeapObject FromAddress(Address address) {
DCHECK_TAG_ALIGNED(address);
diff --git a/src/objects/objects-inl.h b/src/objects/objects-inl.h
index 025c87dbf313cc4b3adb884b4b2d96940c4ce389..baa1167a123b4c161d06b9869938d3cbd4f15fb2 100644
--- a/src/objects/objects-inl.h
+++ b/src/objects/objects-inl.h
@@ -83,6 +83,11 @@ bool Object::InSharedWritableHeap() const {
return IsHeapObject() && HeapObject::cast(*this).InSharedWritableHeap();
}
+bool Object::IsJSObjectThatCanBeTrackedAsPrototype() const {
+ return IsHeapObject() &&
+ HeapObject::cast(*this).IsJSObjectThatCanBeTrackedAsPrototype();
+}
+
#define IS_TYPE_FUNCTION_DEF(type_) \
bool Object::Is##type_() const { \
return IsHeapObject() && HeapObject::cast(*this).Is##type_(); \
@@ -189,6 +194,13 @@ bool HeapObject::InSharedWritableHeap() const {
return BasicMemoryChunk::FromHeapObject(*this)->InSharedHeap();
}
+bool HeapObject::IsJSObjectThatCanBeTrackedAsPrototype() const {
+ // Do not optimize objects in the shared heap because it is not
+ // threadsafe. Objects in the shared heap have fixed layouts and their maps
+ // never change.
+ return IsJSObject() && !InSharedWritableHeap();
+}
+
bool HeapObject::IsNullOrUndefined(Isolate* isolate) const {
return IsNullOrUndefined(ReadOnlyRoots(isolate));
}
diff --git a/src/objects/objects.h b/src/objects/objects.h
index c3a0cbf15a329d0e4e68aa5fd379352a1cc061ba..8814ddadc4bfaac6e243a94c4890147b6ea5b4b9 100644
--- a/src/objects/objects.h
+++ b/src/objects/objects.h
@@ -341,6 +341,8 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
bool IsWasmObject(Isolate* = nullptr) const { return false; }
#endif
+ V8_INLINE bool IsJSObjectThatCanBeTrackedAsPrototype() const;
+
enum class Conversion { kToNumber, kToNumeric };
#define DECL_STRUCT_PREDICATE(NAME, Name, name) \

View File

@@ -1,2 +1,4 @@
cherry-pick-e0efbd45ea74.patch
cherry-pick-218b56e51638.patch
m114_move_transceiver_iteration_loop_over_to_the_signaling_thread.patch
m114_sdp_reject_duplicate_ssrcs_in_ssrc-groups.patch

View File

@@ -1,7 +1,7 @@
From 218b56e516386cd57c7513197528c3124bcd7ef3 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Cooper <alcooper@chromium.org>
Date: Wed, 08 Feb 2023 14:16:01 -0800
Subject: [PATCH] Fix Destruction inside WGC Callback
Date: Wed, 8 Feb 2023 14:16:01 -0800
Subject: Fix Destruction inside WGC Callback
If we are notified of the destruction of the window before a
CaptureFrame call can fail, then we may end up attempting to destroy the
@@ -29,13 +29,12 @@ Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/293246
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5481@{#5}
Cr-Branched-From: 2e1a9a4ae0234d4b1ea7a6fd4188afa1fb20379d-refs/heads/main@{#38901}
---
diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc
index e165291..ea5565c 100644
index 831257b4d476d674303f835f6002b22bf809a772..20045b6d1d1250fc9b634e51fe3875b484d6c397 100644
--- a/modules/desktop_capture/win/wgc_capture_session.cc
+++ b/modules/desktop_capture/win/wgc_capture_session.cc
@@ -397,17 +397,14 @@
@@ -388,17 +388,14 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender,
RTC_LOG(LS_INFO) << "Capture target has been closed.";
item_closed_ = true;

View File

@@ -1,7 +1,11 @@
From e0efbd45ea7421fb944c7343254ac5dc22bee541 Mon Sep 17 00:00:00 2001
From: Henrik Boström <hbos@webrtc.org>
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= <hbos@webrtc.org>
Date: Fri, 20 Jan 2023 10:48:31 +0100
Subject: [PATCH] [Merge-110] [Stats] Handle the case of missing certificates.
Subject: =?UTF-8?q?=C2=A0[Stats]=20Handle=20the=20case=20of=20missing=20ce?=
=?UTF-8?q?rtificates.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Certificates being missing is a sign of a bug (e.g. webrtc:14844, to be
fixed separately) which is why we have a DCHECK. But this DCHECK does
@@ -22,13 +26,12 @@ Cr-Original-Commit-Position: refs/heads/main@{#39159}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291380
Cr-Commit-Position: refs/branch-heads/5481@{#2}
Cr-Branched-From: 2e1a9a4ae0234d4b1ea7a6fd4188afa1fb20379d-refs/heads/main@{#38901}
---
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index d500a7b..1d88566 100644
index ff7e334169da41c400d94387527734362d5dbeaa..c16e9ac7eaade4785f16afa46b2051f338095ca3 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -2192,16 +2192,17 @@
@@ -2197,16 +2197,17 @@ void RTCStatsCollector::ProduceTransportStats_n(
// exist.
const auto& certificate_stats_it =
transport_cert_stats.find(transport_name);

View File

@@ -0,0 +1,126 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tommi <tommi@webrtc.org>
Date: Thu, 1 Jun 2023 16:08:52 +0200
Subject: Move transceiver iteration loop over to the signaling thread.
This is required for ReportTransportStats since iterating over the
transceiver list from the network thread is not safe.
(cherry picked from commit dba22d31909298161318e00d43a80cdb0abc940f)
No-Try: true
Bug: chromium:1446274, webrtc:12692
Change-Id: I7c514df9f029112c4b1da85826af91217850fb26
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307340
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Original-Commit-Position: refs/heads/main@{#40197}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308001
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/branch-heads/5735@{#3}
Cr-Branched-From: df7df199abd619e75b9f1d9a7e12fc3f3f748775-refs/heads/main@{#39949}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 4615ce5a2c413dba798c3f9f8f7d4c1ae78bf9af..62179cd44c57dc6d808579353b398412db5e1ed6 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -716,9 +716,6 @@ JsepTransportController* PeerConnection::InitializeTransportController_n(
transport_controller_->SubscribeIceConnectionState(
[this](cricket::IceConnectionState s) {
RTC_DCHECK_RUN_ON(network_thread());
- if (s == cricket::kIceConnectionConnected) {
- ReportTransportStats();
- }
signaling_thread()->PostTask(
SafeTask(signaling_thread_safety_.flag(), [this, s]() {
RTC_DCHECK_RUN_ON(signaling_thread());
@@ -2372,6 +2369,20 @@ void PeerConnection::OnTransportControllerConnectionState(
case cricket::kIceConnectionConnected:
RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
"all transports are writable.";
+ {
+ std::vector<RtpTransceiverProxyRefPtr> transceivers;
+ if (ConfiguredForMedia()) {
+ transceivers = rtp_manager()->transceivers()->List();
+ }
+
+ network_thread()->PostTask(
+ SafeTask(network_thread_safety_,
+ [this, transceivers = std::move(transceivers)] {
+ RTC_DCHECK_RUN_ON(network_thread());
+ ReportTransportStats(std::move(transceivers));
+ }));
+ }
+
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
break;
@@ -2701,20 +2712,18 @@ void PeerConnection::OnTransportControllerGatheringState(
}
// Runs on network_thread().
-void PeerConnection::ReportTransportStats() {
+void PeerConnection::ReportTransportStats(
+ std::vector<RtpTransceiverProxyRefPtr> transceivers) {
TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
std::map<std::string, std::set<cricket::MediaType>>
media_types_by_transport_name;
- if (ConfiguredForMedia()) {
- for (const auto& transceiver :
- rtp_manager()->transceivers()->UnsafeList()) {
- if (transceiver->internal()->channel()) {
- std::string transport_name(
- transceiver->internal()->channel()->transport_name());
- media_types_by_transport_name[transport_name].insert(
- transceiver->media_type());
- }
+ for (const auto& transceiver : transceivers) {
+ if (transceiver->internal()->channel()) {
+ std::string transport_name(
+ transceiver->internal()->channel()->transport_name());
+ media_types_by_transport_name[transport_name].insert(
+ transceiver->media_type());
}
}
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index 36a9d2ac743a81e2c4ac8b4abd73d2fd40c3dd40..ea221e697322bd8b8c161edada7a448a68fa7f68 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -563,7 +563,8 @@ class PeerConnection : public PeerConnectionInternal,
// Invoked when TransportController connection completion is signaled.
// Reports stats for all transports in use.
- void ReportTransportStats() RTC_RUN_ON(network_thread());
+ void ReportTransportStats(std::vector<RtpTransceiverProxyRefPtr> transceivers)
+ RTC_RUN_ON(network_thread());
// Gather the usage of IPv4/IPv6 as best connection.
static void ReportBestConnectionState(const cricket::TransportStats& stats);
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index 19cc6ce3cfc8b8b38d45f5df9c28fe6dd01572f5..da8a53ef5d91c9c14dc6f42a10d176c7f6089ada 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -1831,6 +1831,10 @@ TEST_P(PeerConnectionIntegrationTest,
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
callee()->ice_connection_state(), kDefaultTimeout);
+ // Part of reporting the stats will occur on the network thread, so flush it
+ // before checking NumEvents.
+ SendTask(network_thread(), [] {});
+
EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
"WebRTC.PeerConnection.CandidatePairType_UDP",
webrtc::kIceCandidatePairHostNameHostName));
@@ -1959,6 +1963,10 @@ TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
callee()->ice_connection_state(), kDefaultTimeout);
+ // Part of reporting the stats will occur on the network thread, so flush it
+ // before checking NumEvents.
+ SendTask(network_thread(), [] {});
+
// TODO(bugs.webrtc.org/9456): Fix it.
const int num_best_ipv4 = webrtc::metrics::NumEvents(
"WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Philipp Hancke <phancke@microsoft.com>
Date: Thu, 15 Jun 2023 07:21:56 +0200
Subject: sdp: reject duplicate ssrcs in ssrc-groups
while not really covered by
https://www.rfc-editor.org/rfc/rfc5576.html#section-4.2
and using the same SSRC for RTX and primary payload may work
since payload type demuxing *could* be used is not a good idea.
This also applies to flexfec's FEC-FR.
For the nonstandard SIM ssrc-group duplicates make no sense.
This rejects duplicates for unknown ssrc-groups as well.
BUG=chromium:1454860
(cherry picked from commit 6a38a3eb38f732b89ca0d8e36c43a434670c4ef5)
No-Try: true
Change-Id: I3e86101dbd5d6c4099f2fdb7b4a52d5cd0809c5f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308820
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Cr-Original-Commit-Position: refs/heads/main@{#40292}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/309601
Cr-Commit-Position: refs/branch-heads/5735@{#4}
Cr-Branched-From: df7df199abd619e75b9f1d9a7e12fc3f3f748775-refs/heads/main@{#39949}
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index 39b16901a1c8951aa102ea1cdbdbfcf06b9b4b87..02375ad60dcef89b303faa42d3ea0faea6d22a0b 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -3485,6 +3485,11 @@ bool ParseSsrcGroupAttribute(absl::string_view line,
if (!GetValueFromString(line, fields[i], &ssrc, error)) {
return false;
}
+ // Reject duplicates. While not forbidden by RFC 5576,
+ // they don't make sense.
+ if (absl::c_linear_search(ssrcs, ssrc)) {
+ return ParseFailed(line, "Duplicate SSRC in ssrc-group", error);
+ }
ssrcs.push_back(ssrc);
}
ssrc_groups->push_back(SsrcGroup(semantics, ssrcs));
diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc
index 7880af069380a514730466112364e4529bef112f..1e5b669ccaef2f6696383c6da1864f9a5e5dc8a8 100644
--- a/pc/webrtc_sdp_unittest.cc
+++ b/pc/webrtc_sdp_unittest.cc
@@ -4722,3 +4722,29 @@ TEST_F(WebRtcSdpTest, ParseIgnoreUnknownSsrcSpecificAttribute) {
SdpParseError error;
ASSERT_TRUE(webrtc::SdpDeserialize(sdp, &output, &error));
}
+
+TEST_F(WebRtcSdpTest, RejectDuplicateSsrcInSsrcGroup) {
+ std::string sdp =
+ "v=0\r\n"
+ "o=- 0 3 IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n"
+ "a=group:BUNDLE 0\r\n"
+ "a=fingerprint:sha-1 "
+ "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
+ "a=setup:actpass\r\n"
+ "a=ice-ufrag:ETEn\r\n"
+ "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n"
+ "m=video 9 UDP/TLS/RTP/SAVPF 96 97\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=sendonly\r\n"
+ "a=mid:0\r\n"
+ "a=rtpmap:96 VP8/90000\r\n"
+ "a=rtpmap:97 rtx/90000\r\n"
+ "a=fmtp:97 apt=96\r\n"
+ "a=ssrc-group:FID 1234 1234\r\n"
+ "a=ssrc:1234 cname:test\r\n";
+ JsepSessionDescription jdesc(kDummyType);
+ EXPECT_FALSE(SdpDeserialize(sdp, &jdesc));
+}

View File

@@ -117,7 +117,6 @@
"parallel/test-webcrypto-sign-verify-eddsa",
"parallel/test-worker-debug",
"parallel/test-worker-stdio",
"parallel/test-v8-serialize-leak",
"parallel/test-zlib-unused-weak",
"report/test-report-fatal-error",
"report/test-report-getreport",

View File

@@ -77,7 +77,7 @@ async function validateReleaseAssets (release, validatingRelease) {
} else {
await verifyShasumsForRemoteFiles(downloadUrls)
.catch(err => {
console.log(`${fail} error verifyingShasums`, err);
console.error(`${fail} error verifyingShasums`, err);
});
}
const azRemoteFiles = azRemoteFilesForVersion(release.tag_name);
@@ -90,7 +90,7 @@ function check (condition, statement, exitIfFail = false) {
console.log(`${pass} ${statement}`);
} else {
failureCount++;
console.log(`${fail} ${statement}`);
console.error(`${fail} ${statement}`);
if (exitIfFail) process.exit(1);
}
}
@@ -212,7 +212,7 @@ function runScript (scriptName, scriptArgs, cwd) {
try {
return execSync(scriptCommand, scriptOptions);
} catch (err) {
console.log(`${fail} Error running ${scriptName}`, err);
console.error(`${fail} Error running ${scriptName}`, err);
process.exit(1);
}
}
@@ -266,7 +266,8 @@ async function createReleaseShasums (release) {
repo: targetRepo,
asset_id: existingAssets[0].id
}).catch(err => {
console.log(`${fail} Error deleting ${fileName} on GitHub:`, err);
console.error(`${fail} Error deleting ${fileName} on GitHub:`, err);
process.exit(1);
});
}
console.log(`Creating and uploading the release ${fileName}.`);
@@ -292,7 +293,7 @@ async function uploadShasumFile (filePath, fileName, releaseId) {
data: fs.createReadStream(filePath),
name: fileName
}).catch(err => {
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err);
console.error(`${fail} Error uploading ${filePath} to GitHub:`, err);
process.exit(1);
});
}
@@ -301,13 +302,13 @@ function saveShaSumFile (checksums, fileName) {
return new Promise((resolve, reject) => {
temp.open(fileName, (err, info) => {
if (err) {
console.log(`${fail} Could not create ${fileName} file`);
console.error(`${fail} Could not create ${fileName} file`);
process.exit(1);
} else {
fs.writeFileSync(info.fd, checksums);
fs.close(info.fd, (err) => {
if (err) {
console.log(`${fail} Could close ${fileName} file`);
console.error(`${fail} Could close ${fileName} file`);
process.exit(1);
}
resolve(info.path);
@@ -333,7 +334,7 @@ async function publishRelease (release) {
draft: false,
make_latest: makeLatest ? 'true' : 'false'
}).catch(err => {
console.log(`${fail} Error publishing release:`, err);
console.error(`${fail} Error publishing release:`, err);
process.exit(1);
});
}
@@ -351,13 +352,17 @@ async function makeRelease (releaseToValidate) {
} else {
let draftRelease = await getDraftRelease();
uploadNodeShasums();
uploadIndexJson();
await createReleaseShasums(draftRelease);
// Fetch latest version of release before verifying
draftRelease = await getDraftRelease(pkgVersion, true);
await validateReleaseAssets(draftRelease);
// index.json goes live once uploaded so do these uploads as
// late as possible to reduce the chances it contains a release
// which fails to publish. It has to be done before the final
// publish to ensure there aren't published releases not contained
// in index.json, which causes other problems in downstream projects
uploadIndexJson();
await publishRelease(draftRelease);
console.log(`${pass} SUCCESS!!! Release has been published. Please run ` +
'"npm run publish-to-npm" to publish release to npm.');
@@ -403,7 +408,7 @@ async function verifyDraftGitHubReleaseAssets (release) {
return { url: response.headers.location, file: asset.name };
})).catch(err => {
console.log(`${fail} Error downloading files from GitHub`, err);
console.error(`${fail} Error downloading files from GitHub`, err);
process.exit(1);
});

View File

@@ -64,10 +64,24 @@ if (args.runners !== undefined) {
async function main () {
if (args.electronVersion) {
const versions = await ElectronVersions.create();
if (!versions.isVersion(args.electronVersion)) {
if (args.electronVersion === 'latest') {
args.electronVersion = versions.latest.version;
} else if (args.electronVersion.startsWith('latest@')) {
const majorVersion = parseInt(args.electronVersion.slice('latest@'.length));
const ver = versions.inMajor(majorVersion).slice(-1)[0];
if (ver) {
args.electronVersion = ver.version;
} else {
console.log(`${fail} '${majorVersion}' is not a recognized Electron major version`);
process.exit(1);
}
} else if (!versions.isVersion(args.electronVersion)) {
console.log(`${fail} '${args.electronVersion}' is not a recognized Electron version`);
process.exit(1);
}
const versionString = `v${args.electronVersion}`;
console.log(`Running against Electron ${versionString.green}`);
}
const [lastSpecHash, lastSpecInstallHash] = loadLastSpecHash();

View File

@@ -17,6 +17,7 @@ def main():
chromedriver_name = {
'darwin': 'chromedriver',
'win32': 'chromedriver.exe',
'linux': 'chromedriver',
'linux2': 'chromedriver'
}

View File

@@ -40,6 +40,7 @@
#include "shell/common/logging.h"
#include "shell/common/options_switches.h"
#include "shell/common/platform_util.h"
#include "shell/common/process_util.h"
#include "shell/renderer/electron_renderer_client.h"
#include "shell/renderer/electron_sandboxed_renderer_client.h"
#include "shell/utility/electron_content_utility_client.h"
@@ -82,11 +83,6 @@ constexpr base::StringPiece kElectronDisableSandbox("ELECTRON_DISABLE_SANDBOX");
constexpr base::StringPiece kElectronEnableStackDumping(
"ELECTRON_ENABLE_STACK_DUMPING");
bool IsBrowserProcess(base::CommandLine* cmd) {
std::string process_type = cmd->GetSwitchValueASCII(::switches::kProcessType);
return process_type.empty();
}
// Returns true if this subprocess type needs the ResourceBundle initialized
// and resources loaded.
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
@@ -249,14 +245,12 @@ absl::optional<int> ElectronMainDelegate::BasicStartupComplete() {
// On Windows the terminal returns immediately, so we add a new line to
// prevent output in the same line as the prompt.
if (IsBrowserProcess(command_line))
if (IsBrowserProcess())
std::wcout << std::endl;
#endif // !BUILDFLAG(IS_WIN)
auto env = base::Environment::Create();
gin_helper::Locker::SetIsBrowserProcess(IsBrowserProcess(command_line));
// Enable convenient stack printing. This is enabled by default in
// non-official builds.
if (env->HasVar(kElectronEnableStackDumping))
@@ -289,7 +283,7 @@ absl::optional<int> ElectronMainDelegate::BasicStartupComplete() {
// bugs, but no use in Electron.
base::win::DisableHandleVerifier();
if (IsBrowserProcess(command_line))
if (IsBrowserProcess())
base::win::PinUser32();
#endif
@@ -385,7 +379,7 @@ void ElectronMainDelegate::PreSandboxStartup() {
crash_keys::SetPlatformCrashKey();
#endif
if (IsBrowserProcess(command_line)) {
if (IsBrowserProcess()) {
// Only append arguments for browser process.
// Allow file:// URIs to read other file:// URIs by default.

View File

@@ -18,6 +18,14 @@
#include "sandbox/mac/seatbelt_exec.h" // nogncheck
#endif
extern "C" {
// abort_report_np() records the message in a special section that both the
// system CrashReporter and Crashpad collect in crash reports. Using a Crashpad
// Annotation would be preferable, but this executable cannot depend on
// Crashpad directly.
void abort_report_np(const char* fmt, ...);
}
namespace {
[[maybe_unused]] bool IsEnvSet(const char* name) {
@@ -25,6 +33,20 @@ namespace {
return indicator && indicator[0] != '\0';
}
#if defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
[[noreturn]] void FatalError(const char* format, ...) {
va_list valist;
va_start(valist, format);
char message[4096];
if (vsnprintf(message, sizeof(message), format, valist) >= 0) {
fputs(message, stderr);
abort_report_np("%s", message);
}
va_end(valist);
abort();
}
#endif
} // namespace
int main(int argc, char* argv[]) {
@@ -42,27 +64,23 @@ int main(int argc, char* argv[]) {
uint32_t exec_path_size = 0;
int rv = _NSGetExecutablePath(NULL, &exec_path_size);
if (rv != -1) {
fprintf(stderr, "_NSGetExecutablePath: get length failed\n");
abort();
FatalError("_NSGetExecutablePath: get length failed.");
}
auto exec_path = std::make_unique<char[]>(exec_path_size);
rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size);
if (rv != 0) {
fprintf(stderr, "_NSGetExecutablePath: get path failed\n");
abort();
FatalError("_NSGetExecutablePath: get path failed.");
}
sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt =
sandbox::SeatbeltExecServer::CreateFromArguments(exec_path.get(), argc,
argv);
if (seatbelt.sandbox_required) {
if (!seatbelt.server) {
fprintf(stderr, "Failed to create seatbelt sandbox server.\n");
abort();
FatalError("Failed to create seatbelt sandbox server.");
}
if (!seatbelt.server->InitializeSandbox()) {
fprintf(stderr, "Failed to initialize sandbox.\n");
abort();
FatalError("Failed to initialize sandbox.");
}
}
#endif // defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)

View File

@@ -25,6 +25,25 @@
namespace electron {
namespace {
bool IsValidWrappable(const v8::Local<v8::Value>& obj) {
v8::Local<v8::Object> port = v8::Local<v8::Object>::Cast(obj);
if (!port->IsObject())
return false;
if (port->InternalFieldCount() != gin::kNumberOfInternalFields)
return false;
const auto* info = static_cast<gin::WrapperInfo*>(
port->GetAlignedPointerFromInternalField(gin::kWrapperInfoIndex));
return info && info->embedder == gin::kEmbedderNativeGin;
}
} // namespace
gin::WrapperInfo MessagePort::kWrapperInfo = {gin::kEmbedderNativeGin};
MessagePort::MessagePort() = default;
@@ -47,10 +66,11 @@ void MessagePort::PostMessage(gin::Arguments* args) {
DCHECK(!IsNeutered());
blink::TransferableMessage transferable_message;
gin_helper::ErrorThrower thrower(args->isolate());
v8::Local<v8::Value> message_value;
if (!args->GetNext(&message_value)) {
args->ThrowTypeError("Expected at least one argument to postMessage");
thrower.ThrowTypeError("Expected at least one argument to postMessage");
return;
}
@@ -60,8 +80,23 @@ void MessagePort::PostMessage(gin::Arguments* args) {
v8::Local<v8::Value> transferables;
std::vector<gin::Handle<MessagePort>> wrapped_ports;
if (args->GetNext(&transferables)) {
std::vector<v8::Local<v8::Value>> wrapped_port_values;
if (!gin::ConvertFromV8(args->isolate(), transferables,
&wrapped_port_values)) {
thrower.ThrowTypeError("transferables must be an array of MessagePorts");
return;
}
for (unsigned i = 0; i < wrapped_port_values.size(); ++i) {
if (!IsValidWrappable(wrapped_port_values[i])) {
thrower.ThrowTypeError("Port at index " + base::NumberToString(i) +
" is not a valid port");
return;
}
}
if (!gin::ConvertFromV8(args->isolate(), transferables, &wrapped_ports)) {
args->ThrowError();
thrower.ThrowTypeError("Passed an invalid MessagePort");
return;
}
}
@@ -69,9 +104,8 @@ void MessagePort::PostMessage(gin::Arguments* args) {
// Make sure we aren't connected to any of the passed-in ports.
for (unsigned i = 0; i < wrapped_ports.size(); ++i) {
if (wrapped_ports[i].get() == this) {
gin_helper::ErrorThrower(args->isolate())
.ThrowError("Port at index " + base::NumberToString(i) +
" contains the source port.");
thrower.ThrowError("Port at index " + base::NumberToString(i) +
" contains the source port.");
return;
}
}

View File

@@ -27,8 +27,6 @@ namespace electron {
namespace {
const int kMaxScanRetries = 5;
void OnDeviceChosen(const content::BluetoothChooser::EventHandler& handler,
const std::string& device_id) {
if (device_id.empty()) {
@@ -66,29 +64,15 @@ void BluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
}
void BluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
bool idle_state = false;
switch (state) {
case DiscoveryState::FAILED_TO_START:
refreshing_ = false;
event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, "");
break;
return;
case DiscoveryState::IDLE:
refreshing_ = false;
if (device_map_.empty()) {
auto event = ++num_retries_ > kMaxScanRetries
? content::BluetoothChooserEvent::CANCELLED
: content::BluetoothChooserEvent::RESCAN;
event_handler_.Run(event, "");
} else {
bool prevent_default = api_web_contents_->Emit(
"select-bluetooth-device", GetDeviceList(),
base::BindOnce(&OnDeviceChosen, event_handler_));
if (!prevent_default) {
auto it = device_map_.begin();
auto device_id = it->first;
event_handler_.Run(content::BluetoothChooserEvent::SELECTED,
device_id);
}
}
idle_state = true;
break;
case DiscoveryState::DISCOVERING:
// The first time this state fires is due to a rescan triggering so set a
@@ -101,6 +85,18 @@ void BluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
}
break;
}
bool prevent_default =
api_web_contents_->Emit("select-bluetooth-device", GetDeviceList(),
base::BindOnce(&OnDeviceChosen, event_handler_));
if (!prevent_default && idle_state) {
if (device_map_.empty()) {
event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, "");
} else {
auto it = device_map_.begin();
auto device_id = it->first;
event_handler_.Run(content::BluetoothChooserEvent::SELECTED, device_id);
}
}
}
void BluetoothChooser::AddOrUpdateDevice(const std::string& device_id,

View File

@@ -44,7 +44,6 @@ class BluetoothChooser : public content::BluetoothChooser {
std::map<std::string, std::u16string> device_map_;
api::WebContents* api_web_contents_;
EventHandler event_handler_;
int num_retries_ = 0;
bool refreshing_ = false;
bool rescan_ = false;
};

View File

@@ -35,12 +35,11 @@ const char MenuBar::kViewClassName[] = "ElectronMenuBar";
MenuBar::MenuBar(NativeWindow* window, RootView* root_view)
: background_color_(kDefaultColor), window_(window), root_view_(root_view) {
const ui::NativeTheme* theme = root_view_->GetNativeTheme();
RefreshColorCache(theme);
UpdateViewColors();
#if BUILDFLAG(IS_WIN)
SetBackground(views::CreateThemedSolidBackground(ui::kColorMenuBackground));
background_color_ = GetBackground()->get_color();
#endif
RefreshColorCache(theme);
UpdateViewColors();
SetFocusBehavior(FocusBehavior::ALWAYS);
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
@@ -209,6 +208,14 @@ void MenuBar::ButtonPressed(size_t id, const ui::Event& event) {
menu_delegate->AddObserver(this);
}
void MenuBar::ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) {
views::AccessiblePaneView::ViewHierarchyChanged(details);
#if BUILDFLAG(IS_WIN)
background_color_ = GetBackground()->get_color();
#endif
}
void MenuBar::RefreshColorCache(const ui::NativeTheme* theme) {
if (theme) {
#if BUILDFLAG(IS_LINUX)
@@ -217,6 +224,8 @@ void MenuBar::RefreshColorCache(const ui::NativeTheme* theme) {
gtk::GetFgColor("GtkMenuBar#menubar GtkMenuItem#menuitem GtkLabel");
disabled_color_ = gtk::GetFgColor(
"GtkMenuBar#menubar GtkMenuItem#menuitem:disabled GtkLabel");
#elif BUILDFLAG(IS_WIN)
background_color_ = GetBackground()->get_color();
#endif
}
}

View File

@@ -50,6 +50,9 @@ class MenuBar : public views::AccessiblePaneView,
ElectronMenuModel** menu_model,
views::MenuButton** button);
void ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) override;
private:
// MenuDelegate::Observer:
void OnBeforeExecuteCommand() override;

View File

@@ -430,24 +430,32 @@ void WebContentsPreferences::OverrideWebkitPrefs(
prefs->web_security_enabled = web_security_;
prefs->allow_running_insecure_content = allow_running_insecure_content_;
if (auto font =
default_font_family_.find("standard") != default_font_family_.end())
prefs->standard_font_family_map[blink::web_pref::kCommonScript] = font;
if (auto font =
default_font_family_.find("serif") != default_font_family_.end())
prefs->serif_font_family_map[blink::web_pref::kCommonScript] = font;
if (auto font =
default_font_family_.find("sansSerif") != default_font_family_.end())
prefs->sans_serif_font_family_map[blink::web_pref::kCommonScript] = font;
if (auto font =
default_font_family_.find("monospace") != default_font_family_.end())
prefs->fixed_font_family_map[blink::web_pref::kCommonScript] = font;
if (auto font =
default_font_family_.find("cursive") != default_font_family_.end())
prefs->cursive_font_family_map[blink::web_pref::kCommonScript] = font;
if (auto font =
default_font_family_.find("fantasy") != default_font_family_.end())
prefs->fantasy_font_family_map[blink::web_pref::kCommonScript] = font;
if (!default_font_family_.empty()) {
if (auto iter = default_font_family_.find("standard");
iter != default_font_family_.end())
prefs->standard_font_family_map[blink::web_pref::kCommonScript] =
iter->second;
if (auto iter = default_font_family_.find("serif");
iter != default_font_family_.end())
prefs->serif_font_family_map[blink::web_pref::kCommonScript] =
iter->second;
if (auto iter = default_font_family_.find("sansSerif");
iter != default_font_family_.end())
prefs->sans_serif_font_family_map[blink::web_pref::kCommonScript] =
iter->second;
if (auto iter = default_font_family_.find("monospace");
iter != default_font_family_.end())
prefs->fixed_font_family_map[blink::web_pref::kCommonScript] =
iter->second;
if (auto iter = default_font_family_.find("cursive");
iter != default_font_family_.end())
prefs->cursive_font_family_map[blink::web_pref::kCommonScript] =
iter->second;
if (auto iter = default_font_family_.find("fantasy");
iter != default_font_family_.end())
prefs->fantasy_font_family_map[blink::web_pref::kCommonScript] =
iter->second;
}
if (default_font_size_)
prefs->default_font_size = *default_font_size_;

View File

@@ -59,12 +59,10 @@ v8::Local<v8::Promise> OpenExternal(const GURL& url, gin::Arguments* args) {
v8::Local<v8::Promise> handle = promise.GetHandle();
platform_util::OpenExternalOptions options;
if (args->Length() >= 2) {
gin::Dictionary obj(nullptr);
if (args->GetNext(&obj)) {
obj.Get("activate", &options.activate);
obj.Get("workingDirectory", &options.working_dir);
}
gin_helper::Dictionary obj;
if (args->GetNext(&obj)) {
obj.Get("activate", &options.activate);
obj.Get("workingDirectory", &options.working_dir);
}
platform_util::OpenExternal(

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