Compare commits

..

63 Commits

Author SHA1 Message Date
Pedro Pontes
70a66589ae chore: cherry-pick 8 changes from 3-M123 and M1nn (#41856)
* chore: [27-x-y] cherry-pick 3 changes from 3-M123

* a65e511a14b4 from DirectXShaderCompiler
* f6672dbbe223 from angle
* 1b1f34234346 from chromium

* chore: [27-x-y] cherry-pick 4 later changes from M1nn

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-04-15 09:26:14 -07:00
Pedro Pontes
6d5b65ec35 chore: cherry-pick 1 change from Release-2-M123 (#41777) 2024-04-05 14:13:38 -04:00
Pedro Pontes
ec2adf0b2e chore: cherry-pick 1 change from Release-3-M122 (#41608)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-04-02 14:59:30 +02:00
Pedro Pontes
2d9eaffb98 chore: cherry-pick 8 changes from Release-1-M123 (#41748)
* chore: cherry-pick 8 changes from Release-1-M123

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-04-01 10:35:05 -04:00
trop[bot]
3d3bd64ab2 ci: use CircleCI hosted macOS arm64 runners for testing (#41666)
* ci: use CircleCI hosted macOS arm64 runners for testing

(cherry picked from commit 6ca2aa6b06)

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

* ci: Use same version of xcode/macOS for both arm and x64 testing

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-03-22 12:27:25 -04:00
Pedro Pontes
8b9170b664 chore: cherry-pick 1 change from Release-0-M123 (#41633) 2024-03-21 12:58:39 +01:00
Pedro Pontes
6b2c470f46 chore: cherry-pick 1 change from Release-2-M122 (#41521) 2024-03-13 16:21:04 +01:00
Cheng Zhao
f53fad8abb chore: update src_preload_function_for_environment.patch (#41503)
* chore: update src_preload_function_for_environment.patch

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-03-04 10:26:12 -05:00
Pedro Pontes
7b2c526a43 chore: cherry-pick 1 change from Release-1-M122 (#41488) 2024-03-04 16:46:09 +09:00
trop[bot]
1da86c0fbf ci: add logging to uploading to GitHub releases (#41457)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-02-28 21:35:23 -08:00
trop[bot]
166bcd3208 chore: fix import from patches.py in script/lib/git.py (#41435)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2024-02-28 14:54:17 +09:00
Charles Kerr
133cd29201 refactor: inline simple getters, pt . 2 (#41338)
refactor: inline simple getters, pt . 2 (#41254)

* refactor: inline AutofillPopup::line_count()

refactor: inline AutofillPopup::value_at()

refactor: inline AutofillPopup::label_at()

* refactor: inline NativeWindow::aspect_ratio()

refactor: inline NativeWindow::aspect_ratio_extra_size()

* refactor: inline BrowserProcessImpl::linux_storage_backend()

* refactor: inline ElectronMenuModel::sharing_item()

* refactor: inline Browser::badge_count()

* refactor: inline WebContents::is_guest()

refactor: inline InspectableWebContents::is_guest()

* refactor: inline InspectableWebContents::dev_tool_bounds()

* refactor: inline WebContents::type()
2024-02-28 12:58:49 +09:00
Pedro Pontes
3511eb1a8e chore: cherry-pick 1 change Release-0-M122 (#41406) 2024-02-22 11:32:38 -05:00
Pedro Pontes
426cd1d68c chore: cherry-pick 4 changes from Release-2-M121 and Release-3-M121 (#41375)
* chore: cherry-pick 4 changes from Release-2-M121 and Release-3-M121

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-02-20 15:35:53 +01:00
trop[bot]
2c152014c4 fix: Ignore -webkit-app-region: drag; when window is in full screen mode. (#41331)
fix: Ignore `-webkit-app-region: drag;` when window is in full screen mode. (#41307)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mikhail Leliakin <leliakin@canva.com>
2024-02-16 10:32:56 -06:00
trop[bot]
d1a6d98a93 build: peg to a specific depot_tools so that we can use goma on older branches (#41343)
chore: peg to a specific depot_tools so that we can use goma on older branches

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-02-14 13:53:10 -08:00
trop[bot]
ea680012de build: allow custom refs for patch import & export (#41320)
feat: allow custom refs for patch import & export (#41306)

* feat: allow custom refs for patch import & export

feat: add Patch-Dir metainfo, a sibling to Patch-Filename

* chore: copyediting

* refactor: minor copyediting

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-02-13 00:37:48 -06:00
Charles Kerr
d635f34565 build: export matching patches (#41303)
build: export matching patches (#41292)
2024-02-12 10:17:54 -06:00
trop[bot]
18bf1d2f59 fix: destroy NodeService message pipe last (#41300)
refactor: destroy NodeService message pipe last

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-02-10 20:41:42 -06:00
trop[bot]
4a0d4975f3 docs: note EXIF data unsupported in nativeImage (#41282)
* docs: note EXIF data unsupported in nativeImage

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

* Update docs/api/native-image.md

Co-authored-by: David Sanders <dsanders11@ucsbalum.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>
2024-02-09 10:55:45 +09:00
Shelley Vohr
56ac51cfa2 fix: webview zoom level persistence on navigation (#41269) 2024-02-08 10:28:50 +09:00
trop[bot]
d297808531 refactor: KeyWeakMap cleanup (#41251)
* refactor: make KeyWeakMap::KeyObject private

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

* perf: avoid redundant map lookup

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

* refactor: remove unused KeyWeakMap::Has()

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

* refactor: make KeyWeakMap dtor nonvirtual

no inheritance used, so no need for virtual dtor?

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

* chore: fix KeyWeakMap code comment

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

* refactor: use if statement in KeyWeakMap::Get()

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

* refactor: use better variable names in KeyWeakMap::Values()

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-02-08 10:26:35 +09:00
trop[bot]
077c4addd5 build: add flag for setting vendor version (#41257)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2024-02-07 12:31:06 +01:00
trop[bot]
c3c5734fa8 refactor: remove deprecated BrowserContext::ResourceContext (#41244) 2024-02-06 10:33:44 -06:00
Cheng Zhao
62c97ffecf refactor: type-safe imports in lib/node/init.ts (#41187)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2024-02-06 11:04:24 +09:00
trop[bot]
24b841cbcd refactor: replace use of deprecated base::JSONWriter::WriteJson() (#41222)
* refactor: use base::WriteJson() in ListValueToNSArray()

refactor: use base::WriteJson() in DictionaryValueToNSDictionary()

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

* refactor: use base::WriteJson() in Debugger::SendCommand()

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

* refactor: use base::WriteJson() in ScriptingExecuteScriptFunction::Run()

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

* refactor: use base::WriteJson() in HandleAccessibilityRequestCallback()

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-02-03 21:48:16 -06:00
Shelley Vohr
b1377d42d9 chore: cherry-pick 4 changes from Release-1-M121 (#41176)
* chore: [27-x-y] cherry-pick 4 changes from Release-1-M121

* d4a197e4913f from chromium
* 8755f76bec32 from chromium
* e321f354a613 from chromium
* 4a98f9e304be from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-02-02 12:33:18 +01:00
trop[bot]
ca92ebff25 fix: select-usb-device should respect filters option (#41196)
fix: select-usb-device should respect filters option

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-01-31 14:44:15 -05:00
Cheng Zhao
f6af8959c3 fix: update osk patch to fix more corner cases (#41151) 2024-01-29 12:52:10 -05:00
trop[bot]
94d5a7429d fix: potential async_hooks crash in NotifyWindowRestore on Windows (#41144)
* fix: potential async_hooks crash in NotifyWindowRestore on Windows

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

* fix: don't use CallbackScope for Error objects

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>
2024-01-28 20:37:12 +01:00
Cheng Zhao
d5065e5ec5 fix: apply module search paths restriction on worker and child process (#41139) 2024-01-26 09:28:22 -06:00
Cheng Zhao
2d559ca855 chore: remove node patches by using the preload feature (#41115)
* chore: remove node patches by using the preload feature

* chore: fix node tests caused by filename change
2024-01-26 17:28:11 +09:00
Pedro Pontes
f9ac250f6d chore: cherry-pick 2 changes from Release-0-M121 (#41106)
* chore: [27-x-y] cherry-pick 2 changes from Release-0-M121

* cc07a95bc309 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-01-25 15:18:14 -05:00
trop[bot]
b87b14d739 docs: update Playwright automated-testing guide (#41096)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Max Schmitt <max@schmitt.mx>
2024-01-25 15:44:38 +09:00
trop[bot]
5c3ab4e1ee fix: only remove hijackable envs from foreign parent (#41100)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2024-01-25 10:14:05 +09:00
trop[bot]
08ce63f8a5 fix: use HasStyleMask(NSWindowStyleMaskResizable) instead of IsResizable() for enabling/disabling window maximize button (#41027)
* fix: use `HasStyleMask(NSWindowStyleMaskResizable)` instead of `IsResizable()` for enabling/disabling window maximize button

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

* Format

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Tamás Zahola <tzahola@gmail.com>
2024-01-23 18:41:40 +09:00
trop[bot]
72332f4574 chore: cleanup tests creating crashpad handler in the test runner process (#41050)
chore: cleanup tests creating crashpad handler in the test runner process (#40668)

* chore: cleanup tests creating crashpad handler in the test runner process

* ci: logging

* ci: enable logging

* ci: more logging

* ci: run all tests

* ci: more logging

* ci: increase timeout

* Revert "ci: increase timeout"

This reverts commit 870f74455d.

* Revert "ci: more logging"

This reverts commit 46837f8b3a.

* Revert "ci: run all tests"

This reverts commit 6a7889ce67.

* Revert "ci: more logging"

This reverts commit 351473ab43.

* Revert "ci: enable logging"

This reverts commit 194109ed5a.

* Revert "ci: logging"

This reverts commit 9a3396fc7a.

* chore: disable flaky ia32 tests

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Robo <hop2deep@gmail.com>
2024-01-18 20:33:15 -05:00
trop[bot]
0c195c0e20 fix: modal rounding on nonmodal windows (#41035)
* fix: modal rounding on nonmodal windows

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

* chore: feedback from review

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>
2024-01-18 14:31:07 -05:00
trop[bot]
8b1d8d7e6a fix: crash when dialog.showMessageBoxSync with missing buttons (#41041)
* fix: crash when dialog.showMessageBoxSync missing buttons

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

* chore: feedback from review

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>
2024-01-18 18:17:21 +01:00
Milan Burda
8c0365a276 feat: add net module to utility process (#40968)
feat: add net module to utility process (#40017)

Co-authored-by: Milan Burda <miburda@microsoft.com>
2024-01-18 09:57:19 -05:00
trop[bot]
c9c159db15 refactor: remove deprecated ToInternalValue() (#41020)
* refactor: do not use deprecated ToInternalValue() in ElectronExtensionLoader::FinishExtensionLoad()

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

* refactor: do not use deprecated ToInternalValue() in NotificationPresenterWin::SaveIconToFilesystem()

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

* chore: rename temp variable to now_usec for clarity

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-01-17 18:15:42 +01:00
Keeley Hammond
b3ca1a1f96 chore: cherry-pick 3 changes from Release-5-M120 (#41014)
* chore: [27-x-y] cherry-pick 3 changes from Release-5-M120

* 46cb67e3b296 from v8
* c1cda70a433a from chromium
* 78dd4b31847a from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-01-16 19:24:58 -08:00
trop[bot]
1a99aa73a9 build: log got error response bodies (#40975)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-01-16 19:52:06 -05:00
Samuel Attard
503c81785d chore: cherry-pick 389ea9be7d68 from v8 (#40971)
* chore: cherry-pick 389ea9be7d68 from v8

* chore: update patches
2024-01-16 19:50:25 -05:00
trop[bot]
6a504f260e build: fix mojom_ts_generator empty module path failure (#41011)
build: fix mojom_ts_generator empty module path failure

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-01-16 16:58:58 -05:00
trop[bot]
aca67b1761 fix: InAppPurchase pre-emptive deallocation (#40955)
* fix: InAppPurchase pre-emptive deallocation

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

* test: try re-enabling IAP tests

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>
2024-01-15 11:03:53 +01:00
trop[bot]
b7a9bdc425 build: use container runner for arm tests (#40932)
* build: use aks arm64 test runners

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* build: better image

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* build: even more stuff

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* build: arm par

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* build: use aks arm32

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* build: arm32 par

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* build: get test timings from abs paths

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* build: avoid realpath, use echo

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* chore: fix contentTracing test

* cry

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2024-01-11 00:28:08 +13:00
trop[bot]
ad0b24cfe2 fix: crash using powerMonitor before ready event (#40923)
* fix: crash using powerMonitor before ready event

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

* refactor: continue using DBusBluezManagerWrapperLinux

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>
2024-01-09 17:18:55 +01:00
Pedro Pontes
6db0b9c70d chore: cherry-pick 8 changes from Release-3-M120 (#40900)
* chore: [27-x-y] cherry-pick 5 changes from Release-3-M120

* 5b2fddadaa12 from chromium
* cd9486849ba3 from sqlite
* 50a1bddfca85 from chromium
* 0c1d249c3fe2 from angle
* 01f439363dcb from angle

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-01-08 22:33:38 +01:00
trop[bot]
79be0be8cb fix: macOS maximize button shouldn't be disabled just because the window is non-fullscreenable (#40895)
* fix: macOS maximize button shouldn't be disabled just because the window is non-fullscreenable

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

* add test

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

* fix test by enabling maximize button if `resizable && (maximizable || fullscreenable)` instead of `(resizable && maximizable) && fullscreenable`

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Tamás Zahola <tzahola@gmail.com>
2024-01-08 12:56:07 -05:00
trop[bot]
c12f2eec55 docs: add missing vibrancy breaking change (#40905)
docs: add missing vibranch change

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-01-07 22:02:05 -08:00
trop[bot]
3ed0d0a502 fix: ignore all NODE_ envs from foreign parent in node process (#40879)
* fix: ignore all NODE_ envs from foreign parent

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

* fix: recognize ad-hoc signed binary

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2024-01-04 10:57:49 +01:00
Calvin
8471e47507 fix: titlebar incorrectly displayed on frameless windows (#40868)
Manual backport of #40749 (a208d45aca)

Co-authored-by: Bruno Henrique da Silva <bruno.d@miro.com>
2024-01-03 09:57:28 +01:00
Pedro Pontes
a7cdf2c7ad chore: cherry-pick 7 changes from Release-1-M120 (#40802)
* chore: [27-x-y] cherry-pick 7 changes from Release-1-M120

* 998e947b265f from chromium
* 021598ea43c1 from chromium
* 76340163a820 from chromium
* f15cfb9371c4 from chromium
* 4ca62c7a8b88 from chromium
* cbd09b2ca928 from v8
* 58bc7b8bb840 from libavif

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-01-02 15:33:38 -05:00
Pedro Pontes
fde45bcab8 chore: cherry-pick 1 changes from Release-2-M120 (#40807)
* chore: [27-x-y] cherry-pick 1 changes from Release-2-M120

* 8d607d3921b8 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-12-21 12:00:06 -06:00
Robo
40e2d6e2f0 fix: save to file option not working in performance tab of devtools (#40753) 2023-12-14 17:56:04 +09:00
trop[bot]
267cbc841e feat: enable code cache for custom protocols (#40708)
* feat: enable code cache for custom protocols

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

* chore: remove trop reference to off-topic patch

* chore: update feat_allow_code_cache_in_custom_schemes.patch

* chore: update patches

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-12-13 12:40:03 -06:00
Pedro Pontes
0cb2077ab3 chore: cherry-pick 1 changes from Release-0-M120 (#40724)
* chore: [27-x-y] cherry-pick 1 changes from Release-0-M120

* 5fde415e06f9 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-12-12 21:46:02 -06:00
trop[bot]
8605079453 build: fix release notes script bug that omitted edited release-clerk comments (#40655)
* build: fix release notes script bug that omitted edited release-clerk comments

add a warning when neither notes nor no-notes are found

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

* fixup! build: fix release notes script bug that omitted edited release-clerk comments

use console.warn() instead of console.log()

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-12-12 12:01:30 +01:00
trop[bot]
b788b3d65c fix: wrong default port in docs (#40742)
fix: wrong default port

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Felipe C <felipe@carassonet.org>
2023-12-12 12:00:36 +01:00
Cheng Zhao
f842ead6bc fix: prevent node mode to be used as script runner by other apps (#40737) 2023-12-11 21:14:53 +01:00
Ryan Manuel
dace26c191 fix: cherry pick 9009d76968b1ec2ed825bc95e47d086ceea07520 from chromium (#40715)
Backport of #40681

See that PR for details.

Notes: Fixed an issue where font requests were incorrectly being sent to dev tools multiple times per resource.
2023-12-11 10:09:52 +09:00
trop[bot]
81984bc728 fix: add missing set_wants_to_be_visible(true) to NativeWindowMac::ShowInactive() (#40658)
* fix: add missing set_wants_to_be_visible(true) to NativeWindowMac::ShowInactive()

Co-authored-by: zaza <tamas@miro.com>

* add test

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: zaza <tamas@miro.com>
Co-authored-by: Tamás Zahola <tzahola@gmail.com>
2023-12-08 13:33:51 +01:00
223 changed files with 13818 additions and 3073 deletions

View File

@@ -75,17 +75,15 @@ executors:
resource_class: << parameters.size >>
# Electron Runners
apple-silicon:
resource_class: electronjs/macos-arm64
machine: true
linux-arm:
resource_class: electronjs/linux-arm
machine: true
resource_class: electronjs/aks-linux-arm-test
docker:
- image: ghcr.io/electron/test:arm32v7-8e0f85b708fa58e28e4824954d6fd55adfda5e9e
linux-arm64:
resource_class: electronjs/linux-arm64
machine: true
resource_class: electronjs/aks-linux-arm-test
docker:
- image: ghcr.io/electron/test:arm64v8-76d5d29e247972da3855a01c2d8cf72c5998233a
# The config expects the following environment variables to be set:
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
@@ -250,6 +248,10 @@ step-depot-tools-get: &step-depot-tools-get
name: Get depot tools
command: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
cd depot_tools
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
cd ..
if [ "`uname`" == "Darwin" ]; then
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
@@ -1656,17 +1658,15 @@ commands:
export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
export MOCHA_TIMEOUT=180000
echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
(cd electron && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
else
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging)
else
if [ "$TARGET_ARCH" == "ia32" ]; then
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
fi
(cd electron && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
fi
if [ "$TARGET_ARCH" == "ia32" ]; then
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
fi
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
fi
- store_test_results:
path: src/junit
@@ -2296,6 +2296,7 @@ jobs:
<<: *env-global
<<: *env-headless-testing
<<: *env-stack-dumping
parallelism: 3
steps:
- electron-tests:
artifact-key: linux-arm
@@ -2307,6 +2308,7 @@ jobs:
<<: *env-global
<<: *env-headless-testing
<<: *env-stack-dumping
parallelism: 3
steps:
- electron-tests:
artifact-key: linux-arm64
@@ -2324,8 +2326,11 @@ jobs:
- electron-tests:
artifact-key: darwin-x64
darwin-testing-arm64-tests:
executor: apple-silicon
darwin-testing-arm64-tests:
executor:
name: macos
size: macos.m1.medium.gen1
version: 14.0.0
environment:
<<: *env-mac-large
<<: *env-stack-dumping
@@ -2349,7 +2354,10 @@ jobs:
artifact-key: mas-x64
mas-testing-arm64-tests:
executor: apple-silicon
executor:
name: macos
size: macos.m1.medium.gen1
version: 14.0.0
environment:
<<: *env-mac-large
<<: *env-stack-dumping

View File

@@ -164,15 +164,6 @@ npm_action("build_electron_definitions") {
outputs = [ "$target_gen_dir/tsc/typings/electron.d.ts" ]
}
webpack_build("electron_asar_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.asar_bundle_deps
config_file = "//electron/build/webpack/webpack.config.asar.js"
out_file = "$target_gen_dir/js2c/asar_bundle.js"
}
webpack_build("electron_browser_bundle") {
deps = [ ":build_electron_definitions" ]
@@ -218,6 +209,15 @@ webpack_build("electron_isolated_renderer_bundle") {
out_file = "$target_gen_dir/js2c/isolated_bundle.js"
}
webpack_build("electron_node_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.node_bundle_deps
config_file = "//electron/build/webpack/webpack.config.node.js"
out_file = "$target_gen_dir/js2c/node_init.js"
}
webpack_build("electron_utility_bundle") {
deps = [ ":build_electron_definitions" ]
@@ -229,9 +229,9 @@ webpack_build("electron_utility_bundle") {
action("electron_js2c") {
deps = [
":electron_asar_bundle",
":electron_browser_bundle",
":electron_isolated_renderer_bundle",
":electron_node_bundle",
":electron_renderer_bundle",
":electron_sandboxed_renderer_bundle",
":electron_utility_bundle",
@@ -239,9 +239,9 @@ action("electron_js2c") {
]
sources = [
"$target_gen_dir/js2c/asar_bundle.js",
"$target_gen_dir/js2c/browser_init.js",
"$target_gen_dir/js2c/isolated_bundle.js",
"$target_gen_dir/js2c/node_init.js",
"$target_gen_dir/js2c/renderer_init.js",
"$target_gen_dir/js2c/sandbox_bundle.js",
"$target_gen_dir/js2c/utility_init.js",

View File

@@ -94,6 +94,11 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: |
cd depot_tools
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
cd ..
- 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"

View File

@@ -92,6 +92,11 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: |
cd depot_tools
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
cd ..
- 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"

View File

@@ -1,5 +0,0 @@
module.exports = require('./webpack.config.base')({
target: 'asar',
alwaysHasNode: true,
targetDeletesNodeGlobals: true
});

View File

@@ -0,0 +1,4 @@
module.exports = require('./webpack.config.base')({
target: 'node',
alwaysHasNode: true
});

View File

@@ -15,4 +15,15 @@ buildflag_header("buildflags") {
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
]
if (electron_vendor_version != "") {
result = string_split(electron_vendor_version, ":")
flags += [
"HAS_VENDOR_VERSION=true",
"VENDOR_VERSION_NAME=\"${result[0]}\"",
"VENDOR_VERSION_VALUE=\"${result[1]}\"",
]
} else {
flags += [ "HAS_VENDOR_VERSION=false" ]
}
}

View File

@@ -23,4 +23,10 @@ declare_args() {
# Packagers and vendor builders should set this in gn args to avoid running
# the script that reads git tag.
override_electron_version = ""
# Define an extra item that will show in process.versions, the value must
# be in the format of "key:value".
# Packagers and vendor builders can set this in gn args to attach extra info
# about the build in the binary.
electron_vendor_version = ""
}

View File

@@ -2,7 +2,7 @@
> Make HTTP/HTTPS requests.
Process: [Main](../glossary.md#main-process)<br />
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)<br />
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
`ClientRequest` implements the [Writable Stream](https://nodejs.org/api/stream.html#stream_writable_streams)

View File

@@ -2,7 +2,7 @@
> Handle responses to HTTP/HTTPS requests.
Process: [Main](../glossary.md#main-process)<br />
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)<br />
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
`IncomingMessage` implements the [Readable Stream](https://nodejs.org/api/stream.html#stream_readable_streams)

View File

@@ -51,6 +51,13 @@ Check the _Size requirements_ section in [this article][icons].
[icons]: https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-icons
:::note
EXIF metadata is currently not supported and will not be taken into account during
image encoding and decoding.
:::
## High Resolution Image
On platforms that have high-DPI support such as Apple Retina displays, you can

View File

@@ -2,7 +2,7 @@
> Issue HTTP/HTTPS requests using Chromium's native networking library
Process: [Main](../glossary.md#main-process)
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)
The `net` module is a client-side API for issuing HTTP(S) requests. It is
similar to the [HTTP](https://nodejs.org/api/http.html) and
@@ -119,6 +119,9 @@ protocol.handle('https', (req) => {
})
```
Note: in the [utility process](../glossary.md#utility-process) custom protocols
are not supported.
### `net.isOnline()`
Returns `boolean` - Whether there is currently internet connection.

View File

@@ -61,8 +61,9 @@ The `protocol` module has the following methods:
module gets emitted and can be called only once.
Registers the `scheme` as standard, secure, bypasses content security policy for
resources, allows registering ServiceWorker, supports fetch API, and streaming
video/audio. Specify a privilege with the value of `true` to enable the capability.
resources, allows registering ServiceWorker, supports fetch API, streaming
video/audio, and V8 code cache. Specify a privilege with the value of `true` to
enable the capability.
An example of registering a privileged scheme, that bypasses Content Security
Policy:

View File

@@ -1356,6 +1356,10 @@ registered.
Sets the directory to store the generated JS [code cache](https://v8.dev/blog/code-caching-for-devs) for this session. The directory is not required to be created by the user before this call, the runtime will create if it does not exist otherwise will use the existing directory. If directory cannot be created, then code cache will not be used and all operations related to code cache will fail silently inside the runtime. By default, the directory will be `Code Cache` under the
respective user data folder.
Note that by default code cache is only enabled for http(s) URLs, to enable code
cache for custom protocols, `codeCache: true` and `standard: true` must be
specified when registering the protocol.
#### `ses.clearCodeCaches(options)`
* `options` Object

View File

@@ -9,3 +9,5 @@
* `supportFetchAPI` boolean (optional) - Default false.
* `corsEnabled` boolean (optional) - Default false.
* `stream` boolean (optional) - Default false.
* `codeCache` boolean (optional) - Enable V8 code cache for the scheme, only
works when `standard` is also set to true. Default false.

View File

@@ -45,6 +45,18 @@ systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
nativeTheme.on('updated', () => { /* ... */ })
```
### Removed: Some `window.setVibrancy` options on macOS
The following vibrancy options have been removed:
* 'light'
* 'medium-light'
* 'dark'
* 'ultra-dark'
* 'appearance-based'
These were previously deprecated and have been removed by Apple in 10.15.
### Removed: `webContents.getPrinters`
The `webContents.getPrinters` method has been removed. Use

View File

@@ -196,32 +196,19 @@ support via Electron's support for the [Chrome DevTools Protocol][] (CDP).
### Install dependencies
You can install Playwright through your preferred Node.js package manager. The Playwright team
recommends using the `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` environment variable to avoid
unnecessary browser downloads when testing an Electron app.
```sh npm2yarn
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --save-dev playwright
```
Playwright also comes with its own test runner, Playwright Test, which is built for end-to-end
testing. You can also install it as a dev dependency in your project:
You can install Playwright through your preferred Node.js package manager. It comes with its
own [test runner][playwright-intro], which is built for end-to-end testing:
```sh npm2yarn
npm install --save-dev @playwright/test
```
:::caution Dependencies
This tutorial was written `playwright@1.16.3` and `@playwright/test@1.16.3`. Check out
This tutorial was written with `@playwright/test@1.41.1`. Check out
[Playwright's releases][playwright-releases] page to learn about
changes that might affect the code below.
:::
:::info Using third-party test runners
If you're interested in using an alternative test runner (e.g. Jest or Mocha), check out
Playwright's [Third-Party Test Runner][playwright-test-runners] guide.
:::
### Write your tests
Playwright launches your app in development mode through the `_electron.launch` API.
@@ -229,8 +216,7 @@ To point this API to your Electron app, you can pass the path to your main proce
entry point (here, it is `main.js`).
```js {5} @ts-nocheck
const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test')
const { test, _electron: electron } = require('@playwright/test')
test('launch app', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
@@ -242,9 +228,8 @@ test('launch app', async () => {
After that, you will access to an instance of Playwright's `ElectronApp` class. This
is a powerful class that has access to main process modules for example:
```js {6-11} @ts-nocheck
const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test')
```js {5-10} @ts-nocheck
const { test, _electron: electron } = require('@playwright/test')
test('get isPackaged', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
@@ -263,8 +248,7 @@ It can also create individual [Page][playwright-page] objects from Electron Brow
For example, to grab the first BrowserWindow and save a screenshot:
```js {6-7} @ts-nocheck
const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test')
const { test, _electron: electron } = require('@playwright/test')
test('save screenshot', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
@@ -275,12 +259,11 @@ test('save screenshot', async () => {
})
```
Putting all this together using the PlayWright Test runner, let's create a `example.spec.js`
Putting all this together using the Playwright test-runner, let's create a `example.spec.js`
test file with a single test and assertion:
```js title='example.spec.js' @ts-nocheck
const { _electron: electron } = require('playwright')
const { test, expect } = require('@playwright/test')
const { test, expect, _electron: electron } = require('@playwright/test')
test('example test', async () => {
const electronApp = await electron.launch({ args: ['.'] })
@@ -316,6 +299,7 @@ Running 1 test using 1 worker
:::info
Playwright Test will automatically run any files matching the `.*(test|spec)\.(js|ts|mjs)` regex.
You can customize this match in the [Playwright Test configuration options][playwright-test-config].
It also works with TypeScript out of the box.
:::
:::tip Further reading
@@ -473,10 +457,10 @@ test.after.always('cleanup', async t => {
[chrome-driver]: https://sites.google.com/chromium.org/driver/
[Puppeteer]: https://github.com/puppeteer/puppeteer
[playwright-intro]: https://playwright.dev/docs/intro
[playwright-electron]: https://playwright.dev/docs/api/class-electron/
[playwright-electronapplication]: https://playwright.dev/docs/api/class-electronapplication
[playwright-page]: https://playwright.dev/docs/api/class-page
[playwright-releases]: https://github.com/microsoft/playwright/releases
[playwright-releases]: https://playwright.dev/docs/release-notes
[playwright-test-config]: https://playwright.dev/docs/api/class-testconfig#test-config-test-match
[playwright-test-runners]: https://playwright.dev/docs/test-runners/
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/

View File

@@ -14,10 +14,10 @@ process:
Electron will listen for V8 inspector protocol messages on the specified `port`,
an external debugger will need to connect on this port. The default `port` is
`5858`.
`9229`.
```shell
electron --inspect=5858 your/app
electron --inspect=9229 your/app
```
### `--inspect-brk=[port]`

View File

@@ -214,7 +214,6 @@ auto_filenames = {
"lib/browser/api/message-channel.ts",
"lib/browser/api/module-list.ts",
"lib/browser/api/native-theme.ts",
"lib/browser/api/net-client-request.ts",
"lib/browser/api/net-fetch.ts",
"lib/browser/api/net-log.ts",
"lib/browser/api/net.ts",
@@ -250,12 +249,12 @@ auto_filenames = {
"lib/browser/web-view-events.ts",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.ts",
"lib/common/api/net-client-request.ts",
"lib/common/api/shell.ts",
"lib/common/define-properties.ts",
"lib/common/deprecate.ts",
"lib/common/init.ts",
"lib/common/ipc-messages.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"package.json",
@@ -273,7 +272,6 @@ auto_filenames = {
"lib/common/deprecate.ts",
"lib/common/init.ts",
"lib/common/ipc-messages.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-provider.ts",
"lib/renderer/api/clipboard.ts",
@@ -312,7 +310,6 @@ auto_filenames = {
"lib/common/deprecate.ts",
"lib/common/init.ts",
"lib/common/ipc-messages.ts",
"lib/common/reset-search-paths.ts",
"lib/common/webpack-provider.ts",
"lib/renderer/api/clipboard.ts",
"lib/renderer/api/context-bridge.ts",
@@ -331,10 +328,9 @@ auto_filenames = {
"typings/internal-electron.d.ts",
]
asar_bundle_deps = [
"lib/asar/fs-wrapper.ts",
"lib/asar/init.ts",
"lib/common/webpack-provider.ts",
node_bundle_deps = [
"lib/node/asar-fs-wrapper.ts",
"lib/node/init.ts",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
@@ -343,12 +339,15 @@ auto_filenames = {
]
utility_bundle_deps = [
"lib/browser/api/net-fetch.ts",
"lib/browser/message-port-main.ts",
"lib/common/api/net-client-request.ts",
"lib/common/define-properties.ts",
"lib/common/init.ts",
"lib/common/reset-search-paths.ts",
"lib/common/webpack-globals-provider.ts",
"lib/utility/api/exports/electron.ts",
"lib/utility/api/module-list.ts",
"lib/utility/api/net.ts",
"lib/utility/init.ts",
"lib/utility/parent-port.ts",
"package.json",

View File

@@ -167,6 +167,8 @@ filenames = {
"shell/common/language_util_mac.mm",
"shell/common/mac/main_application_bundle.h",
"shell/common/mac/main_application_bundle.mm",
"shell/common/mac/codesign_util.cc",
"shell/common/mac/codesign_util.h",
"shell/common/node_bindings_mac.cc",
"shell/common/node_bindings_mac.h",
"shell/common/platform_util_mac.mm",
@@ -249,7 +251,6 @@ filenames = {
"shell/browser/api/electron_api_menu.h",
"shell/browser/api/electron_api_native_theme.cc",
"shell/browser/api/electron_api_native_theme.h",
"shell/browser/api/electron_api_net.cc",
"shell/browser/api/electron_api_net_log.cc",
"shell/browser/api/electron_api_net_log.h",
"shell/browser/api/electron_api_notification.cc",
@@ -275,8 +276,6 @@ filenames = {
"shell/browser/api/electron_api_system_preferences.h",
"shell/browser/api/electron_api_tray.cc",
"shell/browser/api/electron_api_tray.h",
"shell/browser/api/electron_api_url_loader.cc",
"shell/browser/api/electron_api_url_loader.h",
"shell/browser/api/electron_api_utility_process.cc",
"shell/browser/api/electron_api_utility_process.h",
"shell/browser/api/electron_api_view.cc",
@@ -515,8 +514,11 @@ filenames = {
"shell/common/api/electron_api_key_weak_map.h",
"shell/common/api/electron_api_native_image.cc",
"shell/common/api/electron_api_native_image.h",
"shell/common/api/electron_api_net.cc",
"shell/common/api/electron_api_shell.cc",
"shell/common/api/electron_api_testing.cc",
"shell/common/api/electron_api_url_loader.cc",
"shell/common/api/electron_api_url_loader.h",
"shell/common/api/electron_api_v8_util.cc",
"shell/common/api/electron_bindings.cc",
"shell/common/api/electron_bindings.h",

View File

@@ -1,3 +0,0 @@
import { wrapFsWithAsar } from './fs-wrapper';
wrapFsWithAsar(require('fs'));

View File

@@ -1,6 +1,6 @@
import { net, IncomingMessage, Session as SessionT } from 'electron/main';
import { ClientRequestConstructorOptions, ClientRequest, IncomingMessage, Session as SessionT } from 'electron/main';
import { Readable, Writable, isReadable } from 'stream';
import { allowAnyProtocol } from '@electron/internal/browser/api/net-client-request';
import { allowAnyProtocol } from '@electron/internal/common/api/net-client-request';
function createDeferredPromise<T, E extends Error = Error> (): { promise: Promise<T>; resolve: (x: T) => void; reject: (e: E) => void; } {
let res: (x: T) => void;
@@ -13,7 +13,8 @@ function createDeferredPromise<T, E extends Error = Error> (): { promise: Promis
return { promise, resolve: res!, reject: rej! };
}
export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypassCustomProtocolHandlers?: boolean}) | undefined, session: SessionT): Promise<Response> {
export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypassCustomProtocolHandlers?: boolean}) | undefined, session: SessionT | undefined,
request: (options: ClientRequestConstructorOptions | string) => ClientRequest) {
const p = createDeferredPromise<Response>();
let req: Request;
try {
@@ -73,7 +74,7 @@ export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypa
// We can't set credentials to same-origin unless there's an origin set.
const credentials = req.credentials === 'same-origin' && !origin ? 'include' : req.credentials;
const r = net.request(allowAnyProtocol({
const r = request(allowAnyProtocol({
session,
method: req.method,
url: req.url,

View File

@@ -1,10 +1,13 @@
import { IncomingMessage, session } from 'electron/main';
import { app, IncomingMessage, session } from 'electron/main';
import type { ClientRequestConstructorOptions } from 'electron/main';
import { ClientRequest } from '@electron/internal/browser/api/net-client-request';
import { ClientRequest } from '@electron/internal/common/api/net-client-request';
const { isOnline } = process._linkedBinding('electron_browser_net');
const { isOnline } = process._linkedBinding('electron_common_net');
export function request (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
if (!app.isReady()) {
throw new Error('net module can only be used after app is ready');
}
return new ClientRequest(options, callback);
}

View File

@@ -1,8 +1,9 @@
import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
import { net } from 'electron/main';
const { fromPartition, fromPath, Session } = process._linkedBinding('electron_browser_session');
Session.prototype.fetch = function (input: RequestInfo, init?: RequestInit) {
return fetchWithSession(input, init, this);
return fetchWithSession(input, init, this, net.request);
};
export default {

View File

@@ -14,7 +14,7 @@ interface GuestInstance {
}
const webViewManager = process._linkedBinding('electron_browser_web_view_manager');
const netBinding = process._linkedBinding('electron_browser_net');
const netBinding = process._linkedBinding('electron_common_net');
const supportedWebViewEvents = Object.keys(webViewEvents);

View File

@@ -10,9 +10,6 @@ const Module = require('module');
// we need to restore it here.
process.argv.splice(1, 1);
// Clear search paths.
require('../common/reset-search-paths');
// Import common settings.
require('@electron/internal/common/init');

View File

@@ -1,14 +1,15 @@
import * as url from 'url';
import { Readable, Writable } from 'stream';
import { app } from 'electron/main';
import type { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
import type {
ClientRequestConstructorOptions,
UploadProgress
} from 'electron/common';
const {
isValidHeaderName,
isValidHeaderValue,
createURLLoader
} = process._linkedBinding('electron_browser_net');
const { Session } = process._linkedBinding('electron_browser_session');
} = process._linkedBinding('electron_common_net');
const kHttpProtocols = new Set(['http:', 'https:']);
@@ -283,14 +284,17 @@ function parseOptions (optionsIn: ClientRequestConstructorOptions | string): Nod
const key = name.toLowerCase();
urlLoaderOptions.headers[key] = { name, value };
}
if (options.session) {
if (!(options.session instanceof Session)) { throw new TypeError('`session` should be an instance of the Session class'); }
urlLoaderOptions.session = options.session;
} else if (options.partition) {
if (typeof options.partition === 'string') {
urlLoaderOptions.partition = options.partition;
} else {
throw new TypeError('`partition` should be a string');
if (process.type !== 'utility') {
const { Session } = process._linkedBinding('electron_browser_session');
if (options.session) {
if (!(options.session instanceof Session)) { throw new TypeError('`session` should be an instance of the Session class'); }
urlLoaderOptions.session = options.session;
} else if (options.partition) {
if (typeof options.partition === 'string') {
urlLoaderOptions.partition = options.partition;
} else {
throw new TypeError('`partition` should be a string');
}
}
}
return urlLoaderOptions;
@@ -312,10 +316,6 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
constructor (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
super({ autoDestroy: true });
if (!app.isReady()) {
throw new Error('net module can only be used after app is ready');
}
if (callback) {
this.once('response', callback);
}

View File

@@ -73,3 +73,43 @@ if (process.platform === 'win32') {
}
});
}
const Module = require('module');
// Make a fake Electron module that we will insert into the module cache
const makeElectronModule = (name: string) => {
const electronModule = new Module('electron', null);
electronModule.id = 'electron';
electronModule.loaded = true;
electronModule.filename = name;
Object.defineProperty(electronModule, 'exports', {
get: () => require('electron')
});
Module._cache[name] = electronModule;
};
makeElectronModule('electron');
makeElectronModule('electron/common');
if (process.type === 'browser') {
makeElectronModule('electron/main');
}
if (process.type === 'renderer') {
makeElectronModule('electron/renderer');
}
const originalResolveFilename = Module._resolveFilename;
// 'electron/main', 'electron/renderer' and 'electron/common' are module aliases
// of the 'electron' module for TypeScript purposes, i.e., the types for
// 'electron/main' consist of only main process modules, etc. It is intentional
// that these can be `require()`-ed from both the main process as well as the
// renderer process regardless of the names, they're superficial for TypeScript
// only.
const electronModuleNames = new Set(['electron', 'electron/main', 'electron/renderer', 'electron/common']);
Module._resolveFilename = function (request: string, parent: NodeModule, isMain: boolean, options?: { paths: Array<string>}) {
if (electronModuleNames.has(request)) {
return 'electron';
} else {
return originalResolveFilename(request, parent, isMain, options);
}
};

View File

@@ -1,69 +0,0 @@
import * as path from 'path';
const Module = require('module');
// We do not want to allow use of the VM module in the renderer process as
// it conflicts with Blink's V8::Context internal logic.
if (process.type === 'renderer') {
const _load = Module._load;
Module._load = function (request: string) {
if (request === 'vm') {
console.warn('The vm module of Node.js is deprecated in the renderer process and will be removed.');
}
return _load.apply(this, arguments);
};
}
// Prevent Node from adding paths outside this app to search paths.
const resourcesPathWithTrailingSlash = process.resourcesPath + path.sep;
const originalNodeModulePaths = Module._nodeModulePaths;
Module._nodeModulePaths = function (from: string) {
const paths: string[] = originalNodeModulePaths(from);
const fromPath = path.resolve(from) + path.sep;
// If "from" is outside the app then we do nothing.
if (fromPath.startsWith(resourcesPathWithTrailingSlash)) {
return paths.filter(function (candidate) {
return candidate.startsWith(resourcesPathWithTrailingSlash);
});
} else {
return paths;
}
};
// Make a fake Electron module that we will insert into the module cache
const makeElectronModule = (name: string) => {
const electronModule = new Module('electron', null);
electronModule.id = 'electron';
electronModule.loaded = true;
electronModule.filename = name;
Object.defineProperty(electronModule, 'exports', {
get: () => require('electron')
});
Module._cache[name] = electronModule;
};
makeElectronModule('electron');
makeElectronModule('electron/common');
if (process.type === 'browser') {
makeElectronModule('electron/main');
}
if (process.type === 'renderer') {
makeElectronModule('electron/renderer');
}
const originalResolveFilename = Module._resolveFilename;
// 'electron/main', 'electron/renderer' and 'electron/common' are module aliases
// of the 'electron' module for TypeScript purposes, i.e., the types for
// 'electron/main' consist of only main process modules, etc. It is intentional
// that these can be `require()`-ed from both the main process as well as the
// renderer process regardless of the names, they're superficial for TypeScript
// only.
const electronModuleNames = new Set(['electron', 'electron/main', 'electron/renderer', 'electron/common']);
Module._resolveFilename = function (request: string, parent: NodeModule, isMain: boolean, options?: { paths: Array<string>}) {
if (electronModuleNames.has(request)) {
return 'electron';
} else {
return originalResolveFilename(request, parent, isMain, options);
}
};

49
lib/node/init.ts Normal file
View File

@@ -0,0 +1,49 @@
// Initialize ASAR support in fs module.
import { wrapFsWithAsar } from './asar-fs-wrapper';
wrapFsWithAsar(require('fs'));
// Hook child_process.fork.
import cp = require('child_process'); // eslint-disable-line import/first
const originalFork = cp.fork;
cp.fork = (modulePath, args?, options?: cp.ForkOptions) => {
// Parse optional args.
if (args == null) {
args = [];
} else if (typeof args === 'object' && !Array.isArray(args)) {
options = args as cp.ForkOptions;
args = [];
}
// Fallback to original fork to report arg type errors.
if (typeof modulePath !== 'string' || !Array.isArray(args) ||
(typeof options !== 'object' && typeof options !== 'undefined')) {
return originalFork(modulePath, args, options);
}
// When forking a child script, we setup a special environment to make
// the electron binary run like upstream Node.js.
options = options ?? {};
options.env = Object.create(options.env || process.env);
options.env!.ELECTRON_RUN_AS_NODE = '1';
// On mac the child script runs in helper executable.
if (!options.execPath && process.platform === 'darwin') {
options.execPath = process.helperExecPath;
}
return originalFork(modulePath, args, options);
};
// Prevent Node from adding paths outside this app to search paths.
import path = require('path'); // eslint-disable-line import/first
const Module = require('module');
const resourcesPathWithTrailingSlash = process.resourcesPath + path.sep;
const originalNodeModulePaths = Module._nodeModulePaths;
Module._nodeModulePaths = function (from: string) {
const paths: string[] = originalNodeModulePaths(from);
const fromPath = path.resolve(from) + path.sep;
// If "from" is outside the app then we do nothing.
if (fromPath.startsWith(resourcesPathWithTrailingSlash)) {
return paths.filter(function (candidate) {
return candidate.startsWith(resourcesPathWithTrailingSlash);
});
} else {
return paths;
}
};

View File

@@ -6,6 +6,16 @@ import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-re
const Module = require('module');
// We do not want to allow use of the VM module in the renderer process as
// it conflicts with Blink's V8::Context internal logic.
const originalModuleLoad = Module._load;
Module._load = function (request: string) {
if (request === 'vm') {
console.warn('The vm module of Node.js is deprecated in the renderer process and will be removed.');
}
return originalModuleLoad.apply(this, arguments as any);
};
// Make sure globals like "process" and "global" are always available in preload
// scripts even after they are deleted in "loaded" script.
//
@@ -32,9 +42,6 @@ Module.wrapper = [
// init.js, we need to restore it here.
process.argv.splice(1, 1);
// Clear search paths.
require('../common/reset-search-paths');
// Import common settings.
require('@electron/internal/common/init');

View File

@@ -1,2 +1,4 @@
// Utility side modules, please sort alphabetically.
export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [];
export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'net', loader: () => require('./net') }
];

22
lib/utility/api/net.ts Normal file
View File

@@ -0,0 +1,22 @@
import { IncomingMessage } from 'electron/utility';
import type { ClientRequestConstructorOptions } from 'electron/utility';
import { ClientRequest } from '@electron/internal/common/api/net-client-request';
import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
const { isOnline, resolveHost } = process._linkedBinding('electron_common_net');
export function request (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
return new ClientRequest(options, callback);
}
export function fetch (input: RequestInfo, init?: RequestInit): Promise<Response> {
return fetchWithSession(input, init, undefined, request);
}
exports.resolveHost = resolveHost;
exports.isOnline = isOnline;
Object.defineProperty(exports, 'online', {
get: () => isOnline()
});

View File

@@ -1,3 +1,5 @@
import { EventEmitter } from 'events';
import { ParentPort } from '@electron/internal/utility/parent-port';
const Module = require('module');
const v8Util = process._linkedBinding('electron_common_v8_util');
@@ -7,12 +9,11 @@ const entryScript: string = v8Util.getHiddenValue(process, '_serviceStartupScrip
// we need to restore it here.
process.argv.splice(1, 1, entryScript);
// Clear search paths.
require('../common/reset-search-paths');
// Import common settings.
require('@electron/internal/common/init');
process._linkedBinding('electron_browser_event_emitter').setEventEmitterPrototype(EventEmitter.prototype);
const parentPort: ParentPort = new ParentPort();
Object.defineProperty(process, 'parentPort', {
enumerable: true,

View File

@@ -6,9 +6,6 @@ const Module = require('module');
// init.js, we need to restore it here.
process.argv.splice(1, 1);
// Clear search paths.
require('../common/reset-search-paths');
// Import common settings.
require('@electron/internal/common/init');

View File

@@ -6,11 +6,11 @@
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@electron/asar": "^3.2.1",
"@electron/docs-parser": "^1.1.1",
"@electron/docs-parser": "^1.2.0",
"@electron/fiddle-core": "^1.0.4",
"@electron/github-app-auth": "^2.0.0",
"@electron/lint-roller": "^1.8.0",
"@electron/typescript-definitions": "^8.14.5",
"@electron/typescript-definitions": "^8.15.2",
"@octokit/rest": "^19.0.7",
"@primer/octicons": "^10.0.0",
"@types/basic-auth": "^1.1.3",

View File

@@ -0,0 +1,2 @@
fix_hlmatrixlowerpass_leaving_call_to_dangling_functionval.patch
cherry-pick-a65e511a14b4.patch

View File

@@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Maiorano <amaiorano@google.com>
Date: Wed, 3 Apr 2024 15:58:51 -0400
Subject: Fix ASAN use-after-free on unreferenced self-assignment of struct
instance (#6466)
When deleting an unused memcpy, ScalarReplAggregatesHLSL was attempting
to delete both the target and the source of the memcpy without first
checking if they were both same, resulting in a double-delete.
Bug: chromium:331123811
Change-Id: Idaef95a06b10a7fb6f0ca2e662972a44ec662fbc
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5419225
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Reviewed-by: Ben Clayton <bclayton@chromium.org>
diff --git a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
index b3589884aa3b690e1aad5ca7a19218a222591d39..8e2eff7f69ec378393c7a9afc4040cd9e921c42d 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
@@ -989,9 +989,11 @@ void DeleteMemcpy(MemCpyInst *MI) {
if (op0->user_empty())
op0->eraseFromParent();
}
- if (Instruction *op1 = dyn_cast<Instruction>(Op1)) {
- if (op1->user_empty())
- op1->eraseFromParent();
+ if (Op0 != Op1) {
+ if (Instruction *op1 = dyn_cast<Instruction>(Op1)) {
+ if (op1->user_empty())
+ op1->eraseFromParent();
+ }
}
}
diff --git a/tools/clang/test/DXC/unreferenced_struct_selft_assignment_crash.hlsl b/tools/clang/test/DXC/unreferenced_struct_selft_assignment_crash.hlsl
new file mode 100644
index 0000000000000000000000000000000000000000..81adf71867c9868992372e12dc1ba81aebb48344
--- /dev/null
+++ b/tools/clang/test/DXC/unreferenced_struct_selft_assignment_crash.hlsl
@@ -0,0 +1,24 @@
+// RUN: %dxc -T cs_6_0 %s | FileCheck %s
+
+// Validate that self-assignment of a static struct instance that is not
+// referenced does not crash the compiler. This was resulting in an ASAN
+// use-after-free in ScalarReplAggregatesHLSL because DeleteMemcpy would
+// attempt to delete both source and target, even if both were the same.
+// CHECK: define void @main() {
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+
+struct MyStruct {
+ int m0;
+};
+
+static MyStruct s;
+
+void foo() {
+ s = s;
+}
+
+[numthreads(1, 1, 1)]
+void main() {
+ foo();
+}

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Maiorano <amaiorano@google.com>
Date: Wed, 20 Mar 2024 17:15:40 -0400
Subject: Fix HLMatrixLowerPass leaving call to dangling FunctionVal
When lowering an hl.cast, when the operand was an undef matrix, the pass would insert a call to a mat2vec stub, but since the undef value is not
an alloca, it never gets handled, and the call to the temporary stub
remains. Since the stub FunctionVal gets deleted, when the instruction
is accessed in a future pass, it reads a dangling pointer.
The fix is to handle undef similarly to how constant 0 is handled, and
to return an undef vector from lowerHLCast.
Bug: chromium:328958020
Change-Id: Id31e3aa326d9cb9f03ea97139f14dc5292cd6f7b
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5383595
Reviewed-by: Ben Clayton <bclayton@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
diff --git a/lib/HLSL/HLMatrixLowerPass.cpp b/lib/HLSL/HLMatrixLowerPass.cpp
index e35ff832ecff9f2e46eecbd74f4b8b2f7cc7f700..c3a7254ef2b2f894a36ba8499b4aa9ace0afb8fa 100644
--- a/lib/HLSL/HLMatrixLowerPass.cpp
+++ b/lib/HLSL/HLMatrixLowerPass.cpp
@@ -381,6 +381,11 @@ Value* HLMatrixLowerPass::getLoweredByValOperand(Value *Val, IRBuilder<> &Builde
if (isa<ConstantAggregateZero>(Val))
return ConstantAggregateZero::get(LoweredTy);
+ // Lower undef mat as undef vec
+ if (isa<UndefValue>(Val)) {
+ return UndefValue::get(LoweredTy);
+ }
+
// Return a mat-to-vec translation stub
FunctionType *TranslationStubTy = FunctionType::get(LoweredTy, { Ty }, /* isVarArg */ false);
Function *TranslationStub = m_matToVecStubs->get(TranslationStubTy);

8
patches/angle/.patches Normal file
View File

@@ -0,0 +1,8 @@
m120_translator_optimize_field-name-collision_check.patch
m120_translator_fail_compilation_if_too_many_struct_fields.patch
m120_translator_limit_private_variable_size_to_64kb.patch
m120_vulkan_don_t_crash_when_glcopyteximage2d_redefines_itself.patch
m123_vulkan_fix_access_to_inactive_attributes.patch
cherry-pick-f6672dbbe223.patch
m119_move_invalid_uniform_protection_to_the_frontend.patch
m120_fix_off-by-one_bounds_check_on_uniform_location.patch

View File

@@ -0,0 +1,267 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Mon, 25 Mar 2024 14:46:56 -0400
Subject: M123: Translator: Disallow samplers in structs in interface blocks
As disallowed by the spec:
> Types and declarators are the same as for other uniform variable
> declarations outside blocks, with these exceptions:
>
> * opaque types are not allowed
Bug: chromium:328859176
Change-Id: Ib94977860102329e520e635c3757827c93ca2163
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5391986
Auto-Submit: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
(cherry picked from commit a0fa06f6d79ced897c0fe2795551268199d29806)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5435737
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index e174725beb764407185e471a9916ffd164493cd8..cb9eb3a4a566348f11aa5962037164147bc65684 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -34,27 +34,39 @@ namespace
const int kWebGLMaxStructNesting = 4;
-bool ContainsSampler(const TStructure *structType);
+struct IsSamplerFunc
+{
+ bool operator()(TBasicType type) { return IsSampler(type); }
+};
+struct IsOpaqueFunc
+{
+ bool operator()(TBasicType type) { return IsOpaqueType(type); }
+};
+
+template <typename OpaqueFunc>
+bool ContainsOpaque(const TStructure *structType);
-bool ContainsSampler(const TType &type)
+template <typename OpaqueFunc>
+bool ContainsOpaque(const TType &type)
{
- if (IsSampler(type.getBasicType()))
+ if (OpaqueFunc{}(type.getBasicType()))
{
return true;
}
if (type.getBasicType() == EbtStruct)
{
- return ContainsSampler(type.getStruct());
+ return ContainsOpaque<OpaqueFunc>(type.getStruct());
}
return false;
}
-bool ContainsSampler(const TStructure *structType)
+template <typename OpaqueFunc>
+bool ContainsOpaque(const TStructure *structType)
{
for (const auto &field : structType->fields())
{
- if (ContainsSampler(*field->type()))
+ if (ContainsOpaque<OpaqueFunc>(*field->type()))
return true;
}
return false;
@@ -1057,7 +1069,7 @@ bool TParseContext::checkIsNotOpaqueType(const TSourceLoc &line,
{
if (pType.type == EbtStruct)
{
- if (ContainsSampler(pType.userDef))
+ if (ContainsOpaque<IsSamplerFunc>(pType.userDef))
{
std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
reasonStream << reason << " (structure contains a sampler)";
@@ -4923,12 +4935,9 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
{
TField *field = (*fieldList)[memberIndex];
TType *fieldType = field->type();
- if (IsOpaqueType(fieldType->getBasicType()))
+ if (ContainsOpaque<IsOpaqueFunc>(*fieldType))
{
- std::string reason("unsupported type - ");
- reason += fieldType->getBasicString();
- reason += " types are not allowed in interface blocks";
- error(field->line(), reason.c_str(), fieldType->getBasicString());
+ error(field->line(), "Opaque types are not allowed in interface blocks", blockName);
}
const TQualifier qualifier = fieldType->getQualifier();
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index f4b7ce6222ff4a29cb20b75bc102e2c8ae478189..8ac5b758b128ded933d727f7dccb0ce8f8eb338b 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -6716,7 +6716,34 @@ void main()
gl_FragColor = vec4(f(us), 0, 0, 1);
})";
- CompileShader(GL_FRAGMENT_SHADER, kFS);
+ GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_NE(fs, 0u);
+ ASSERT_GL_NO_ERROR();
+}
+
+// Test that structs with samplers are not allowed in interface blocks. This is forbidden per
+// GLES3:
+//
+// > Types and declarators are the same as for other uniform variable declarations outside blocks,
+// > with these exceptions:
+// > * opaque types are not allowed
+TEST_P(GLSLTest_ES3, StructWithSamplersDisallowedInInterfaceBlock)
+{
+ const char kFS[] = R"(#version 300 es
+precision mediump float;
+struct S { sampler2D samp; bool b; };
+
+layout(std140) uniform Buffer { S s; } buffer;
+
+out vec4 color;
+
+void main()
+{
+ color = texture(buffer.s.samp, vec2(0));
+})";
+
+ GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(fs, 0u);
ASSERT_GL_NO_ERROR();
}
@@ -18195,6 +18222,116 @@ void main() {
EXPECT_EQ(0u, shader);
}
+// Same as TooManyFieldsInStruct, but with samplers in the struct.
+TEST_P(GLSLTest_ES3, TooManySamplerFieldsInStruct)
+{
+ std::ostringstream fs;
+ fs << R"(#version 300 es
+precision highp float;
+struct TooManyFields
+{
+)";
+ for (uint32_t i = 0; i < (1 << 16); ++i)
+ {
+ fs << " sampler2D field" << i << ";\n";
+ }
+ fs << R"(};
+uniform TooManyFields s;
+out vec4 color;
+void main() {
+ color = texture(s.field0, vec2(0));
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
+ EXPECT_EQ(0u, shader);
+}
+
+// More complex variation of ManySamplerFieldsInStruct. This one compiles fine.
+TEST_P(GLSLTest_ES3, ManySamplerFieldsInStructComplex)
+{
+ // D3D and OpenGL may be more restrictive about this many samplers.
+ ANGLE_SKIP_TEST_IF(IsD3D() || IsOpenGL());
+
+ std::ostringstream fs;
+ fs << R"(#version 300 es
+precision highp float;
+
+struct X {
+ mediump sampler2D a[0xf00];
+ mediump sampler2D b[0xf00];
+ mediump sampler2D c[0xf000];
+ mediump sampler2D d[0xf00];
+};
+
+struct Y {
+ X s1;
+ mediump sampler2D a[0xf00];
+ mediump sampler2D b[0xf000];
+ mediump sampler2D c[0x14000];
+};
+
+struct S {
+ Y s1;
+};
+
+struct structBuffer { S s; };
+
+uniform structBuffer b;
+
+out vec4 color;
+void main()
+{
+ color = texture(b.s.s1.s1.c[0], vec2(0));
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
+ EXPECT_NE(0u, shader);
+}
+
+// Make sure a large array of samplers works.
+TEST_P(GLSLTest, ManySamplers)
+{
+ // D3D and OpenGL may be more restrictive about this many samplers.
+ ANGLE_SKIP_TEST_IF(IsD3D() || IsOpenGL());
+
+ std::ostringstream fs;
+ fs << R"(precision highp float;
+
+uniform mediump sampler2D c[0x12000];
+
+void main()
+{
+ gl_FragColor = texture2D(c[0], vec2(0));
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
+ EXPECT_NE(0u, shader);
+}
+
+// Make sure a large array of samplers works when declared in a struct.
+TEST_P(GLSLTest, ManySamplersInStruct)
+{
+ // D3D and OpenGL may be more restrictive about this many samplers.
+ ANGLE_SKIP_TEST_IF(IsD3D() || IsOpenGL());
+
+ std::ostringstream fs;
+ fs << R"(precision highp float;
+
+struct X {
+ mediump sampler2D c[0x12000];
+};
+
+uniform X x;
+
+void main()
+{
+ gl_FragColor = texture2D(x.c[0], vec2(0));
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
+ EXPECT_NE(0u, shader);
+}
+
// Test that passing large arrays to functions are compiled correctly. Regression test for the
// SPIR-V generator that made a copy of the array to pass to the function, by decomposing and
// reconstructing it (in the absence of OpCopyLogical), but the reconstruction instruction has a
diff --git a/src/tests/gl_tests/PixelLocalStorageTest.cpp b/src/tests/gl_tests/PixelLocalStorageTest.cpp
index c49ba5741ad565ad9637fb2188a472ccbebc6284..126936271eb25eec601349a560fabc6f0f7d4b75 100644
--- a/src/tests/gl_tests/PixelLocalStorageTest.cpp
+++ b/src/tests/gl_tests/PixelLocalStorageTest.cpp
@@ -5573,8 +5573,7 @@ TEST_P(PixelLocalStorageCompilerTest, Declarations)
EXPECT_FALSE(log.compileFragmentShader(kPLSInStruct));
EXPECT_TRUE(log.has("ERROR: 0:5: 'pixelLocalANGLE' : disallowed type in struct"));
EXPECT_TRUE(
- log.has("ERROR: 0:10: 'pixelLocalANGLE' : unsupported type - pixelLocalANGLE types are not "
- "allowed in interface blocks"));
+ log.has("ERROR: 0:10: 'PLSBlock' : Opaque types are not allowed in interface blocks"));
ASSERT_GL_NO_ERROR();
}

View File

@@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Tue, 17 Oct 2023 11:39:10 -0400
Subject: M119: Move invalid uniform protection to the frontend.
The frontend potentialy indexes into mUniformLocations with invalid
uniform locations while validation is disabled too. Move the validation
from the Metal backend to the frontend.
Bug: chromium:1484878
Change-Id: I92bc43aa28cfa26d601bb28f318860375f618608
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4947652
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
(cherry picked from commit e076d6cfd0e1d6948623bb344c5a38753b0c2b2e)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4969232
Reviewed-by: Kenneth Russell <kbr@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 5caab257c909d81ea40c8bdad6bca8ce5e9c72c7..5dc66027831b0d1ac1915faf0d32223d6a71cd1c 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -2192,7 +2192,7 @@ GLuint Program::getUniformIndex(const std::string &name) const
bool Program::shouldIgnoreUniform(UniformLocation location) const
{
- if (location.value == -1)
+ if (location.value < 0 || static_cast<size_t>(location.value) >= mUniformLocations.size())
{
return true;
}
diff --git a/src/libANGLE/renderer/metal/ProgramMtl.mm b/src/libANGLE/renderer/metal/ProgramMtl.mm
index 5b86c4a8e0fa00012460d2e14101494c1dc4fa82..c7b98020e47c2f881815685e122ecaa57dbc1ad9 100644
--- a/src/libANGLE/renderer/metal/ProgramMtl.mm
+++ b/src/libANGLE/renderer/metal/ProgramMtl.mm
@@ -766,22 +766,10 @@ void operator()() override
ProgramExecutableMtl *executableMtl = getExecutable();
const std::vector<gl::VariableLocation> &uniformLocations = mState.getUniformLocations();
- if (location < 0 || static_cast<size_t>(location) >= uniformLocations.size())
- {
- ERR() << "Invalid uniform location " << location << ", expected [0, "
- << uniformLocations.size() << ")";
- return;
- }
- const gl::VariableLocation &locationInfo = uniformLocations[location];
+ const gl::VariableLocation &locationInfo = uniformLocations[location];
const std::vector<gl::LinkedUniform> &linkedUniforms = mState.getUniforms();
- if (locationInfo.index >= linkedUniforms.size())
- {
- ERR() << "Invalid uniform location index " << locationInfo.index << ", expected [0, "
- << linkedUniforms.size() << ")";
- return;
- }
- const gl::LinkedUniform &linkedUniform = linkedUniforms[locationInfo.index];
+ const gl::LinkedUniform &linkedUniform = linkedUniforms[locationInfo.index];
if (linkedUniform.isSampler())
{

View File

@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Wed, 22 Nov 2023 12:01:31 -0500
Subject: M120: Fix off-by-one bounds check on uniform location.
Log an error when the user provides an invalid uniform location.
Bug: chromium:1504162
Bug: chromium:1484878
Change-Id: Ieb7eb964d508954ac8dfa8e4d9bd941778185223
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5054238
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: James Godfrey-Kittle <jamesgk@google.com>
(cherry picked from commit fba482b7107ccf3e178f6bf56b6b0285407ace3a)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5080772
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 5dc66027831b0d1ac1915faf0d32223d6a71cd1c..d9e9582679b1e16e122c7e7b0a699e23cf45ae46 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -2192,13 +2192,15 @@ GLuint Program::getUniformIndex(const std::string &name) const
bool Program::shouldIgnoreUniform(UniformLocation location) const
{
- if (location.value < 0 || static_cast<size_t>(location.value) >= mUniformLocations.size())
+ if (location.value < 0)
{
return true;
}
- if (mState.mExecutable->mUniformLocations[static_cast<size_t>(location.value)].ignored)
+ if (static_cast<size_t>(location.value) >= mState.mExecutable->mUniformLocations.size())
{
+ ERR() << "Invalid uniform location " << location.value << ", expected [0, "
+ << mState.mExecutable->mUniformLocations.size() << ")";
return true;
}

View File

@@ -0,0 +1,215 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Thu, 30 Nov 2023 14:12:42 -0500
Subject: M120: Translator: Fail compilation if too many struct fields
If there are too many struct fields, SPIR-V cannot be produced (as it
has a hard limit of 16383 fields). The Nvidia GL driver has also been
observed to fail when there are too many fields.
Bug: chromium:1505009
Change-Id: I29fd61d180175e89e7db9ca8ba49ab07585b5f9a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143827
Reviewed-by: Cody Northrop <cnorthrop@google.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 7c90ea4f1d23a8af0cab1d44124eea021a27a16d..e174725beb764407185e471a9916ffd164493cd8 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -4726,6 +4726,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
const TVector<unsigned int> *arraySizes,
const TSourceLoc &arraySizesLine)
{
+ checkDoesNotHaveTooManyFields(blockName, fieldList, nameLine);
+
// Ensure there are no duplicate field names
checkDoesNotHaveDuplicateFieldNames(fieldList, nameLine);
@@ -6289,6 +6291,21 @@ void TParseContext::checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields
}
}
+void TParseContext::checkDoesNotHaveTooManyFields(const ImmutableString &name,
+ const TFieldList *fields,
+ const TSourceLoc &location)
+{
+ // Check that there are not too many fields. SPIR-V has a limit of 16383 fields, and it would
+ // be reasonable to apply that limit to all outputs. For example, it was observed that 32768
+ // fields cause the Nvidia GL driver to fail compilation, so such a limit is not too specific to
+ // SPIR-V.
+ constexpr size_t kMaxFieldCount = 16383;
+ if (fields->size() > kMaxFieldCount)
+ {
+ error(location, "Too many fields in the struct (limit is 16383)", name);
+ }
+}
+
TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
{
return fields;
@@ -6392,6 +6409,8 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
}
}
+ checkDoesNotHaveTooManyFields(structName, fieldList, structLine);
+
// Ensure there are no duplicate field names
checkDoesNotHaveDuplicateFieldNames(fieldList, structLine);
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index b63dbbadd146d1a004513823de72c89240a31929..c83b73271b557ed122668d7e655deae5aa23bc48 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -355,6 +355,9 @@ class TParseContext : angle::NonCopyable
const TVector<unsigned int> *arraySizes);
void checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields, const TSourceLoc &location);
+ void checkDoesNotHaveTooManyFields(const ImmutableString &name,
+ const TFieldList *fields,
+ const TSourceLoc &location);
TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
TFieldList *combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields,
diff --git a/src/tests/compiler_tests/ExpressionLimit_test.cpp b/src/tests/compiler_tests/ExpressionLimit_test.cpp
index d399e1792d97edb76d5e0247e4166e094cecb7e5..e17eace1b4b9a4185d6833fb7895f5fd49ae7679 100644
--- a/src/tests/compiler_tests/ExpressionLimit_test.cpp
+++ b/src/tests/compiler_tests/ExpressionLimit_test.cpp
@@ -16,12 +16,6 @@ class ExpressionLimitTest : public testing::Test
static const int kMaxExpressionComplexity = 16;
static const int kMaxCallStackDepth = 16;
static const int kMaxFunctionParameters = 16;
- static const char *kExpressionTooComplex;
- static const char *kCallStackTooDeep;
- static const char *kHasRecursion;
- static const char *kTooManyParameters;
- static const char *kTooComplexSwitch;
- static const char *kGlobalVariableInit;
virtual void SetUp()
{
@@ -125,9 +119,7 @@ class ExpressionLimitTest : public testing::Test
GenerateDeepFunctionStack(length, &ss);
- ss << "void main() {\n"
- << " gl_FragColor = function" << length << "();\n"
- << "}";
+ ss << "void main() {\n" << " gl_FragColor = function" << length << "();\n" << "}";
return ss.str();
}
@@ -138,9 +130,7 @@ class ExpressionLimitTest : public testing::Test
GenerateDeepFunctionStack(length, &ss);
- ss << "void main() {\n"
- << " gl_FragColor = vec4(0,0,0,0);\n"
- << "}";
+ ss << "void main() {\n" << " gl_FragColor = vec4(0,0,0,0);\n" << "}";
return ss.str();
}
@@ -149,9 +139,7 @@ class ExpressionLimitTest : public testing::Test
{
std::stringstream ss;
- ss << "precision mediump float;\n"
- << "\n"
- << "float foo(";
+ ss << "precision mediump float;\n" << "\n" << "float foo(";
for (int i = 0; i < parameters; ++i)
{
ss << "float f" << i;
@@ -244,15 +232,13 @@ class ExpressionLimitTest : public testing::Test
ShBuiltInResources resources;
};
-const char *ExpressionLimitTest::kExpressionTooComplex = "Expression too complex";
-const char *ExpressionLimitTest::kCallStackTooDeep = "Call stack too deep";
-const char *ExpressionLimitTest::kHasRecursion =
- "Recursive function call in the following call chain";
-const char *ExpressionLimitTest::kTooManyParameters = "Function has too many parameters";
-const char *ExpressionLimitTest::kTooComplexSwitch =
- "too complex expressions inside a switch statement";
-const char *ExpressionLimitTest::kGlobalVariableInit =
- "global variable initializers must be constant expressions";
+constexpr char kExpressionTooComplex[] = "Expression too complex";
+constexpr char kCallStackTooDeep[] = "Call stack too deep";
+constexpr char kHasRecursion[] = "Recursive function call in the following call chain";
+constexpr char kTooManyParameters[] = "Function has too many parameters";
+constexpr char kTooComplexSwitch[] = "too complex expressions inside a switch statement";
+constexpr char kGlobalVariableInit[] = "global variable initializers must be constant expressions";
+constexpr char kTooManyFields[] = "Too many fields in the struct";
TEST_F(ExpressionLimitTest, ExpressionComplexity)
{
@@ -632,3 +618,31 @@ TEST_F(ExpressionLimitTest, NestingInsideGlobalInitializer)
compileOptions, nullptr));
sh::Destruct(compiler);
}
+
+TEST_F(ExpressionLimitTest, TooManyStructFields)
+{
+ ShShaderSpec spec = SH_WEBGL2_SPEC;
+ ShShaderOutput output = SH_ESSL_OUTPUT;
+ ShHandle compiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, spec, output, &resources);
+ ShCompileOptions compileOptions = {};
+
+ std::ostringstream fs;
+ fs << R"(#version 300 es
+precision highp float;
+struct TooManyFields
+{
+)";
+ for (uint32_t i = 0; i < (1 << 16); ++i)
+ {
+ fs << " float field" << i << ";\n";
+ }
+ fs << R"(};
+uniform B { TooManyFields s; };
+out vec4 color;
+void main() {
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
+})";
+
+ EXPECT_TRUE(CheckShaderCompilation(compiler, fs.str().c_str(), compileOptions, kTooManyFields));
+ sh::Destruct(compiler);
+}
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 0fa89f59a38165b8d526a99bae60c7b752dec15d..d7eb48eacfe58fc128fc2d24088ac18ea5196c05 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -18168,6 +18168,33 @@ void main() {
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fs.str().c_str());
}
+// Test that structs with too many fields are rejected. In SPIR-V, the instruction that defines the
+// struct lists the fields which means the length of the instruction is a function of the field
+// count. Since SPIR-V instruction sizes are limited to 16 bits, structs with more fields cannot be
+// represented.
+TEST_P(GLSLTest_ES3, TooManyFieldsInStruct)
+{
+ std::ostringstream fs;
+ fs << R"(#version 300 es
+precision highp float;
+struct TooManyFields
+{
+)";
+ for (uint32_t i = 0; i < (1 << 16); ++i)
+ {
+ fs << " float field" << i << ";\n";
+ }
+ fs << R"(};
+uniform B { TooManyFields s; };
+out vec4 color;
+void main() {
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
+ EXPECT_EQ(0u, shader);
+}
+
} // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);

View File

@@ -0,0 +1,416 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Thu, 30 Nov 2023 15:42:32 -0500
Subject: M120: Translator: Limit private variable size to 64KB
This is indirectly fixing an issue where passing large arrays in SPIR-V
such that an internal cast is needed (such as array inside interface
block copied to local varaible) causes an overflow of the instruction
length limit (in the absence of OpCopyLogical).
By limiting the size of private variables to 32KB, this limitation is
indirectly enforced. It was observed that all the test shaders added in
this CL fail on the Nvidia OpenGL drivers, so such a limit seems to be
reasonble.
Bug: chromium:1505009
Change-Id: I75a1e40a538120ffc69ae7edafbdba5830c6b0bb
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143828
Reviewed-by: Cody Northrop <cnorthrop@google.com>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 1f3a4d52f2f45e7ed10b9b5512f2f92a06877256..c70c419631a1c4d382bcc8ba36c35d0ba06c2c5d 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -771,11 +771,6 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
return false;
}
- if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(root, &mSymbolTable, &mDiagnostics))
- {
- return false;
- }
-
if (!ValidateFragColorAndFragData(mShaderType, mShaderVersion, mSymbolTable, &mDiagnostics))
{
return false;
@@ -1056,6 +1051,13 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
return false;
}
+ // Run after RemoveUnreferencedVariables, validate that the shader does not have excessively
+ // large variables.
+ if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(root, &mSymbolTable, &mDiagnostics))
+ {
+ return false;
+ }
+
// Built-in function emulation needs to happen after validateLimitations pass.
GetGlobalPoolAllocator()->lock();
initBuiltInFunctionEmulator(&mBuiltInFunctionEmulator, compileOptions);
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index f0ff9cb11ac39e62672285300c8f41641f12c617..8f02c65b5ec5fd20b8bcee2bc595cfb278f758b4 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -24,10 +24,11 @@ namespace
// 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 (16MB) as that much memory won't fit in
+// For local and global variables, the limit is much lower (64KB) 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>(16) * 1024 * 1024;
+constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(64) * 1024;
+constexpr size_t kMaxTotalPrivateVariableSizeInBytes = static_cast<size_t>(16) * 1024 * 1024;
// Traverses intermediate tree to ensure that the shader does not
// exceed certain implementation-defined limits on the sizes of types.
@@ -70,43 +71,115 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
continue;
}
- const TType &variableType = asSymbol->getType();
-
- // Create a ShaderVariable from which to compute
- // (conservative) sizing information.
- ShaderVariable shaderVar;
- setCommonVariableProperties(variableType, variable, &shaderVar);
-
- // Compute the std140 layout of this variable, assuming
- // it's a member of a block (which it might not be).
- Std140BlockEncoder layoutEncoder;
- BlockEncoderVisitor visitor("", "", &layoutEncoder);
- // Since the size limit's arbitrary, it doesn't matter
- // whether the row-major layout is correctly determined.
- bool isRowMajorLayout = false;
- TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
- if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
+ if (!validateVariableSize(variable, asSymbol->getLine()))
{
- error(asSymbol->getLine(),
- "Size of declared variable exceeds implementation-defined limit",
- asSymbol->getName());
return false;
}
+ }
+
+ return true;
+ }
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override
+ {
+ const TFunction *function = node->getFunction();
+ const size_t paramCount = function->getParamCount();
+
+ for (size_t paramIndex = 0; paramIndex < paramCount; ++paramIndex)
+ {
+ validateVariableSize(*function->getParam(paramIndex), node->getLine());
+ }
+ }
+
+ bool validateVariableSize(const TVariable &variable, const TSourceLoc &location)
+ {
+ const TType &variableType = variable.getType();
+
+ // Create a ShaderVariable from which to compute
+ // (conservative) sizing information.
+ ShaderVariable shaderVar;
+ setCommonVariableProperties(variableType, variable, &shaderVar);
+
+ // Compute the std140 layout of this variable, assuming
+ // it's a member of a block (which it might not be).
+ Std140BlockEncoder layoutEncoder;
+ BlockEncoderVisitor visitor("", "", &layoutEncoder);
+ // Since the size limit's arbitrary, it doesn't matter
+ // whether the row-major layout is correctly determined.
+ bool isRowMajorLayout = false;
+ TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
+ if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
+ {
+ error(location, "Size of declared variable exceeds implementation-defined limit",
+ variable.name());
+ return false;
+ }
+
+ // Skip over struct declarations. As long as they are not used (or if they are used later
+ // in a less-restricted context (such as a UBO or SSBO)), they can be larger than
+ // kMaxPrivateVariableSizeInBytes.
+ if (variable.symbolType() == SymbolType::Empty && variableType.isStructSpecifier())
+ {
+ return true;
+ }
+
+ switch (variableType.getQualifier())
+ {
+ // List of all types that need to be limited (for example because they cause overflows
+ // in drivers, or create trouble for the SPIR-V gen as the number of an instruction's
+ // arguments cannot be more than 64KB (see OutputSPIRVTraverser::cast)).
+
+ // Local/global variables
+ case EvqTemporary:
+ case EvqGlobal:
+ case EvqConst:
+
+ // Function arguments
+ case EvqParamIn:
+ case EvqParamOut:
+ case EvqParamInOut:
+ case EvqParamConst:
+
+ // Varyings
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqSampleOut:
+ case EvqNoPerspectiveCentroidOut:
+ case EvqNoPerspectiveSampleOut:
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqCentroidIn:
+ case EvqNoPerspectiveCentroidIn:
+ case EvqNoPerspectiveSampleIn:
+ case EvqVertexOut:
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ case EvqPerVertexIn:
+ case EvqPerVertexOut:
+ case EvqPatchIn:
+ case EvqPatchOut:
+ case EvqTessControlIn:
+ case EvqTessControlOut:
+ case EvqTessEvaluationIn:
+ case EvqTessEvaluationOut:
- const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
- variableType.getQualifier() == EvqGlobal ||
- variableType.getQualifier() == EvqConst;
- if (isPrivate)
- {
if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
{
- error(asSymbol->getLine(),
+ error(location,
"Size of declared private variable exceeds implementation-defined limit",
- asSymbol->getName());
+ variable.name());
return false;
}
mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
- }
+ break;
+ default:
+ break;
}
return true;
@@ -115,7 +188,7 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
void validateTotalPrivateVariableSize()
{
if (mTotalPrivateVariablesSize.ValueOrDefault(std::numeric_limits<size_t>::max()) >
- kMaxPrivateVariableSizeInBytes)
+ kMaxTotalPrivateVariableSizeInBytes)
{
mDiagnostics->error(
TSourceLoc{},
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index 91233461298150dff48e4d044eb8535e1bcfb7b6..f1343f8e8ad65b6fa292c630214c66aaf3ff5a64 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -110,6 +110,8 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
7872 WIN INTEL OPENGL : VertexAttributeTest.AliasingMatrixAttribLocations/ES2_OpenGL = SKIP
7872 WIN INTEL OPENGL : VertexAttributeTest.ShortUnnormalized/ES2_OpenGL = SKIP
7872 WIN INTEL OPENGL : ViewportTest.DoubleWindowCentered/ES2_OpenGL = SKIP
+8441 WIN INTEL OPENGL : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
+8441 WIN INTEL OPENGL : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
// Linux
6065 LINUX INTEL VULKAN : SimpleStateChangeTestES31.DrawThenUpdateUBOThenDrawThenDrawIndexed/* = SKIP
@@ -146,6 +148,10 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
6977 LINUX NVIDIA OpenGL : MipmapTestES31.GenerateLowerMipsWithDraw/* = SKIP
7301 LINUX NVIDIA OpenGL : CopyTexImageTest.RGBAToRGB/ES2_OpenGL_EmulateCopyTexImage2DFromRenderbuffers/* = SKIP
7371 LINUX NVIDIA OpenGL : FramebufferTest_ES3.SurfaceDimensionsChangeAndFragCoord/* = SKIP
+8441 NVIDIA OPENGL : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
+8441 NVIDIA OPENGL : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
+8441 NVIDIA GLES : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
+8441 NVIDIA GLES : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
// Nvidia Vulkan
7236 NVIDIA VULKAN : GLSLTest_ES31.TessellationControlShaderMatrixCopyBug/* = SKIP
@@ -1055,6 +1061,8 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
7389 MAC OPENGL : Texture2DTest.ManySupersedingTextureUpdates/* = SKIP
8437 MAC OPENGL : GLSLTest_ES3.LotsOfFieldsInStruct/* = SKIP
+8437 MAC OPENGL : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
+8437 MAC OPENGL : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
// GL, GLES run into issues with cleanup
7495 WIN OpenGL : EGLMultiContextTest.ReuseUnterminatedDisplay/* = SKIP
diff --git a/src/tests/compiler_tests/RecordConstantPrecision_test.cpp b/src/tests/compiler_tests/RecordConstantPrecision_test.cpp
index 07923f991423f4ec1ff8cbe81fb822c2b526d149..9446576ac797c0e5db8f9c63d79adff744ea488e 100644
--- a/src/tests/compiler_tests/RecordConstantPrecision_test.cpp
+++ b/src/tests/compiler_tests/RecordConstantPrecision_test.cpp
@@ -141,11 +141,11 @@ TEST_F(RecordConstantPrecisionTest, HigherPrecisionConstantInIndex)
uniform mediump float u;
void main()
{
- const highp int a = 33000;
- mediump float b[34000];
+ const highp int a = 330;
+ mediump float b[340];
gl_FragColor = vec4(b[a]);
})";
compile(shaderString);
ASSERT_FALSE(foundInCode("const highp int s"));
- ASSERT_TRUE(foundInCode("b[33000]"));
+ ASSERT_TRUE(foundInCode("b[330]"));
}
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index d7eb48eacfe58fc128fc2d24088ac18ea5196c05..f4b7ce6222ff4a29cb20b75bc102e2c8ae478189 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -18195,6 +18195,138 @@ void main() {
EXPECT_EQ(0u, shader);
}
+// Test that passing large arrays to functions are compiled correctly. Regression test for the
+// SPIR-V generator that made a copy of the array to pass to the function, by decomposing and
+// reconstructing it (in the absence of OpCopyLogical), but the reconstruction instruction has a
+// length higher than can fit in SPIR-V.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArrayPassedToFunction)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+uniform Large { float a[65536]; };
+float f(float b[65536])
+{
+ b[0] = 1.0;
+ return b[0] + b[1];
+}
+out vec4 color;
+void main() {
+ color = vec4(f(a), 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Make sure the shader in LargeInterfaceBlockArrayPassedToFunction works if the large local is
+// avoided.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArray)
+{
+ int maxUniformBlockSize = 0;
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
+ ANGLE_SKIP_TEST_IF(maxUniformBlockSize < 16384 * 4);
+
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+uniform Large { float a[16384]; };
+out vec4 color;
+void main() {
+ color = vec4(a[0], 0.0, 0.0, 1.0);
+})";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+}
+
+// Similar to LargeInterfaceBlockArrayPassedToFunction, but the array is nested in a struct.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArrayPassedToFunction)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+struct S { float a[65536]; };
+uniform Large { S s; };
+float f(float b[65536])
+{
+ b[0] = 1.0;
+ return b[0] + b[1];
+}
+out vec4 color;
+void main() {
+ color = vec4(f(s.a), 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Make sure the shader in LargeInterfaceBlockNestedArrayPassedToFunction works if the large local
+// is avoided.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArray)
+{
+ int maxUniformBlockSize = 0;
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
+ ANGLE_SKIP_TEST_IF(maxUniformBlockSize < 16384 * 4);
+
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+struct S { float a[16384]; };
+uniform Large { S s; };
+out vec4 color;
+void main() {
+ color = vec4(s.a[0], 0.0, 0.0, 1.0);
+})";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+}
+
+// Similar to LargeInterfaceBlockArrayPassedToFunction, but the large array is copied to a local
+// variable instead.
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArrayCopiedToLocal)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+uniform Large { float a[65536]; };
+out vec4 color;
+void main() {
+ float b[65536] = a;
+ color = vec4(b[0], 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Similar to LargeInterfaceBlockArrayCopiedToLocal, but the array is nested in a struct
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArrayCopiedToLocal)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+struct S { float a[65536]; };
+uniform Large { S s; };
+out vec4 color;
+void main() {
+ S s2 = s;
+ color = vec4(s2.a[0], 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
+// Test that too large varyings are rejected.
+TEST_P(GLSLTest_ES3, LargeArrayVarying)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision highp float;
+in float a[65536];
+out vec4 color;
+void main() {
+ color = vec4(a[0], 0.0, 0.0, 1.0);
+})";
+
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
+ EXPECT_EQ(0u, shader);
+}
+
} // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);

View File

@@ -0,0 +1,180 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Thu, 30 Nov 2023 13:53:00 -0500
Subject: M120: Translator: Optimize field-name-collision check
As each field of the struct was encountered, its name was linearly
checked against previously added fields. That's O(n^2).
The name collision check is now moved to when the struct is completely
defined, and is done with an unordered_map.
Bug: chromium:1505009
Change-Id: I3fbc23493e5a03e61b631af615cffaf9995fd566
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143826
Reviewed-by: Cody Northrop <cnorthrop@google.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 28ac378cab6cb3812a43b6064733d7354ee694bc..7c90ea4f1d23a8af0cab1d44124eea021a27a16d 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -4726,6 +4726,9 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
const TVector<unsigned int> *arraySizes,
const TSourceLoc &arraySizesLine)
{
+ // Ensure there are no duplicate field names
+ checkDoesNotHaveDuplicateFieldNames(fieldList, nameLine);
+
const bool isGLPerVertex = blockName == "gl_PerVertex";
// gl_PerVertex is allowed to be redefined and therefore not reserved
if (!isGLPerVertex)
@@ -6269,28 +6272,25 @@ TDeclarator *TParseContext::parseStructArrayDeclarator(const ImmutableString &id
return new TDeclarator(identifier, arraySizes, loc);
}
-void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
- const TFieldList::const_iterator end,
- const ImmutableString &name,
- const TSourceLoc &location)
+void TParseContext::checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields,
+ const TSourceLoc &location)
{
- for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
+ TUnorderedMap<ImmutableString, uint32_t, ImmutableString::FowlerNollVoHash<sizeof(size_t)>>
+ fieldNames;
+ for (TField *field : *fields)
{
- if ((*fieldIter)->name() == name)
+ // Note: operator[] adds this name to the map if it doesn't already exist, and initializes
+ // its value to 0.
+ uint32_t count = ++fieldNames[field->name()];
+ if (count != 1)
{
- error(location, "duplicate field name in structure", name);
+ error(location, "Duplicate field name in structure", field->name());
}
}
}
TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
{
- for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end();
- ++fieldIter)
- {
- checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(),
- location);
- }
return fields;
}
@@ -6298,12 +6298,8 @@ TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields,
const TSourceLoc &location)
{
- for (TField *field : *newlyAddedFields)
- {
- checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(),
- field->name(), location);
- processedFields->push_back(field);
- }
+ processedFields->insert(processedFields->end(), newlyAddedFields->begin(),
+ newlyAddedFields->end());
return processedFields;
}
@@ -6396,7 +6392,10 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
}
}
- // ensure we do not specify any storage qualifiers on the struct members
+ // Ensure there are no duplicate field names
+ checkDoesNotHaveDuplicateFieldNames(fieldList, structLine);
+
+ // Ensure we do not specify any storage qualifiers on the struct members
for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
{
TField &field = *(*fieldList)[typeListIndex];
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 9e1354ef816705fb512b40b329794e0282129807..b63dbbadd146d1a004513823de72c89240a31929 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -354,10 +354,7 @@ class TParseContext : angle::NonCopyable
const TSourceLoc &loc,
const TVector<unsigned int> *arraySizes);
- void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
- const TFieldList::const_iterator end,
- const ImmutableString &name,
- const TSourceLoc &location);
+ void checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields, const TSourceLoc &location);
TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
TFieldList *combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields,
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index 04b1a80e4ccabf0043617d90a1a06cff25deab98..91233461298150dff48e4d044eb8535e1bcfb7b6 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -1054,6 +1054,8 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
7389 SWIFTSHADER : Texture2DTest.ManySupersedingTextureUpdates/* = SKIP
7389 MAC OPENGL : Texture2DTest.ManySupersedingTextureUpdates/* = SKIP
+8437 MAC OPENGL : GLSLTest_ES3.LotsOfFieldsInStruct/* = SKIP
+
// GL, GLES run into issues with cleanup
7495 WIN OpenGL : EGLMultiContextTest.ReuseUnterminatedDisplay/* = SKIP
7495 WIN GLES : EGLMultiContextTest.ReuseUnterminatedDisplay/* = SKIP
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 6443d47740d7f625fde2ebca2ef4a34d512d0883..0fa89f59a38165b8d526a99bae60c7b752dec15d 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -18124,6 +18124,50 @@ void main()
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
+// Test that Metal compiler doesn't inline non-const globals
+TEST_P(WebGLGLSLTest, InvalidGlobalsNotInlined)
+{
+ constexpr char kFS[] = R"(#version 100
+ precision highp float;
+ float v1 = 0.5;
+ float v2 = v1;
+
+ float f1() {
+ return v2;
+ }
+
+ void main() {
+ gl_FragColor = vec4(v1 + f1(),0.0,0.0, 1.0);
+ })";
+ ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS);
+ ASSERT_GL_NO_ERROR();
+}
+
+// Test that a struct can have lots of fields. Regression test for an inefficient O(n^2) check for
+// fields having unique names.
+TEST_P(GLSLTest_ES3, LotsOfFieldsInStruct)
+{
+ std::ostringstream fs;
+ fs << R"(#version 300 es
+precision highp float;
+struct LotsOfFields
+{
+)";
+ // Note: 16383 is the SPIR-V limit for struct member count.
+ for (uint32_t i = 0; i < 16383; ++i)
+ {
+ fs << " float field" << i << ";\n";
+ }
+ fs << R"(};
+uniform B { LotsOfFields s; };
+out vec4 color;
+void main() {
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
+})";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fs.str().c_str());
+}
+
} // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);

View File

@@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Tue, 5 Dec 2023 13:36:53 -0500
Subject: M120: Vulkan: Don't crash when glCopyTexImage2D redefines itself
The Vulkan backend marks a level being redefined as such before doing
the copy. If a single-level texture was being redefined, it releases it
so it can be immediately reallocated. If the source of the copy is the
same texture, this causes a crash.
This can be properly supported by using a temp image to do the copy, but
that is not implemented in this change.
Bug: chromium:1501798
Change-Id: I3a902b1e9eec41afd385d9c75a8c95dc986070a8
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143829
Reviewed-by: Cody Northrop <cnorthrop@google.com>
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 54d1184518e1cc6e83157b901a37e4ce1e9b58a5..98f66a1d4b02f78dcb3bdae673d21f4bd087fea7 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -879,8 +879,28 @@ angle::Result TextureVk::copyImage(const gl::Context *context,
gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
const vk::Format &vkFormat = renderer->getFormat(internalFormatInfo.sizedInternalFormat);
+ // The texture level being redefined might be the same as the one bound to the framebuffer.
+ // This _could_ be supported by using a temp image before redefining the level (and potentially
+ // discarding the image). However, this is currently unimplemented.
+ FramebufferVk *framebufferVk = vk::GetImpl(source);
+ RenderTargetVk *colorReadRT = framebufferVk->getColorReadRenderTarget();
+ vk::ImageHelper *srcImage = &colorReadRT->getImageForCopy();
+ const bool isCubeMap = index.getType() == gl::TextureType::CubeMap;
+ gl::LevelIndex levelIndex(getNativeImageIndex(index).getLevelIndex());
+ const uint32_t layerIndex = index.hasLayer() ? index.getLayerIndex() : 0;
+ const uint32_t redefinedFace = isCubeMap ? layerIndex : 0;
+ const uint32_t sourceFace = isCubeMap ? colorReadRT->getLayerIndex() : 0;
+ const bool isSelfCopy = mImage == srcImage && levelIndex == colorReadRT->getLevelIndex() &&
+ redefinedFace == sourceFace;
+
ANGLE_TRY(redefineLevel(context, index, vkFormat, newImageSize));
+ if (isSelfCopy)
+ {
+ UNIMPLEMENTED();
+ return angle::Result::Continue;
+ }
+
return copySubImageImpl(context, index, gl::Offset(0, 0, 0), sourceArea, internalFormatInfo,
source);
}
@@ -1949,7 +1969,8 @@ angle::Result TextureVk::redefineLevel(const gl::Context *context,
mImage->getLevelCount() == 1 && mImage->getFirstAllocatedLevel() == levelIndexGL;
// If incompatible, and redefining the single-level image, release it so it can be
- // recreated immediately. This is an optimization to avoid an extra copy.
+ // recreated immediately. This is needed so that the texture can be reallocated with
+ // the correct format/size.
if (!isCompatibleRedefinition && isUpdateToSingleLevelImage)
{
releaseImage(contextVk);
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index f1343f8e8ad65b6fa292c630214c66aaf3ff5a64..e60ea8f9970d14a551128528d18e7be3bc08efcc 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -29,6 +29,8 @@
6989 GLES : BlitFramebufferTestES31.OOBResolve/* = SKIP
7881 VULKAN : MultithreadingTestES3.UnsynchronizedTextureReads/* = SKIP
7881 VULKAN : MultithreadingTestES3.UnsynchronizedTextureReads2/* = SKIP
+// Incorrectly handled pretty much in all backends
+8446 : CopyTexImageTestES3.RedefineSameLevel/* = SKIP
6743 OPENGL : SimpleStateChangeTestES3.RespecifyBufferAfterBeginTransformFeedback/* = SKIP
6743 GLES : SimpleStateChangeTestES3.RespecifyBufferAfterBeginTransformFeedback/* = SKIP
diff --git a/src/tests/gl_tests/CopyTexImageTest.cpp b/src/tests/gl_tests/CopyTexImageTest.cpp
index 3d0cf40ab244a5463c2e4b3d53470d6f932e357b..d6949280ed301fc918e397dad26b9efec1c32f23 100644
--- a/src/tests/gl_tests/CopyTexImageTest.cpp
+++ b/src/tests/gl_tests/CopyTexImageTest.cpp
@@ -1262,6 +1262,56 @@ TEST_P(CopyTexImageTestES3, 3DSubImageDrawMismatchedTextureTypes)
glBindTexture(GL_TEXTURE_3D, 0);
}
+// Make sure a single-level texture can be redefined through glCopyTexImage2D from a framebuffer
+// bound to the same texture. Regression test for a bug in the Vulkan backend where the texture was
+// released before the copy.
+TEST_P(CopyTexImageTestES3, RedefineSameLevel)
+{
+ constexpr GLsizei kSize = 32;
+ constexpr GLsizei kHalfSize = kSize / 2;
+
+ // Create a single-level texture with four colors in different regions.
+ std::vector<GLColor> initData(kSize * kSize);
+ for (GLsizei y = 0; y < kSize; ++y)
+ {
+ const bool isTop = y < kHalfSize;
+ for (GLsizei x = 0; x < kSize; ++x)
+ {
+ const bool isLeft = x < kHalfSize;
+
+ GLColor color = isLeft && isTop ? GLColor::red
+ : isLeft && !isTop ? GLColor::green
+ : !isLeft && isTop ? GLColor::blue
+ : GLColor::yellow;
+ color.A = 123;
+ initData[y * kSize + x] = color;
+ }
+ }
+
+ GLTexture tex;
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ initData.data());
+
+ // Bind the framebuffer to the same texture
+ GLFramebuffer framebuffer;
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+
+ // Redefine the texture
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kHalfSize / 2, kHalfSize / 2, kHalfSize, kHalfSize,
+ 0);
+
+ // Verify copy is done correctly.
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ EXPECT_PIXEL_RECT_EQ(0, 0, kHalfSize / 2, kHalfSize / 2, GLColor::red);
+ EXPECT_PIXEL_RECT_EQ(kHalfSize / 2, 0, kHalfSize / 2, kHalfSize / 2, GLColor::blue);
+ EXPECT_PIXEL_RECT_EQ(0, kHalfSize / 2, kHalfSize / 2, kHalfSize / 2, GLColor::green);
+ EXPECT_PIXEL_RECT_EQ(kHalfSize / 2, kHalfSize / 2, kHalfSize / 2, kHalfSize / 2,
+ GLColor::yellow);
+}
+
ANGLE_INSTANTIATE_TEST(CopyTexImageTest,
ANGLE_ALL_TEST_PLATFORMS_ES2,
ES2_D3D11_PRESENT_PATH_FAST(),

View File

@@ -0,0 +1,112 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Tue, 12 Mar 2024 16:06:37 -0400
Subject: M123: Vulkan: Fix access to inactive attributes
... within range of active ones. Since a buffer is bound for inactive
attributes, it must be considered accessed.
Ultimately, the nullDescriptor feature could be used to avoid binding a
buffer for inactive attributes.
Bug: chromium:327807820
Change-Id: I953b419d8ec51760e8848409024cad5083888fa2
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5386431
Reviewed-by: Shahbaz Youssefi <syoussefi@google.com>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 9965bb1084ea237a18f72a1549916c0a6140806e..8e1708c82cd97acee56aae131c7d629c05a9d6a9 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -2596,8 +2596,7 @@ angle::Result ContextVk::handleDirtyGraphicsVertexBuffers(DirtyBits::Iterator *d
vertexArrayVk->getCurrentArrayBuffers();
// Mark all active vertex buffers as accessed.
- const gl::AttributesMask attribsMask = executable->getActiveAttribLocationsMask();
- for (size_t attribIndex : attribsMask)
+ for (uint32_t attribIndex = 0; attribIndex < maxAttrib; ++attribIndex)
{
vk::BufferHelper *arrayBuffer = arrayBufferResources[attribIndex];
if (arrayBuffer)
diff --git a/src/tests/gl_tests/VertexAttributeTest.cpp b/src/tests/gl_tests/VertexAttributeTest.cpp
index b26821200e472bec3d522d7b3e7f7aa0cb0d27a5..c37868cd4067aced75f2edb7397d72457a6fabb3 100644
--- a/src/tests/gl_tests/VertexAttributeTest.cpp
+++ b/src/tests/gl_tests/VertexAttributeTest.cpp
@@ -1200,6 +1200,19 @@ class VertexAttributeOORTest : public VertexAttributeTest
}
};
+class RobustVertexAttributeTest : public VertexAttributeTest
+{
+ public:
+ RobustVertexAttributeTest()
+ {
+ // mac GL and metal do not support robustness.
+ if (!IsMac() && !IsIOS())
+ {
+ setRobustAccess(true);
+ }
+ }
+};
+
// Verify that drawing with a large out-of-range offset generates INVALID_OPERATION.
// Requires WebGL compatibility with robust access behaviour disabled.
TEST_P(VertexAttributeOORTest, ANGLEDrawArraysBufferTooSmall)
@@ -1260,6 +1273,48 @@ TEST_P(VertexAttributeOORTest, ANGLEDrawArraysOutOfBoundsCases)
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
+// Test that enabling a buffer in an unused attribute doesn't crash. There should be an active
+// attribute after that.
+TEST_P(RobustVertexAttributeTest, BoundButUnusedBuffer)
+{
+ constexpr char kVS[] = R"(attribute vec2 offset;
+void main()
+{
+ gl_Position = vec4(offset.xy, 0, 1);
+ gl_PointSize = 1.0;
+})";
+
+ constexpr char kFS[] = R"(precision mediump float;
+void main()
+{
+ gl_FragColor = vec4(1.0, 0, 0, 1.0);
+})";
+
+ const GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS);
+ const GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
+
+ GLuint program = glCreateProgram();
+ glBindAttribLocation(program, 1, "offset");
+ glAttachShader(program, vs);
+ glAttachShader(program, fs);
+ glLinkProgram(program);
+
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ glBufferData(GL_ARRAY_BUFFER, 100, nullptr, GL_STATIC_DRAW);
+
+ // Enable an unused attribute that is within the range of active attributes (not beyond it)
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+
+ glUseProgram(program);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ // Destroy the buffer. Regression test for a tracking bug where the buffer was used by
+ // SwiftShader (even though location 1 is inactive), but not marked as used by ANGLE.
+ buffer.reset();
+}
+
// Verify that using a different start vertex doesn't mess up the draw.
TEST_P(VertexAttributeTest, DrawArraysWithBufferOffset)
{
@@ -4544,6 +4599,8 @@ ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
ES3_METAL().disable(Feature::HasExplicitMemBarrier).disable(Feature::HasCheapRenderPass),
ES3_METAL().disable(Feature::HasExplicitMemBarrier).enable(Feature::HasCheapRenderPass));
+ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(RobustVertexAttributeTest);
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VertexAttributeTestES3);
ANGLE_INSTANTIATE_TEST_ES3_AND(
VertexAttributeTestES3,

View File

@@ -135,3 +135,32 @@ revert_same_party_cookie_attribute_removal.patch
crash_gpu_process_and_clear_shader_cache_when_skia_reports.patch
scale_rects_properly_in_syncgetfirstrectforrange.patch
fix_restore_original_resize_performance_on_macos.patch
feat_allow_code_cache_in_custom_schemes.patch
fix_font_flooding_in_dev_tools.patch
cherry-pick-5fde415e06f9.patch
cherry-pick-8d607d3921b8.patch
cherry-pick-998e947b265f.patch
cherry-pick-021598ea43c1.patch
cherry-pick-76340163a820.patch
cherry-pick-f15cfb9371c4.patch
cherry-pick-4ca62c7a8b88.patch
cherry-pick-5b2fddadaa12.patch
cherry-pick-50a1bddfca85.patch
reland_mojom_ts_generator_handle_empty_module_path_identically_to.patch
cherry-pick-c1cda70a433a.patch
cherry-pick-cc07a95bc309.patch
safely_crash_on_dangling_profile.patch
cherry-pick-91a02d67a83d.patch
cherry-pick-8755f76bec32.patch
cherry-pick-1f8bec968902.patch
cherry-pick-4a98f9e304be.patch
fix_racy_iterator_use_in_node_addconnection.patch
fix_a_crash_when_a_bmp_image_contains_an_unnecessary_eof_code.patch
m120_ipcz_fix_a_few_weak_asserts.patch
prevent_mojotrap_event_re-ordering.patch
m122_cherry_pick_cve-2024-25062_libxml_fix.patch
update_crashpad_to_37afd37401253ebcebcf6e07ce15c8cfecb1a1cc.patch
m122_webcodecs_disable_async_videoframe_readback_to_mitigate_a.patch
fix_paintimage_deserialization_arbitrary-read_issue.patch
reland_sensors_winrt_call_onreadingchangedcallback_via.patch
cherry-pick-1b1f34234346.patch

View File

@@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Guido Urdaneta <guidou@chromium.org>
Date: Mon, 4 Dec 2023 23:00:41 +0000
Subject: Drop frames received on the wrong task runner
It can happen during transfer that a frame is posted from the
background media thread to the task runner of the old execution
context, which can lead to races and UAF.
This CL makes underlying sources drop frames received on the
wrong task runner to avoid the problem.
(cherry picked from commit 9d042e0d498356185fe9eb33c53b69fab33d06bf)
Bug: 1505708
Change-Id: I686228d88cb1c48bdf8c0b6bf85edd280a54300a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5077845
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: Tony Herre <toprice@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1231802}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5082444
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1370}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
index b5a2f71bae81bba6e61d8f303d24a9df874ae885..4c7b0b982e3d314749e39178eb0fca706d11bd85 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
@@ -58,7 +58,15 @@ void RTCEncodedAudioUnderlyingSource::Trace(Visitor* visitor) const {
void RTCEncodedAudioUnderlyingSource::OnFrameFromSource(
std::unique_ptr<webrtc::TransformableAudioFrameInterface> webrtc_frame) {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ // It can happen that a frame is posted to the task runner of the old
+ // execution context during a stream transfer to a new context.
+ // TODO(https://crbug.com/1506631): Make the state updates related to the
+ // transfer atomic and turn this into a DCHECK.
+ if (!task_runner_->BelongsToCurrentThread()) {
+ DVLOG(1) << "Dropped frame posted to incorrect task runner. This can "
+ "happen during transfer.";
+ return;
+ }
// If the source is canceled or there are too many queued frames,
// drop the new frame.
if (!disconnect_callback_ || !GetExecutionContext()) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
index 54ca7d1529b1772200c3691b56e847acc42d086d..8fb1d8460e289cd5e6764271f79dada7f121cb1b 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
@@ -58,7 +58,15 @@ void RTCEncodedVideoUnderlyingSource::Trace(Visitor* visitor) const {
void RTCEncodedVideoUnderlyingSource::OnFrameFromSource(
std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame) {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ // It can happen that a frame is posted to the task runner of the old
+ // execution context during a stream transfer to a new context.
+ // TODO(https://crbug.com/1506631): Make the state updates related to the
+ // transfer atomic and turn this into a DCHECK.
+ if (!task_runner_->BelongsToCurrentThread()) {
+ DVLOG(1) << "Dropped frame posted to incorrect task runner. This can "
+ "happen during transfer.";
+ return;
+ }
// If the source is canceled or there are too many queued frames,
// drop the new frame.
if (!disconnect_callback_ || !GetExecutionContext()) {

View File

@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: kylechar <kylechar@chromium.org>
Date: Tue, 9 Apr 2024 17:14:26 +0000
Subject: Validate buffer length
The BitmapInSharedMemory mojo traits were only validating row length and
not total buffer length.
(cherry picked from commit 1a19ff70bd54847d818566bd7a1e7c384c419746)
(cherry picked from commit f15315f1cb7897e208947a40d538aac693283d7f)
Bug: 331237485
Change-Id: Ia2318899c44e9e7ac72fc7183954e6ce2c702179
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5396796
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/main@{#1278417}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5420432
Commit-Queue: danakj <danakj@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/6312@{#786}
Cr-Original-Branched-From: 6711dcdae48edaf98cbc6964f90fac85b7d9986e-refs/heads/main@{#1262506}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5433678
Reviewed-by: danakj <danakj@chromium.org>
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#2003}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc b/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc
index a6e5f45d9e72b9ac48e536c3a7756966b3c263cf..519d554055e5182cdcbae44fafdac339a64a923b 100644
--- a/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc
+++ b/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc
@@ -76,6 +76,10 @@ bool StructTraits<viz::mojom::BitmapInSharedMemoryDataView, SkBitmap>::Read(
if (!mapping_ptr->IsValid())
return false;
+ if (mapping_ptr->size() < image_info.computeByteSize(data.row_bytes())) {
+ return false;
+ }
+
if (!sk_bitmap->installPixels(image_info, mapping_ptr->memory(),
data.row_bytes(), &DeleteSharedMemoryMapping,
mapping_ptr.get())) {

View File

@@ -0,0 +1,125 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tsuyoshi Horo <horo@chromium.org>
Date: Wed, 24 Jan 2024 02:04:24 +0000
Subject: Fix UAF in SourceStreamToDataPipe
SourceStreamToDataPipe::ReadMore() is passing a callback with
Unretained(this) to net::SourceStream::Read(). But this callback may be
called even after the SourceStream is destructed. This is causing UAF
issue (crbug.com/1511085).
To solve this problem, this CL changes ReadMore() method to pass a
callback with a weak ptr of this.
(cherry picked from commit 6e36a69da1b73f9aea9c54bfbe6c5b9cb2c672a5)
Bug: 1511085
Change-Id: Idd4e34ff300ff5db2de1de7b303841c7db3a964a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5179746
Reviewed-by: Adam Rice <ricea@chromium.org>
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1244526}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5231558
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1860}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/services/network/public/cpp/source_stream_to_data_pipe.cc b/services/network/public/cpp/source_stream_to_data_pipe.cc
index bfd85b1a00b216b52ae816ca29cb66ddabe20b6d..07afd58a40f92485ded07c535092a891c5140c7b 100644
--- a/services/network/public/cpp/source_stream_to_data_pipe.cc
+++ b/services/network/public/cpp/source_stream_to_data_pipe.cc
@@ -55,9 +55,9 @@ void SourceStreamToDataPipe::ReadMore() {
scoped_refptr<net::IOBuffer> buffer(
new network::NetToMojoIOBuffer(pending_write_.get()));
- int result = source_->Read(
- buffer.get(), base::checked_cast<int>(num_bytes),
- base::BindOnce(&SourceStreamToDataPipe::DidRead, base::Unretained(this)));
+ int result = source_->Read(buffer.get(), base::checked_cast<int>(num_bytes),
+ base::BindOnce(&SourceStreamToDataPipe::DidRead,
+ weak_factory_.GetWeakPtr()));
if (result != net::ERR_IO_PENDING)
DidRead(result);
diff --git a/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc b/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc
index 7061418c5141d936f04b1193c98e66efc5e72ac5..54159df39afa7cf6e2faa51da185dc034b923209 100644
--- a/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc
+++ b/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc
@@ -6,7 +6,9 @@
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
+#include "base/test/bind.h"
#include "base/test/task_environment.h"
+#include "net/base/net_errors.h"
#include "net/filter/mock_source_stream.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@@ -42,6 +44,33 @@ struct SourceStreamToDataPipeTestParam {
const ReadResultType read_result_type;
};
+class DummyPendingSourceStream : public net::SourceStream {
+ public:
+ DummyPendingSourceStream() : net::SourceStream(SourceStream::TYPE_NONE) {}
+ ~DummyPendingSourceStream() override = default;
+
+ DummyPendingSourceStream(const DummyPendingSourceStream&) = delete;
+ DummyPendingSourceStream& operator=(const DummyPendingSourceStream&) = delete;
+
+ // SourceStream implementation
+ int Read(net::IOBuffer* dest_buffer,
+ int buffer_size,
+ net::CompletionOnceCallback callback) override {
+ callback_ = std::move(callback);
+ return net::ERR_IO_PENDING;
+ }
+ std::string Description() const override { return ""; }
+ bool MayHaveMoreBytes() const override { return true; }
+
+ net::CompletionOnceCallback TakeCompletionCallback() {
+ CHECK(callback_);
+ return std::move(callback_);
+ }
+
+ private:
+ net::CompletionOnceCallback callback_;
+};
+
} // namespace
class SourceStreamToDataPipeTest
@@ -212,4 +241,33 @@ TEST_P(SourceStreamToDataPipeTest, MayHaveMoreBytes) {
EXPECT_EQ(ReadPipe(&output), net::OK);
EXPECT_EQ(output, message);
}
+
+TEST(SourceStreamToDataPipeCallbackTest, CompletionCallbackAfterDestructed) {
+ base::test::TaskEnvironment task_environment;
+
+ std::unique_ptr<DummyPendingSourceStream> source =
+ std::make_unique<DummyPendingSourceStream>();
+ DummyPendingSourceStream* source_ptr = source.get();
+ const MojoCreateDataPipeOptions data_pipe_options{
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 1};
+ mojo::ScopedDataPipeProducerHandle producer_end;
+ mojo::ScopedDataPipeConsumerHandle consumer_end;
+ CHECK_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&data_pipe_options,
+ producer_end, consumer_end));
+
+ std::unique_ptr<SourceStreamToDataPipe> adapter =
+ std::make_unique<SourceStreamToDataPipe>(std::move(source),
+ std::move(producer_end));
+ bool callback_called = false;
+ adapter->Start(
+ base::BindLambdaForTesting([&](int result) { callback_called = true; }));
+ net::CompletionOnceCallback callback = source_ptr->TakeCompletionCallback();
+ adapter.reset();
+
+ // Test that calling `callback` after deleting `adapter` must not cause UAF
+ // (crbug.com/1511085).
+ std::move(callback).Run(net::ERR_FAILED);
+ EXPECT_FALSE(callback_called);
+}
+
} // namespace network

View File

@@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@chromium.org>
Date: Fri, 26 Jan 2024 19:37:57 +0000
Subject: Speculatively fix race in mojo ShutDownOnIOThread
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This acquires `write_lock_` before resetting handles used by WriteNoLock
(which is called under the same lock in another thread). We also set
`reject_writes_` to prevent future write attempts after shutdown. That
seems strictly more correct.
We also acquire `fds_to_close_lock_` before clearing the FDs.
I was unable to repro locally as content_browsertests just times out
in my local setup without reporting anything interesting. This seems
strictly more correct though.
(cherry picked from commit 9755d9d81e4a8cb5b4f76b23b761457479dbb06b)
Bug: 1519980
Change-Id: I96279936ca908ecb98eddd381df20d61597cba43
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5226127
Auto-Submit: Peter Boström <pbos@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Commit-Queue: Ken Rockot <rockot@google.com>
Commit-Queue: Peter Boström <pbos@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1250580}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5239564
Cr-Commit-Position: refs/branch-heads/6099@{#1883}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/mojo/core/channel_posix.cc b/mojo/core/channel_posix.cc
index 0a3596382d0e9a40c72bfb4ead6f0338a61253d6..eae6b0768463679b5043514dc5745da52b80ae10 100644
--- a/mojo/core/channel_posix.cc
+++ b/mojo/core/channel_posix.cc
@@ -246,16 +246,21 @@ void ChannelPosix::WaitForWriteOnIOThreadNoLock() {
void ChannelPosix::ShutDownOnIOThread() {
base::CurrentThread::Get()->RemoveDestructionObserver(this);
- read_watcher_.reset();
- write_watcher_.reset();
- if (leak_handle_) {
- std::ignore = socket_.release();
- } else {
- socket_.reset();
- }
+ {
+ base::AutoLock lock(write_lock_);
+ reject_writes_ = true;
+ read_watcher_.reset();
+ write_watcher_.reset();
+ if (leak_handle_) {
+ std::ignore = socket_.release();
+ } else {
+ socket_.reset();
+ }
#if BUILDFLAG(IS_IOS)
- fds_to_close_.clear();
+ base::AutoLock fd_lock(fds_to_close_lock_);
+ fds_to_close_.clear();
#endif
+ }
// May destroy the |this| if it was the last reference.
self_ = nullptr;

View File

@@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vasiliy Telezhnikov <vasilyt@chromium.org>
Date: Thu, 7 Dec 2023 16:56:57 +0000
Subject: Check for slugs count before deserializing Slugs in DrawSlugOp
Count is part of serialized data and while we never serialize values
less then 1, it can be any value when coming over IPC, we should check
that it's positive before substacting one.
(cherry picked from commit 0527e0d5b08a13d63f4f1eeefa1b86ecfd0cb63b)
Bug: 1506726
Change-Id: I244f50a682f2e852b22ba88f1e9cddddb0fdfcb9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5078779
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1232013}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5096809
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/6099@{#1428}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/cc/paint/paint_op.cc b/cc/paint/paint_op.cc
index bd39210efa9a4da6f3888dd25ef465a1d0a4cc70..4c88eaa1e57ddae2c7fb0ba94d66b843ab8f63f2 100644
--- a/cc/paint/paint_op.cc
+++ b/cc/paint/paint_op.cc
@@ -976,10 +976,12 @@ PaintOp* DrawSlugOp::Deserialize(PaintOpReader& reader, void* output) {
reader.Read(&op->flags);
unsigned int count = 0;
reader.Read(&count);
- reader.Read(&op->slug);
- op->extra_slugs.resize(count - 1);
- for (auto& extra_slug : op->extra_slugs) {
- reader.Read(&extra_slug);
+ if (count > 0) {
+ reader.Read(&op->slug);
+ op->extra_slugs.resize(count - 1);
+ for (auto& extra_slug : op->extra_slugs) {
+ reader.Read(&extra_slug);
+ }
}
return op;
}

View File

@@ -0,0 +1,117 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Eng <enga@chromium.org>
Date: Tue, 19 Dec 2023 17:25:51 +0000
Subject: Use cross thread handles to bind args for async webgpu context
creation
(cherry picked from commit 542b278a0c1de7202f4bf5e3e5cbdc2dd6c337d4)
Fixed: 1506923
Change-Id: I174703cbd993471e3afb39c0cfa4cce2770755f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5113019
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1237179}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5133239
Cr-Commit-Position: refs/branch-heads/6099@{#1551}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc
index f2f4e8be0cc73f5b569fd3345bd3b64f4539041d..5752c80fbbfc91d492f497c87f181d3211c71d86 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -39,11 +39,13 @@
#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h"
#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_callback.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h"
+#include "third_party/blink/renderer/platform/heap/cross_thread_handle.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
namespace blink {
@@ -300,9 +302,19 @@ void GPU::RequestAdapterImpl(ScriptState* script_state,
CreateWebGPUGraphicsContext3DProviderAsync(
execution_context->Url(),
execution_context->GetTaskRunner(TaskType::kWebGPU),
- WTF::BindOnce(
- [](GPU* gpu, ExecutionContext* execution_context,
+ CrossThreadBindOnce(
+ [](CrossThreadHandle<GPU> gpu_handle,
+ CrossThreadHandle<ExecutionContext> execution_context_handle,
std::unique_ptr<WebGraphicsContext3DProvider> context_provider) {
+ auto unwrap_gpu = MakeUnwrappingCrossThreadHandle(gpu_handle);
+ auto unwrap_execution_context =
+ MakeUnwrappingCrossThreadHandle(execution_context_handle);
+ if (!unwrap_gpu || !unwrap_execution_context) {
+ return;
+ }
+ auto* gpu = unwrap_gpu.GetOnCreationThread();
+ auto* execution_context =
+ unwrap_execution_context.GetOnCreationThread();
const KURL& url = execution_context->Url();
context_provider =
CheckContextProvider(url, std::move(context_provider));
@@ -324,7 +336,8 @@ void GPU::RequestAdapterImpl(ScriptState* script_state,
std::move(callback).Run();
}
},
- WrapPersistent(this), WrapPersistent(execution_context)));
+ MakeCrossThreadHandle(this),
+ MakeCrossThreadHandle(execution_context)));
return;
}
diff --git a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc
index f859f3e62c54d26453a145321f697c5116c13348..3d9890b9b4a58a30a11e501fdb9297f4a57b601b 100644
--- a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc
+++ b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc
@@ -121,8 +121,8 @@ CreateWebGPUGraphicsContext3DProvider(const KURL& url) {
void CreateWebGPUGraphicsContext3DProviderAsync(
const KURL& url,
scoped_refptr<base::SingleThreadTaskRunner> current_thread_task_runner,
- base::OnceCallback<void(std::unique_ptr<WebGraphicsContext3DProvider>)>
- callback) {
+ WTF::CrossThreadOnceFunction<
+ void(std::unique_ptr<WebGraphicsContext3DProvider>)> callback) {
if (IsMainThread()) {
std::move(callback).Run(
Platform::Current()->CreateWebGPUGraphicsContext3DProvider(url));
@@ -140,8 +140,7 @@ void CreateWebGPUGraphicsContext3DProviderAsync(
AccessMainThreadForWebGraphicsContext3DProvider()),
FROM_HERE,
CrossThreadBindOnce(&CreateWebGPUGraphicsContextOnMainThreadAsync, url,
- current_thread_task_runner,
- CrossThreadBindOnce(std::move(callback))));
+ current_thread_task_runner, std::move(callback)));
}
}
diff --git a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h
index 8fcab24bfec2c9b2e9edf9885b66de4f99949b35..8b785cc30acdfffed0f59eb53b073d0cdedc2151 100644
--- a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h
+++ b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h
@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -42,8 +43,8 @@ CreateWebGPUGraphicsContext3DProvider(const KURL& url);
PLATFORM_EXPORT void CreateWebGPUGraphicsContext3DProviderAsync(
const KURL& url,
scoped_refptr<base::SingleThreadTaskRunner> current_thread_task_runner,
- base::OnceCallback<void(std::unique_ptr<WebGraphicsContext3DProvider>)>
- callback);
+ WTF::CrossThreadOnceFunction<
+ void(std::unique_ptr<WebGraphicsContext3DProvider>)> callback);
} // namespace blink

View File

@@ -0,0 +1,61 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Tue, 12 Dec 2023 02:34:29 +0000
Subject: Clamp the input value correctly before scheduling an AudioParam event
When the AudioParam value is set via the setter, it internally calls
the setValueAtTime() function to schedule the change. However, the
current code does not correctly clamp the value within the nominal
range. This CL fixes the problem.
(cherry picked from commit c97b506c1e32951dd39e11e453e1ecc29cc0b35c)
Bug: 1505086
Test: Locally confirmed with both negative and positive param values.
Change-Id: Ibb0aae168161af9ea95c5e11a929b3aa2c621c73
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5100625
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1235028}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5112838
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1497}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param.cc b/third_party/blink/renderer/modules/webaudio/audio_param.cc
index 8c7b9d07bb68ec51d21ea2132cc5ecbc39e5cd95..95a40d39c9214fd6555523bd7e7bd91e36d2c6c0 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_param.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_param.cc
@@ -120,12 +120,15 @@ void AudioParam::setValue(float value) {
void AudioParam::setValue(float value, ExceptionState& exception_state) {
WarnIfOutsideRange("value", value);
- // This is to signal any errors, if necessary, about conflicting
- // automations.
- setValueAtTime(value, Context()->currentTime(), exception_state);
- // This is to change the value so that an immediate query for the
- // value returns the expected values.
+ // Change the intrinsic value so that an immediate query for the value
+ // returns the value that the user code provided. It also clamps the value
+ // to the nominal range.
Handler().SetValue(value);
+
+ // Use the intrinsic value (after clamping) to schedule the actual
+ // automation event.
+ setValueAtTime(Handler().IntrinsicValue(), Context()->currentTime(),
+ exception_state);
}
float AudioParam::defaultValue() const {
diff --git a/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt b/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt
index 7bb2d0aec7feaed69424f209a2e3e031c7a9e512..ebe05a2c239d35be4729cc187aa77de6a44f5a41 100644
--- a/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt
+++ b/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt
@@ -1,5 +1,4 @@
CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.value 99 outside nominal range [0, 1]; value will be clamped.
-CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.setValueAtTime value 99 outside nominal range [0, 1]; value will be clamped.
CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.setValueAtTime value -1 outside nominal range [0, 1]; value will be clamped.
CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.linearRampToValueAtTime value 5 outside nominal range [0, 1]; value will be clamped.
This is a testharness.js-based test.

View File

@@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Guido Urdaneta <guidou@chromium.org>
Date: Fri, 10 Nov 2023 20:46:57 +0000
Subject: Use KeepAlive to prevent lifetime race with audio delivery
(cherry picked from commit 186dad16ae69183f02730fb26d84e1d53f9f1b04)
Bug: 1497984
Change-Id: Ic22729b2ef9690203bbb09555d32238959e93a0f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5009864
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1221614}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5018212
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/6099@{#500}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
index f68c265271b48f92ff67a752cf2bedac183bd2fc..a53053b12925b6aaa4fb201e7de2c00d4203bb2a 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
@@ -142,12 +142,12 @@ bool MediaStreamAudioTrackUnderlyingSource::StartFrameDelivery() {
return false;
}
- if (added_to_track_) {
+ if (is_connected_to_track_) {
return true;
}
WebMediaStreamAudioSink::AddToAudioTrack(this, WebMediaStreamTrack(track_));
- added_to_track_ = true;
+ is_connected_to_track_ = this;
return true;
}
@@ -159,7 +159,7 @@ void MediaStreamAudioTrackUnderlyingSource::DisconnectFromTrack() {
WebMediaStreamAudioSink::RemoveFromAudioTrack(this,
WebMediaStreamTrack(track_));
- added_to_track_ = false;
+ is_connected_to_track_.Clear();
track_.Clear();
}
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
index 334da29c2b210f92e9ee191275651406487601c3..4e7d22959dc8947c12d9ee2bb7acd814cc4db6b3 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/prefinalizer.h"
+#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
namespace blink {
@@ -80,10 +81,13 @@ class MODULES_EXPORT MediaStreamAudioTrackUnderlyingSource
const Member<ScriptWrappable> media_stream_track_processor_;
Member<MediaStreamComponent> track_;
- bool added_to_track_ = false;
std::unique_ptr<AudioBufferPool> buffer_pool_;
+ // This prevents collection of this object while it is still connected to a
+ // platform MediaStreamTrack.
+ SelfKeepAlive<MediaStreamAudioTrackUnderlyingSource> is_connected_to_track_;
+
SEQUENCE_CHECKER(sequence_checker_);
};

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Semel <paulsemel@chromium.org>
Date: Wed, 6 Dec 2023 15:52:56 +0000
Subject: ImageBitmapFactory: fix empty context dcheck
Approved by:
https://bugs.chromium.org/p/chromium/issues/detail?id=1502102#c34
(cherry picked from commit c4d2f15b8f97076c8fd0f9aa5814b94db698b75c)
Fixed: 1502102
Change-Id: Ib42d2897d62136ae835561bcf56884b5624060a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5071252
Commit-Queue: Paul Semel <paulsemel@chromium.org>
Reviewed-by: Jean-Philippe Gravel <jpgravel@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1230617}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5088373
Auto-Submit: Arthur Sonzogni <arthursonzogni@google.com>
Reviewed-by: Paul Semel <paulsemel@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1416}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
index 4693dbc043f27d3799c4df127a1a91905ca1860a..19a9bee39a6aafb528b004b7757a69f47cf10658 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
@@ -155,7 +155,9 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmapFromBlob(
ImageBitmapSource* bitmap_source,
absl::optional<gfx::Rect> crop_rect,
const ImageBitmapOptions* options) {
- DCHECK(script_state->ContextIsValid());
+ if (!script_state->ContextIsValid()) {
+ return ScriptPromise();
+ }
// imageOrientation: 'from-image' will be used to replace imageOrientation:
// 'none'. Adding a deprecation warning when 'none' is called in

View File

@@ -0,0 +1,110 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Guido Urdaneta <guidou@chromium.org>
Date: Thu, 18 Jan 2024 16:47:18 +0000
Subject: Exit early from RTCPeerConnectionHandler
For certain operations that require a live client
(i.e., RTCPeerConnection, which is garbage collected),
PeerConnectionHandler keeps a pointer to the client on the stack
to prevent garbage collection.
In some cases, the client may have already been garbage collected
(the client is null). In that case, there is no point in doing the
operation and it should exit early to avoid UAF/crashes.
This CL adds early exit to the cases that do not already have it.
Bug: 1514777
Change-Id: I27e9541cfaa74d978799c03e2832a0980f9e5710
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5210359
Reviewed-by: Tomas Gunnarsson <tommi@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1248826}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
index 473eb82685f004d960f3d488e3976a2305eda248..b6d893cc0f93d5bbb12b07734c63b31a52d662f1 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
@@ -1056,15 +1056,19 @@ bool RTCPeerConnectionHandler::Initialize(
WebLocalFrame* frame,
ExceptionState& exception_state) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- DCHECK(frame);
DCHECK(dependency_factory_);
- frame_ = frame;
CHECK(!initialize_called_);
initialize_called_ = true;
// Prevent garbage collection of client_ during processing.
auto* client_on_stack = client_.Get();
+ if (!client_on_stack) {
+ return false;
+ }
+
+ DCHECK(frame);
+ frame_ = frame;
peer_connection_tracker_ = PeerConnectionTracker::From(*frame);
configuration_ = server_configuration;
@@ -2312,10 +2316,13 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
int sdp_mline_index,
int component,
int address_family) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
// In order to ensure that the RTCPeerConnection is not garbage collected
// from under the function, we keep a pointer to it on the stack.
auto* client_on_stack = client_.Get();
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ if (!client_on_stack) {
+ return;
+ }
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
// This line can cause garbage collection.
auto* platform_candidate = MakeGarbageCollected<RTCIceCandidatePlatform>(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
index f8838ab0c5a31182e210cc6f42b9f489c7dd5365..f689a679a7589f16839349189cbfdf84efd14367 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -601,7 +601,7 @@ class RTCPeerConnectionHandlerTest : public SimTest {
waitable_event->Signal();
}
- public:
+ protected:
ScopedTestingPlatformSupport<AudioCapturerSourceTestingPlatformSupport>
webrtc_audio_device_platform_support_;
Persistent<MockRTCPeerConnectionHandlerClient> mock_client_;
@@ -1168,4 +1168,32 @@ TEST_F(RTCPeerConnectionHandlerTest,
observer->OnIceCandidate(native_candidate.get());
}
+TEST_F(RTCPeerConnectionHandlerTest,
+ OnIceCandidateAfterClientGarbageCollectionDoesNothing) {
+ testing::InSequence sequence;
+ EXPECT_CALL(*mock_tracker_.Get(),
+ TrackAddIceCandidate(pc_handler_.get(), _,
+ PeerConnectionTracker::kSourceLocal, true))
+ .Times(0);
+
+ std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
+ mock_dependency_factory_->CreateIceCandidate("sdpMid", 1, kDummySdp));
+ mock_client_ = nullptr;
+ WebHeap::CollectAllGarbageForTesting();
+ pc_handler_->observer()->OnIceCandidate(native_candidate.get());
+ RunMessageLoopsUntilIdle();
+}
+
+TEST_F(RTCPeerConnectionHandlerTest,
+ OnIceCandidateAfterClientGarbageCollectionFails) {
+ DummyExceptionStateForTesting exception_state;
+ auto pc_handler = CreateRTCPeerConnectionHandlerUnderTest();
+ mock_client_ = nullptr;
+ WebHeap::CollectAllGarbageForTesting();
+ EXPECT_FALSE(pc_handler->Initialize(
+ /*context=*/nullptr, webrtc::PeerConnectionInterface::RTCConfiguration(),
+ /*media_constraints=*/nullptr,
+ /*frame=*/nullptr, exception_state));
+}
+
} // namespace blink

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gustaf Ullberg <gustaf@chromium.org>
Date: Wed, 20 Dec 2023 16:59:29 +0000
Subject: WebRtcAudioSink: Stop on invalid configuration
(cherry picked from commit 340b7e300d380460a039a07b90f62d1febae9da5)
Bug: 1513170
Change-Id: Ia4ca55e9eafb81789b28b8b8c54e615ac28df633
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5136295
Reviewed-by: Harald Alvestrand <hta@chromium.org>
Commit-Queue: Gustaf Ullberg <gustaf@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1239233}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5136708
Owners-Override: Krishna Govind <govind@chromium.org>
Commit-Queue: Krishna Govind <govind@chromium.org>
Reviewed-by: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1566}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc b/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
index cd5b8b83ce3904f0d13152627602a57b2af116cf..de4a661d6322220ed04c471a14570e91f3f76896 100644
--- a/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
+++ b/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
@@ -121,7 +121,7 @@ void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
}
void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
- DCHECK(params.IsValid());
+ CHECK(params.IsValid());
SendLogMessage(base::StringPrintf("OnSetFormat([label=%s] {params=[%s]})",
adapter_->label().c_str(),
params.AsHumanReadableString().c_str()));

View File

@@ -0,0 +1,125 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jean-Philippe Gravel <jpgravel@chromium.org>
Date: Tue, 23 Jan 2024 21:37:50 +0000
Subject: Fix use-after-free in DrawTextInternal
DrawTextInternal was calling GetOrCreatePaintCanvas multiple times,
once at the start of the function, once inside of the
BaseRenderingContext2DAutoRestoreSkCanvas helper class and once in the
Draw call. GetOrCreatePaintCanvas destroys the canvas resource provider
if the GPU context is lost. If this happens on the second call to
GetOrCreatePaintCanvas, destroying the resource provider will
invalidate the cc::PaintCanvas returned by the first call to
GetOrCreatePaintCanvas.
The GPU process can technically crash at any point during the renderer
process execution (perhaps because of something another renderer
process did). We therefore have to assume that any call to
GetOrCreatePaintCanvas can invalidate previously returned
cc::PaintCanvas.
(cherry picked from commit d4a197e4913f8e5072263b59aedc29f2b5af3e93)
Change-Id: Ifa77735ab1b2b55b3d494f886b8566299937f6fe
Fixed: 1511567
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5198419
Reviewed-by: Fernando Serboncini <fserb@chromium.org>
Commit-Queue: Jean-Philippe Gravel <jpgravel@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1248204}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5230237
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/6099@{#1859}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index f09459b0b67c37d307c70a516731d05db49f49b8..89cb2a41b3eef8bb359984b0d14bfa0e4e19cfdc 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -2682,40 +2682,6 @@ const Font& BaseRenderingContext2D::AccessFont(HTMLCanvasElement* canvas) {
return GetState().GetFont();
}
-namespace {
-
-// Drawing methods need to use this instead of SkAutoCanvasRestore in case
-// overdraw detection substitutes the recording canvas (to discard overdrawn
-// draw calls).
-class BaseRenderingContext2DAutoRestoreSkCanvas {
- STACK_ALLOCATED();
-
- public:
- explicit BaseRenderingContext2DAutoRestoreSkCanvas(
- BaseRenderingContext2D* context)
- : context_(context) {
- DCHECK(context_);
- cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
- if (c) {
- save_count_ = c->getSaveCount();
- }
- }
-
- ~BaseRenderingContext2DAutoRestoreSkCanvas() {
- cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
- if (c) {
- c->restoreToCount(save_count_);
- }
- context_->ValidateStateStack();
- }
-
- private:
- BaseRenderingContext2D* context_;
- int save_count_ = 0;
-};
-
-} // namespace
-
void BaseRenderingContext2D::DrawTextInternal(
const String& text,
double x,
@@ -2736,8 +2702,10 @@ void BaseRenderingContext2D::DrawTextInternal(
canvas->GetDocument().UpdateStyleAndLayoutTreeForNode(
canvas, DocumentUpdateReason::kCanvas);
}
- cc::PaintCanvas* c = GetOrCreatePaintCanvas();
- if (!c) {
+
+ // Abort if we don't have a paint canvas (e.g. the context was lost).
+ cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas();
+ if (!paint_canvas) {
return;
}
@@ -2808,14 +2776,13 @@ void BaseRenderingContext2D::DrawTextInternal(
InflateStrokeRect(bounds);
}
- BaseRenderingContext2DAutoRestoreSkCanvas state_restorer(this);
if (use_max_width) {
- c->save();
+ paint_canvas->save();
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op)
// still work. As the width of canvas is scaled, so text can be scaled to
// match the given maxwidth, update text location so it appears on desired
// place.
- c->scale(ClampTo<float>(width / font_width), 1);
+ paint_canvas->scale(ClampTo<float>(width / font_width), 1);
location.set_x(location.x() / ClampTo<float>(width / font_width));
}
@@ -2846,6 +2813,16 @@ void BaseRenderingContext2D::DrawTextInternal(
{ return false; },
bounds, paint_type, CanvasRenderingContext2DState::kNoImage,
CanvasPerformanceMonitor::DrawType::kText);
+
+ if (use_max_width) {
+ // Cannot use `paint_canvas` in case recording canvas was substituted or
+ // destroyed during draw call.
+ cc::PaintCanvas* c = GetPaintCanvas();
+ if (c) {
+ c->restore();
+ }
+ }
+ ValidateStateStack();
}
TextMetrics* BaseRenderingContext2D::measureText(const String& text) {

View File

@@ -0,0 +1,175 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yi Gu <yigu@chromium.org>
Date: Fri, 1 Dec 2023 00:10:37 +0000
Subject: Check API permission before showing accounts UI
The accounts fetch could be delayed for legitimate reasons. A user may be
able to disable FedCM API (e.g. via settings or dismissing another FedCM
UI on the same RP origin) before the browser receives the accounts
response.
This patch checks the API permission before showing the accounts UI.
(cherry picked from commit 98676a2f66c4b4b802316eef70f4aab77e631f85)
Change-Id: Idbbe88912941113ec3f54d7f222845cd774dc897
Bug: 1500921
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5064052
Commit-Queue: Yi Gu <yigu@chromium.org>
Reviewed-by: Christian Biesinger <cbiesinger@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1229912}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5074630
Auto-Submit: Yi Gu <yigu@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1255}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index b2717870cd40ec50fb8c6d22fab5fae89f5c9a20..5c8431c19e376f493fbb22bfdf626188e1fdaf20 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -685,9 +685,7 @@ void FederatedAuthRequestImpl::RequestToken(
request_dialog_controller_ = CreateDialogController();
start_time_ = base::TimeTicks::Now();
- FederatedApiPermissionStatus permission_status =
- GetApiPermissionStatus(url::Origin::Create(
- idp_get_params_ptrs[0]->providers[0]->get_federated()->config_url));
+ FederatedApiPermissionStatus permission_status = GetApiPermissionStatus();
absl::optional<TokenStatus> error_token_status;
FederatedAuthRequestResult request_result =
@@ -896,8 +894,7 @@ void FederatedAuthRequestImpl::LogoutRps(
return;
}
- if (GetApiPermissionStatus(origin()) !=
- FederatedApiPermissionStatus::GRANTED) {
+ if (GetApiPermissionStatus() != FederatedApiPermissionStatus::GRANTED) {
CompleteLogoutRequest(LogoutRpsStatus::kError);
return;
}
@@ -1181,6 +1178,18 @@ void FederatedAuthRequestImpl::MaybeShowAccountsDialog() {
return;
}
+ // The accounts fetch could be delayed for legitimate reasons. A user may be
+ // able to disable FedCM API (e.g. via settings or dismissing another FedCM UI
+ // on the same RP origin) before the browser receives the accounts response.
+ // We should exit early without showing any UI.
+ if (GetApiPermissionStatus() != FederatedApiPermissionStatus::GRANTED) {
+ CompleteRequestWithError(
+ FederatedAuthRequestResult::kErrorDisabledInSettings,
+ TokenStatus::kDisabledInSettings,
+ /*should_delay_callback=*/true);
+ return;
+ }
+
// The RenderFrameHost may be alive but not visible in the following
// situations:
// Situation #1: User switched tabs
@@ -1619,9 +1628,7 @@ void FederatedAuthRequestImpl::OnAccountSelected(const GURL& idp_config_url,
// settings are changed while an existing FedCM UI is displayed. Ideally, we
// should enforce this check before all requests but users typically won't
// have time to disable the FedCM API in other types of requests.
- url::Origin idp_origin = url::Origin::Create(idp_config_url);
- if (GetApiPermissionStatus(idp_origin) !=
- FederatedApiPermissionStatus::GRANTED) {
+ if (GetApiPermissionStatus() != FederatedApiPermissionStatus::GRANTED) {
CompleteRequestWithError(
FederatedAuthRequestResult::kErrorDisabledInSettings,
TokenStatus::kDisabledInSettings,
@@ -2262,8 +2269,8 @@ void FederatedAuthRequestImpl::OnRejectRequest() {
}
}
-FederatedApiPermissionStatus FederatedAuthRequestImpl::GetApiPermissionStatus(
- const url::Origin& idp_origin) {
+FederatedApiPermissionStatus
+FederatedAuthRequestImpl::GetApiPermissionStatus() {
DCHECK(api_permission_delegate_);
FederatedApiPermissionStatus status =
api_permission_delegate_->GetApiPermissionStatus(GetEmbeddingOrigin());
@@ -2271,7 +2278,7 @@ FederatedApiPermissionStatus FederatedAuthRequestImpl::GetApiPermissionStatus(
// status API is enabled, in general or through OT.
if (status ==
FederatedApiPermissionStatus::BLOCKED_THIRD_PARTY_COOKIES_BLOCKED &&
- webid::GetIdpSigninStatusMode(render_frame_host(), idp_origin) ==
+ webid::GetIdpSigninStatusMode(render_frame_host(), url::Origin()) ==
FedCmIdpSigninStatusMode::ENABLED) {
status = FederatedApiPermissionStatus::GRANTED;
}
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h
index aaf21e3f443ae26d4918602943117d695c0e54ff..d7117ee9c1424107b168a45edc21b4182a27cbd8 100644
--- a/content/browser/webid/federated_auth_request_impl.h
+++ b/content/browser/webid/federated_auth_request_impl.h
@@ -109,10 +109,9 @@ class CONTENT_EXPORT FederatedAuthRequestImpl
// Rejects the pending request if it has not been resolved naturally yet.
void OnRejectRequest();
- // This wrapper around FederatedIdentityApiPermissionContextDelegate ensures
- // that we handle BLOCKED_THIRD_PARTY_COOKIES_BLOCKED correctly.
+ // Returns whether the API is enabled or not.
FederatedIdentityApiPermissionContextDelegate::PermissionStatus
- GetApiPermissionStatus(const url::Origin& idp_origin);
+ GetApiPermissionStatus();
struct IdentityProviderGetInfo {
IdentityProviderGetInfo(blink::mojom::IdentityProviderConfigPtr,
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc
index 347fc6a19609c88313ccbbe7fda7841c7ff8268d..ea886ed50780007ec0f2a7babc9caeaa58cb1bb8 100644
--- a/content/browser/webid/federated_auth_request_impl_unittest.cc
+++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -711,15 +711,28 @@ class TestDialogController
class TestApiPermissionDelegate : public MockApiPermissionDelegate {
public:
- std::pair<url::Origin, ApiPermissionStatus> permission_override_ =
+ using PermissionOverride = std::pair<url::Origin, ApiPermissionStatus>;
+ PermissionOverride permission_override_ =
std::make_pair(url::Origin(), ApiPermissionStatus::GRANTED);
+ absl::optional<std::pair<size_t, PermissionOverride>>
+ permission_override_for_nth_;
std::set<url::Origin> embargoed_origins_;
+ size_t api_invocation_counter{0};
ApiPermissionStatus GetApiPermissionStatus(
const url::Origin& origin) override {
+ ++api_invocation_counter;
+
if (embargoed_origins_.count(origin))
return ApiPermissionStatus::BLOCKED_EMBARGO;
+ if (permission_override_for_nth_ &&
+ permission_override_for_nth_->first == api_invocation_counter) {
+ return (origin == permission_override_for_nth_->second.first)
+ ? permission_override_for_nth_->second.second
+ : ApiPermissionStatus::GRANTED;
+ }
+
return (origin == permission_override_.first)
? permission_override_.second
: ApiPermissionStatus::GRANTED;
@@ -4991,4 +5004,23 @@ TEST_F(FederatedAuthRequestImplTest, InvalidResponseErrorDialogDisabled) {
EXPECT_FALSE(dialog_controller_state_.did_show_error_dialog);
}
+// Test that the account UI is not displayed if FedCM is disabled after accounts
+// fetch.
+TEST_F(FederatedAuthRequestImplTest,
+ AccountUiNotDisplayedIfFedCmDisabledAfterAccountsFetch) {
+ test_api_permission_delegate_->permission_override_for_nth_ = std::make_pair(
+ /*override the nth invocation=*/2,
+ std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
+ ApiPermissionStatus::BLOCKED_EMBARGO));
+
+ RequestExpectations expectations = {
+ RequestTokenStatus::kError,
+ FederatedAuthRequestResult::kErrorDisabledInSettings,
+ /*standalone_console_message=*/absl::nullopt,
+ /*selected_idp_config_url=*/absl::nullopt};
+ RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
+ EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
+ EXPECT_FALSE(did_show_accounts_dialog());
+}
+
} // namespace content

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mike Wasserman <msw@chromium.org>
Date: Thu, 21 Dec 2023 22:33:05 +0000
Subject: Speculative fix for UAF in
content::WebContentsImpl::ExitFullscreenMode
Bug: 1506535, 854815
Change-Id: Iace64d63f8cea2dbfbc761ad233db42451ec101c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5146875
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Auto-Submit: Mike Wasserman <msw@chromium.org>
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1240353}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index dd060f4207516af6b7db21593dcbed3848d47409..0ecc7989e7bfa459c80b4fe10705781257dd9b7d 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3748,7 +3748,12 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
static_cast<RenderWidgetHostViewBase*>(view)->ExitFullscreenMode();
if (delegate_) {
+ // This may spin the message loop and destroy this object crbug.com/1506535
+ base::WeakPtr<WebContentsImpl> weak_ptr = weak_factory_.GetWeakPtr();
delegate_->ExitFullscreenModeForTab(this);
+ if (!weak_ptr) {
+ return;
+ }
if (keyboard_lock_widget_)
delegate_->CancelKeyboardLockRequest(this);

View File

@@ -0,0 +1,165 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Fri, 19 Jan 2024 19:17:18 +0000
Subject: Update rendering state of automatic pull nodes before graph rendering
In rare cases, the rendering fan out count of automatic pull node
does not match the main thread fan out count after recreating
a platform destination followed by disconnection.
This CL forces the update of the rendering state of automatic
pull nodes before graph rendering to make sure that fan out counts
are synchronized before executing the audio processing function call.
NOTE: This change makes 2 WPTs fail. The follow-up work is planned
to address them once this patch is merged.
(cherry picked from commit f4bffa09b46c21147431179e1e6dd2b27bc35fbc)
Bug: 1505080
Test: Locally confirmed that ASAN doesn't crash on all repro cases.
Change-Id: I6768cd8bc64525ea9d56a19b9c58439e9cdab9a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5131958
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1246718}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5214669
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1833}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
index b2f3242426930b06694a12296206da1e7a7abfb7..490143f710dc51a93dd89fdc85035519db5e292b 100644
--- a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
@@ -40,9 +40,14 @@ AnalyserHandler::~AnalyserHandler() {
}
void AnalyserHandler::Process(uint32_t frames_to_process) {
- AudioBus* output_bus = Output(0).Bus();
+ DCHECK(Context()->IsAudioThread());
+
+ // It's possible that output is not connected. Assign nullptr to indicate
+ // such case.
+ AudioBus* output_bus = Output(0).RenderingFanOutCount() > 0
+ ? Output(0).Bus() : nullptr;
- if (!IsInitialized()) {
+ if (!IsInitialized() && output_bus) {
output_bus->Zero();
return;
}
@@ -54,6 +59,11 @@ void AnalyserHandler::Process(uint32_t frames_to_process) {
// Analyser reflects the current input.
analyser_.WriteInput(input_bus.get(), frames_to_process);
+ // Subsequent steps require `output_bus` to be valid.
+ if (!output_bus) {
+ return;
+ }
+
if (!Input(0).IsConnected()) {
// No inputs, so clear the output, and propagate the silence hint.
output_bus->Zero();
@@ -178,8 +188,12 @@ double AnalyserHandler::TailTime() const {
}
void AnalyserHandler::PullInputs(uint32_t frames_to_process) {
- // Render directly into the output bus
- Input(0).Pull(Output(0).Bus(), frames_to_process);
+ DCHECK(Context()->IsAudioThread());
+
+ AudioBus* output_bus = Output(0).RenderingFanOutCount() > 0
+ ? Output(0).Bus() : nullptr;
+
+ Input(0).Pull(output_bus, frames_to_process);
}
void AnalyserHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
index 0bf86b7d659533e0acd9cd0c902c6dd68b51e1e6..903e8172d7c381da2e2cb8e9962ea601c76b375a 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
@@ -119,12 +119,14 @@ void AudioWorkletHandler::Process(uint32_t frames_to_process) {
return;
}
- // If the input is not connected, inform the processor with nullptr.
+ // If the input or the output is not connected, inform the processor with
+ // nullptr.
for (unsigned i = 0; i < NumberOfInputs(); ++i) {
inputs_[i] = Input(i).IsConnected() ? Input(i).Bus() : nullptr;
}
for (unsigned i = 0; i < NumberOfOutputs(); ++i) {
- outputs_[i] = WrapRefCounted(Output(i).Bus());
+ outputs_[i] = Output(i).RenderingFanOutCount() > 0
+ ? WrapRefCounted(Output(i).Bus()) : nullptr;
}
for (const auto& param_name : param_value_map_.Keys()) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
index 181dfa92723843d5ce9ae3e7399215870ac1dc80..c3c53d7a7099d67a6bb76df55a6c71965ca3bf02 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
@@ -376,6 +376,12 @@ void AudioWorkletProcessor::CopyArrayBuffersToPort(
for (uint32_t bus_index = 0; bus_index < audio_port.size(); ++bus_index) {
const scoped_refptr<AudioBus>& audio_bus = audio_port[bus_index];
+
+ // nullptr indicates the output bus is not connected. Do not proceed.
+ if (!audio_bus) {
+ break;
+ }
+
for (uint32_t channel_index = 0;
channel_index < audio_bus->NumberOfChannels(); ++channel_index) {
auto backing_store = array_buffers[bus_index][channel_index]
diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
index fa1de8f37b9be681f7ac447bc3e3859e8909216d..4730383dafa957c2e84c009387d15d6fe479e5ba 100644
--- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
@@ -172,6 +172,16 @@ void DeferredTaskHandler::UpdateAutomaticPullNodes() {
base::AutoTryLock try_locker(automatic_pull_handlers_lock_);
if (try_locker.is_acquired()) {
rendering_automatic_pull_handlers_.assign(automatic_pull_handlers_);
+
+ // In rare cases, it is possible for automatic pull nodes' output bus
+ // to become stale. Make sure update their rendering output counts.
+ // crbug.com/1505080.
+ for (auto& handler : rendering_automatic_pull_handlers_) {
+ for (unsigned i = 0; i < handler->NumberOfOutputs(); ++i) {
+ handler->Output(i).UpdateRenderingState();
+ }
+ }
+
automatic_pull_handlers_need_updating_ = false;
}
}
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
index 33627204a6f538eba77bd8346952404814e4affa..ce0cfa40b691d859d372c9e6da7ff54fe64bbbe1 100644
--- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
@@ -43,7 +43,10 @@
if (actual.done)
task.done();
};
- sourceNode.connect(workletNode);
+ // To have valid ArrayBuffers for both input and output, we need
+ // both connections.
+ // See: https://github.com/WebAudio/web-audio-api/issues/2566
+ sourceNode.connect(workletNode).connect(context.destination);
sourceNode.start();
});
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fbac76d9b865bfdec552bf280e4a19ae1743ef4a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+[PASS] 3 inputs; 0 outputs
+[FAIL] 0 inputs; 3 outputs
+ assert_equals: outputs[0].length expected 1 but got 0
+Harness: the test ran to completion.
+

View File

@@ -0,0 +1,181 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kai Ninomiya <kainino@chromium.org>
Date: Thu, 7 Dec 2023 14:31:32 +0000
Subject: Fix reinit order in
ContextProviderCommandBuffer::BindToCurrentSequence
See comments for explanation.
(cherry picked from commit 7d8400ceb56db5fd97249f787251fe8b3928e6fd)
Bug: 1505632
Change-Id: I0f43821a9708af91303048332e9fae5e100deee5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5069480
Reviewed-by: Saifuddin Hitawala <hitawala@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Brendon Tiszka <tiszka@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1230735}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5095795
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Saifuddin Hitawala <hitawala@chromium.org>
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1424}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
index 4d516f50bf2270c7fcf152dad5a11795a3e02232..da496e51d04af6699058cea36de0da65a01cdc3a 100644
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
@@ -169,13 +169,13 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
}
// The transfer buffer is used to serialize Dawn commands
- transfer_buffer_ =
+ auto transfer_buffer =
std::make_unique<gpu::TransferBuffer>(webgpu_helper.get());
// The WebGPUImplementation exposes the WebGPUInterface, as well as the
// gpu::ContextSupport interface.
auto webgpu_impl = std::make_unique<gpu::webgpu::WebGPUImplementation>(
- webgpu_helper.get(), transfer_buffer_.get(), command_buffer_.get());
+ webgpu_helper.get(), transfer_buffer.get(), command_buffer_.get());
bind_result_ = webgpu_impl->Initialize(memory_limits_);
if (bind_result_ != gpu::ContextResult::kSuccess) {
DLOG(ERROR) << "Failed to initialize WebGPUImplementation.";
@@ -187,8 +187,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
std::string unique_context_name =
base::StringPrintf("%s-%p", type_name.c_str(), webgpu_impl.get());
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
+ // See note in the header (and keep it up to date if things change).
impl_ = webgpu_impl.get();
webgpu_interface_ = std::move(webgpu_impl);
+ transfer_buffer_ = std::move(transfer_buffer);
helper_ = std::move(webgpu_helper);
} else if (attributes_.enable_raster_interface &&
!attributes_.enable_gles2_interface &&
@@ -206,14 +209,14 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
}
// The transfer buffer is used to copy resources between the client
// process and the GPU process.
- transfer_buffer_ =
+ auto transfer_buffer =
std::make_unique<gpu::TransferBuffer>(raster_helper.get());
// The RasterImplementation exposes the RasterInterface, as well as the
// gpu::ContextSupport interface.
DCHECK(channel_);
auto raster_impl = std::make_unique<gpu::raster::RasterImplementation>(
- raster_helper.get(), transfer_buffer_.get(),
+ raster_helper.get(), transfer_buffer.get(),
attributes_.bind_generates_resource,
attributes_.lose_context_when_out_of_memory, command_buffer_.get(),
channel_->image_decode_accelerator_proxy());
@@ -230,8 +233,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
raster_impl->TraceBeginCHROMIUM("gpu_toplevel",
unique_context_name.c_str());
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
+ // See note in the header (and keep it up to date if things change).
impl_ = raster_impl.get();
raster_interface_ = std::move(raster_impl);
+ transfer_buffer_ = std::move(transfer_buffer);
helper_ = std::move(raster_helper);
} else {
// The GLES2 helper writes the command buffer protocol.
@@ -246,7 +252,7 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
// The transfer buffer is used to copy resources between the client
// process and the GPU process.
- transfer_buffer_ =
+ auto transfer_buffer =
std::make_unique<gpu::TransferBuffer>(gles2_helper.get());
// The GLES2Implementation exposes the OpenGLES2 API, as well as the
@@ -259,13 +265,13 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
// we only use it if grcontext_support was requested.
gles2_impl = std::make_unique<
skia_bindings::GLES2ImplementationWithGrContextSupport>(
- gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer_.get(),
+ gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer.get(),
attributes_.bind_generates_resource,
attributes_.lose_context_when_out_of_memory,
support_client_side_arrays, command_buffer_.get());
} else {
gles2_impl = std::make_unique<gpu::gles2::GLES2Implementation>(
- gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer_.get(),
+ gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer.get(),
attributes_.bind_generates_resource,
attributes_.lose_context_when_out_of_memory,
support_client_side_arrays, command_buffer_.get());
@@ -276,8 +282,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
return bind_result_;
}
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
+ // See note in the header (and keep it up to date if things change).
impl_ = gles2_impl.get();
gles2_impl_ = std::move(gles2_impl);
+ transfer_buffer_ = std::move(transfer_buffer);
helper_ = std::move(gles2_helper);
}
@@ -311,6 +320,7 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
switches::kEnableGpuClientTracing)) {
// This wraps the real GLES2Implementation and we should always use this
// instead when it's present.
+ // IMPORTANT: This holds a raw_ptr to gles2_impl_.
trace_impl_ = std::make_unique<gpu::gles2::GLES2TraceImplementation>(
gles2_impl_.get());
gl = trace_impl_.get();
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
index c5fdc66539ed7b0535e0ba84ac2858d7a95a4bb1..47600f1754a79a349ed48896bd8bab91b4634376 100644
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.h
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
@@ -156,19 +156,42 @@ class ContextProviderCommandBuffer
// associated shared images are destroyed.
std::unique_ptr<gpu::ClientSharedImageInterface> shared_image_interface_;
- base::Lock context_lock_; // Referenced by command_buffer_.
+ //////////////////////////////////////////////////////////////////////////////
+ // IMPORTANT NOTE: All of the objects in this block are part of a complex //
+ // graph of raw pointers (holder or pointee of various raw_ptrs). They are //
+ // defined in topological order: only later items point to earlier items. //
+ // - When writing any member, always ensure its pointers to earlier members
+ // are guaranteed to stay alive.
+ // - When clearing OR overwriting any member, always ensure objects that
+ // point to it have already been cleared.
+ // - The topological order of definitions guarantees that the
+ // destructors will be called in the correct order (bottom to top).
+ // - When overwriting multiple members, similarly do so in reverse order.
+ //
+ // Please note these comments are likely not to stay perfectly up-to-date.
+
+ base::Lock context_lock_;
+ // Points to the context_lock_ field of `this`.
std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_;
+
+ // Points to command_buffer_.
std::unique_ptr<gpu::CommandBufferHelper> helper_;
+ // Points to helper_.
std::unique_ptr<gpu::TransferBuffer> transfer_buffer_;
+ // Points to transfer_buffer_, helper_, and command_buffer_.
std::unique_ptr<gpu::gles2::GLES2Implementation> gles2_impl_;
+ // Points to gles2_impl_.
std::unique_ptr<gpu::gles2::GLES2TraceImplementation> trace_impl_;
+ // Points to transfer_buffer_, helper_, and command_buffer_.
std::unique_ptr<gpu::raster::RasterInterface> raster_interface_;
+ // Points to transfer_buffer_, helper_, and command_buffer_.
std::unique_ptr<gpu::webgpu::WebGPUInterface> webgpu_interface_;
+ // This is an alias for gles2_impl_, raster_interface_, or webgpu_interface_.
+ raw_ptr<gpu::ImplementationBase> impl_ = nullptr;
- // Owned by one of gles2_impl_, raster_interface_, or webgpu_interface_. It
- // must be declared last and cleared first.
- raw_ptr<gpu::ImplementationBase> impl_;
+ // END IMPORTANT NOTE //
+ //////////////////////////////////////////////////////////////////////////////
std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_;

View File

@@ -0,0 +1,390 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 26 Oct 2023 11:07:47 +0900
Subject: Enable V8 code cache for custom schemes
Add a new category in ContentClient::AddAdditionalSchemes which allows
embedders to make custom schemes allow V8 code cache.
Chromium CL: https://chromium-review.googlesource.com/c/chromium/src/+/5019665
diff --git a/content/browser/code_cache/generated_code_cache.cc b/content/browser/code_cache/generated_code_cache.cc
index 86058c25d4128539c3f6f39691550a7ee8f23064..04dd303919a3dc12c6a3c6770df8dac456084f57 100644
--- a/content/browser/code_cache/generated_code_cache.cc
+++ b/content/browser/code_cache/generated_code_cache.cc
@@ -6,6 +6,7 @@
#include <iostream>
+#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
@@ -24,6 +25,7 @@
#include "net/base/url_util.h"
#include "net/http/http_cache.h"
#include "url/gurl.h"
+#include "url/url_util.h"
using storage::BigIOBuffer;
@@ -46,24 +48,37 @@ void CheckValidKeys(const GURL& resource_url,
GeneratedCodeCache::CodeCacheType cache_type) {
// If the resource url is invalid don't cache the code.
DCHECK(resource_url.is_valid());
+ bool resource_url_allows_code_cache =
+ base::Contains(url::GetCodeCacheSchemes(), resource_url.scheme());
bool resource_url_is_chrome_or_chrome_untrusted =
resource_url.SchemeIs(content::kChromeUIScheme) ||
resource_url.SchemeIs(content::kChromeUIUntrustedScheme);
DCHECK(resource_url.SchemeIsHTTPOrHTTPS() ||
+ resource_url_allows_code_cache ||
resource_url_is_chrome_or_chrome_untrusted);
- // |origin_lock| should be either empty or should have
- // Http/Https/chrome/chrome-untrusted schemes and it should not be a URL with
- // opaque origin. Empty origin_locks are allowed when the renderer is not
- // locked to an origin.
+ // |origin_lock| should be either empty or should have code cache allowed
+ // schemes (http/https/chrome/chrome-untrusted or other custom schemes added
+ // by url::AddCodeCacheScheme), and it should not be a URL with opaque
+ // origin. Empty origin_locks are allowed when the renderer is not locked to
+ // an origin.
+ bool origin_lock_allows_code_cache =
+ base::Contains(url::GetCodeCacheSchemes(), origin_lock.scheme());
bool origin_lock_is_chrome_or_chrome_untrusted =
origin_lock.SchemeIs(content::kChromeUIScheme) ||
origin_lock.SchemeIs(content::kChromeUIUntrustedScheme);
DCHECK(origin_lock.is_empty() ||
((origin_lock.SchemeIsHTTPOrHTTPS() ||
+ origin_lock_allows_code_cache ||
origin_lock_is_chrome_or_chrome_untrusted) &&
!url::Origin::Create(origin_lock).opaque()));
+ // The custom schemes share the cache type with http(s).
+ if (origin_lock_allows_code_cache || resource_url_allows_code_cache) {
+ DCHECK(cache_type == GeneratedCodeCache::kJavaScript ||
+ cache_type == GeneratedCodeCache::kWebAssembly);
+ }
+
// The chrome and chrome-untrusted schemes are only used with the WebUI
// code cache type.
DCHECK_EQ(origin_lock_is_chrome_or_chrome_untrusted,
diff --git a/content/browser/code_cache/generated_code_cache.h b/content/browser/code_cache/generated_code_cache.h
index f5c5ff2c89489257003dfe3284ee9de9f517c99b..fdd2e2483171c4d43963590200817dac27d22cf9 100644
--- a/content/browser/code_cache/generated_code_cache.h
+++ b/content/browser/code_cache/generated_code_cache.h
@@ -52,12 +52,14 @@ class CONTENT_EXPORT GeneratedCodeCache {
// Cache type. Used for collecting statistics for JS and Wasm in separate
// buckets.
enum CodeCacheType {
- // JavaScript from http(s) pages.
+ // JavaScript from pages of http(s) schemes or custom schemes registered by
+ // url::AddCodeCacheScheme.
kJavaScript,
- // WebAssembly from http(s) pages. This cache allows more total size and
- // more size per item than the JavaScript cache, since some
- // WebAssembly programs are very large.
+ // WebAssembly from pages of http(s) schemes or custom schemes registered by
+ // url::AddCodeCacheScheme. This cache allows more total size and more size
+ // per item than the JavaScript cache, since some WebAssembly programs are
+ // very large.
kWebAssembly,
// JavaScript from chrome and chrome-untrusted pages. The resource URLs are
diff --git a/content/browser/code_cache/generated_code_cache_browsertest.cc b/content/browser/code_cache/generated_code_cache_browsertest.cc
index c06245a4cf0fff1292927482032af5c02ddcbc67..a1cfa8c8e428d4c1cd32bda7707048a94c1001bb 100644
--- a/content/browser/code_cache/generated_code_cache_browsertest.cc
+++ b/content/browser/code_cache/generated_code_cache_browsertest.cc
@@ -5,17 +5,27 @@
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
+#include "components/services/storage/storage_service_impl.h"
#include "content/browser/code_cache/generated_code_cache.h"
+#include "content/browser/code_cache/generated_code_cache_context.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/common/url_schemes.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_browser_context.h"
#include "content/shell/browser/shell.h"
+#include "content/test/test_content_client.h"
#include "net/dns/mock_host_resolver.h"
+#include "url/url_util.h"
namespace content {
namespace {
+const std::string kCodeCacheScheme = "test-code-cache"
+
bool SupportsSharedWorker() {
#if BUILDFLAG(IS_ANDROID)
// SharedWorkers are not enabled on Android. https://crbug.com/154571
@@ -379,4 +389,80 @@ IN_PROC_BROWSER_TEST_P(CodeCacheBrowserTest,
}
}
+class CodeCacheInCustomSchemeBrowserTest : public ContentBrowserTest {
+ public:
+ CodeCacheInCustomSchemeBrowserTest() {
+ SetContentClient(&test_content_client_);
+ ReRegisterContentSchemesForTests();
+ }
+
+ private:
+ class CustomSchemeContentClient : public TestContentClient {
+ public:
+ void AddAdditionalSchemes(Schemes* schemes) override {
+ schemes->standard_schemes.push_back(kCodeCacheScheme);
+ schemes->code_cache_schemes.push_back(kCodeCacheScheme);
+ }
+ };
+
+ CustomSchemeContentClient test_content_client_;
+ url::ScopedSchemeRegistryForTests scheme_registry_;
+};
+
+IN_PROC_BROWSER_TEST_F(CodeCacheInCustomSchemeBrowserTest,
+ AllowedCustomSchemeCanGenerateCodeCache) {
+ // Create browser context and get code cache context.
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ TestBrowserContext browser_context;
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ browser_context.GetDefaultStoragePartition());
+ scoped_refptr<GeneratedCodeCacheContext> context =
+ partition->GetGeneratedCodeCacheContext();
+ EXPECT_NE(context, nullptr);
+
+ GURL url(kCodeCacheScheme + "://host4/script.js");
+ GURL origin(kCodeCacheScheme + "://host1:1/");
+ ASSERT_TRUE(url.is_valid());
+ ASSERT_TRUE(origin.is_valid());
+ std::string data("SomeData");
+
+ // Add a code cache entry for the custom scheme.
+ base::test::TestFuture<void> add_entry_future;
+ GeneratedCodeCacheContext::RunOrPostTask(
+ context.get(), FROM_HERE,
+ base::BindOnce([](scoped_refptr<GeneratedCodeCacheContext> context,
+ const GURL& url,
+ const GURL& origin,
+ const std::string& data,
+ base::OnceClosure callback) {
+ context->generated_js_code_cache()->WriteEntry(
+ url, origin, net::NetworkIsolationKey(),
+ base::Time::Now(), std::vector<uint8_t>(data.begin(), data.end()));
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, std::move(callback));
+ }, context, url, origin, data, add_entry_future.GetCallback()));
+ ASSERT_TRUE(add_entry_future.Wait());
+
+ // Get the code cache entry.
+ base::test::TestFuture<std::string> get_entry_future;
+ GeneratedCodeCacheContext::RunOrPostTask(
+ context.get(), FROM_HERE,
+ base::BindOnce([](scoped_refptr<GeneratedCodeCacheContext> context,
+ const GURL& url,
+ const GURL& origin,
+ base::OnceCallback<void(std::string)> callback) {
+ context->generated_js_code_cache()->FetchEntry(
+ url, origin, net::NetworkIsolationKey(),
+ base::BindOnce([](base::OnceCallback<void(std::string)> callback,
+ const base::Time& response_time,
+ mojo_base::BigBuffer buffer) {
+ std::string data(buffer.data(), buffer.data() + buffer.size());
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), data));
+ }, std::move(callback)));
+ }, context, url, origin, get_entry_future.GetCallback()));
+ ASSERT_TRUE(get_entry_future.Wait());
+ ASSERT_EQ(data, get_entry_future.Get<0>());
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/code_cache_host_impl.cc b/content/browser/renderer_host/code_cache_host_impl.cc
index 6b9e5065dc570b506c4c2606d536319d98684e12..9d1f337b9c9890b6b7afda40bf2f829ff2a25bfd 100644
--- a/content/browser/renderer_host/code_cache_host_impl.cc
+++ b/content/browser/renderer_host/code_cache_host_impl.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/metrics/histogram_functions.h"
@@ -28,6 +29,7 @@
#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
#include "url/gurl.h"
#include "url/origin.h"
+#include "url/url_util.h"
using blink::mojom::CacheStorageError;
@@ -40,6 +42,11 @@ enum class Operation {
kWrite,
};
+bool ProcessLockURLIsCodeCacheScheme(const ProcessLock& process_lock) {
+ return base::Contains(url::GetCodeCacheSchemes(),
+ process_lock.lock_url().scheme());
+}
+
bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
int render_process_id,
Operation operation) {
@@ -47,11 +54,12 @@ bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
ChildProcessSecurityPolicyImpl::GetInstance()->GetProcessLock(
render_process_id);
- // Code caching is only allowed for http(s) and chrome/chrome-untrusted
- // scripts. Furthermore, there is no way for http(s) pages to load chrome or
- // chrome-untrusted scripts, so any http(s) page attempting to store data
- // about a chrome or chrome-untrusted script would be an indication of
- // suspicious activity.
+ // Code caching is only allowed for scripts from open-web (http/https and
+ // custom schemes registered with url::AddCodeCacheScheme) and
+ // chrome/chrome-untrusted schemes. Furthermore, there is no way for
+ // open-web pages to load chrome or chrome-untrusted scripts, so any
+ // open-web page attempting to store data about a chrome or
+ // chrome-untrusted script would be an indication of suspicious activity.
if (resource_url.SchemeIs(content::kChromeUIScheme) ||
resource_url.SchemeIs(content::kChromeUIUntrustedScheme)) {
if (!process_lock.is_locked_to_site()) {
@@ -60,9 +68,10 @@ bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
return false;
}
if (process_lock.matches_scheme(url::kHttpScheme) ||
- process_lock.matches_scheme(url::kHttpsScheme)) {
+ process_lock.matches_scheme(url::kHttpsScheme) ||
+ ProcessLockURLIsCodeCacheScheme(process_lock)) {
if (operation == Operation::kWrite) {
- mojo::ReportBadMessage("HTTP(S) pages cannot cache WebUI code");
+ mojo::ReportBadMessage("Open-web pages cannot cache WebUI code");
}
return false;
}
@@ -72,7 +81,16 @@ bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
return process_lock.matches_scheme(content::kChromeUIScheme) ||
process_lock.matches_scheme(content::kChromeUIUntrustedScheme);
}
- if (resource_url.SchemeIsHTTPOrHTTPS()) {
+ if (base::Contains(url::GetCodeCacheSchemes(), resource_url.scheme()) &&
+ (process_lock.matches_scheme(url::kHttpScheme) ||
+ process_lock.matches_scheme(url::kHttpsScheme))) {
+ // While custom schemes registered with url::AddCodeCacheScheme are
+ // considered as open-web pages, we still do not trust http(s) pages
+ // loading resources from custom schemes.
+ return false;
+ }
+ if (resource_url.SchemeIsHTTPOrHTTPS() ||
+ base::Contains(url::GetCodeCacheSchemes(), resource_url.scheme())) {
if (process_lock.matches_scheme(content::kChromeUIScheme) ||
process_lock.matches_scheme(content::kChromeUIUntrustedScheme)) {
// It is possible for WebUI pages to include open-web content, but such
@@ -136,15 +154,17 @@ absl::optional<GURL> GetSecondaryKeyForCodeCache(const GURL& resource_url,
return absl::nullopt;
// Case 3: process_lock_url is used to enfore site-isolation in code caches.
- // Http/https/chrome schemes are safe to be used as a secondary key. Other
- // schemes could be enabled if they are known to be safe and if it is
- // required to cache code from those origins.
+ // Code cache enabled schemes (http/https/chrome/chrome-untrusted and custom
+ // schemes registered with url::AddCodeCacheScheme) are safe to be used as a
+ // secondary key. Other schemes could be enabled if they are known to be safe
+ // and if it is required to cache code from those origins.
//
// file:// URLs will have a "file:" process lock and would thus share a
// cache across all file:// URLs. That would likely be ok for security, but
// since this case is not performance sensitive we will keep things simple and
- // limit the cache to http/https/chrome/chrome-untrusted processes.
- if (process_lock.matches_scheme(url::kHttpScheme) ||
+ // limit the cache to processes of code cache enabled schemes.
+ if (ProcessLockURLIsCodeCacheScheme(process_lock) ||
+ process_lock.matches_scheme(url::kHttpScheme) ||
process_lock.matches_scheme(url::kHttpsScheme) ||
process_lock.matches_scheme(content::kChromeUIScheme) ||
process_lock.matches_scheme(content::kChromeUIUntrustedScheme)) {
diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc
index ce9644d33fe83379127b01bf9a2b1c4badc3bc7c..532b14e013b9b65ba390f09e8bb8934bb278a0d8 100644
--- a/content/common/url_schemes.cc
+++ b/content/common/url_schemes.cc
@@ -98,6 +98,9 @@ void RegisterContentSchemes(bool should_lock_registry) {
for (auto& scheme : schemes.empty_document_schemes)
url::AddEmptyDocumentScheme(scheme.c_str());
+ for (auto& scheme : schemes.code_cache_schemes)
+ url::AddCodeCacheScheme(scheme.c_str());
+
#if BUILDFLAG(IS_ANDROID)
if (schemes.allow_non_standard_schemes_in_origins)
url::EnableNonStandardSchemesForAndroidWebView();
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
index 26bf98bc78b3a02dedf0b46b7c44d135507cb2d3..095582e753fe7b5012eaab7ade16a317aea20277 100644
--- a/content/public/common/content_client.h
+++ b/content/public/common/content_client.h
@@ -139,6 +139,9 @@ class CONTENT_EXPORT ContentClient {
// Registers a URL scheme as strictly empty documents, allowing them to
// commit synchronously.
std::vector<std::string> empty_document_schemes;
+ // Registers a URL scheme whose js and wasm scripts have V8 code cache
+ // enabled.
+ std::vector<std::string> code_cache_schemes;
// Registers a URL scheme as extension scheme.
std::vector<std::string> extension_schemes;
// Registers a URL scheme with a predefined default custom handler.
diff --git a/url/url_util.cc b/url/url_util.cc
index 001c50e72fd244a40f5629a2a26324bad4bbd300..4ad52f3faa1f67fc1f4047c6e1118c02d792402b 100644
--- a/url/url_util.cc
+++ b/url/url_util.cc
@@ -114,6 +114,9 @@ struct SchemeRegistry {
kAboutScheme,
};
+ // Embedder schemes that have V8 code cache enabled in js and wasm scripts.
+ std::vector<std::string> code_cache_schemes = {};
+
// Schemes with a predefined default custom handler.
std::vector<SchemeWithHandler> predefined_handler_schemes;
@@ -673,6 +676,15 @@ const std::vector<std::string>& GetEmptyDocumentSchemes() {
return GetSchemeRegistry().empty_document_schemes;
}
+void AddCodeCacheScheme(const char* new_scheme) {
+ DoAddScheme(new_scheme,
+ &GetSchemeRegistryWithoutLocking()->code_cache_schemes);
+}
+
+const std::vector<std::string>& GetCodeCacheSchemes() {
+ return GetSchemeRegistry().code_cache_schemes;
+}
+
void AddPredefinedHandlerScheme(const char* new_scheme, const char* handler) {
DoAddSchemeWithHandler(
new_scheme, handler,
diff --git a/url/url_util.h b/url/url_util.h
index 670552a8ce12ad50d7777a0fc52ca42f2aebbd99..14f09ecdbf6dfd63e0c7208ec7c74dd4a32f885d 100644
--- a/url/url_util.h
+++ b/url/url_util.h
@@ -115,6 +115,15 @@ COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCSPBypassingSchemes();
COMPONENT_EXPORT(URL) void AddEmptyDocumentScheme(const char* new_scheme);
COMPONENT_EXPORT(URL) const std::vector<std::string>& GetEmptyDocumentSchemes();
+// Adds an application-defined scheme to the list of schemes that have V8 code
+// cache enabled for the js and wasm scripts.
+// The WebUI schemes (chrome/chrome-untrusted) do not belong to this list, as
+// they are treated as a separate cache type for security purpose.
+// The http(s) schemes do not belong to this list neither, they always have V8
+// code cache enabled and can not load scripts from schemes in this list.
+COMPONENT_EXPORT(URL) void AddCodeCacheScheme(const char* new_scheme);
+COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCodeCacheSchemes();
+
// Adds a scheme with a predefined default handler.
//
// This pair of strings must be normalized protocol handler parameters as

View File

@@ -0,0 +1,106 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Stiles <johnstiles@google.com>
Date: Thu, 1 Feb 2024 20:40:55 +0000
Subject: Fix a crash when a BMP image contains an unnecessary EOF code.
Previously, this would try to perform color correction on a row
one past the end of the image data.
(cherry picked from commit 4bdd8d61bebbba9fab77fa86a8f66b305995199b)
Bug: 1521893
Change-Id: I425437005b9ef400138556705616095857d2cf0d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5241305
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Peter Kasting <pkasting@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1253633}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5259699
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/branch-heads/6099@{#1915}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist b/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist
index 42d0414da143f509a89551c8b09762949f8011c2..49e238e38fef374c698fcdc1d4b50d4ed7670c3d 100644
--- a/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist
+++ b/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist
@@ -403,6 +403,7 @@
../../web_tests/images/resources/truncated.webp
../../web_tests/images/resources/truncated2.webp
../../web_tests/images/resources/twitter_favicon.ico
+../../web_tests/images/resources/unnecessary-eof.bmp
../../web_tests/images/resources/webp-animated-icc-xmp.webp
../../web_tests/images/resources/webp-animated-large.webp
../../web_tests/images/resources/webp-animated-no-blend.webp
diff --git a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc
index 85e3591ac707297944b81cc4673b75d308417bd1..6c867a76a44c57ae818e7a00df30d046077b4d4c 100644
--- a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc
+++ b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc
@@ -98,6 +98,19 @@ TEST(BMPImageDecoderTest, crbug752898) {
decoder->DecodeFrameBufferAtIndex(0);
}
+// Verify that decoding an image with an unnecessary EOF marker does not crash.
+TEST(BMPImageDecoderTest, allowEOFWhenPastEndOfImage) {
+ static constexpr char kBmpFile[] = "/images/resources/unnecessary-eof.bmp";
+ scoped_refptr<SharedBuffer> data = ReadFile(kBmpFile);
+ ASSERT_TRUE(data.get());
+
+ std::unique_ptr<ImageDecoder> decoder = CreateBMPDecoder();
+ decoder->SetData(data.get(), true);
+ ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(0);
+ EXPECT_EQ(ImageFrame::kFrameComplete, frame->GetStatus());
+ EXPECT_FALSE(decoder->Failed());
+}
+
class BMPImageDecoderCorpusTest : public ImageDecoderBaseTest {
public:
BMPImageDecoderCorpusTest() : ImageDecoderBaseTest("bmp") {}
diff --git a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
index 6b6bcb2e8fce05062e80b84283fd635f9d4bf008..b7bbbf51a1b419d1641db5e2f062cfefb2eae554 100644
--- a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
+++ b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
@@ -886,7 +886,8 @@ BMPImageReader::ProcessingResult BMPImageReader::ProcessRLEData() {
// the image.
const uint8_t count = ReadUint8(0);
const uint8_t code = ReadUint8(1);
- if ((count || (code != 1)) && PastEndOfImage(0)) {
+ const bool is_past_end_of_image = PastEndOfImage(0);
+ if ((count || (code != 1)) && is_past_end_of_image) {
return kFailure;
}
@@ -911,7 +912,9 @@ BMPImageReader::ProcessingResult BMPImageReader::ProcessRLEData() {
: (coord_.y() > 0))) {
buffer_->SetHasAlpha(true);
}
- ColorCorrectCurrentRow();
+ if (!is_past_end_of_image) {
+ ColorCorrectCurrentRow();
+ }
// There's no need to move |coord_| here to trigger the caller
// to call SetPixelsChanged(). If the only thing that's changed
// is the alpha state, that will be properly written into the
@@ -1136,6 +1139,13 @@ void BMPImageReader::ColorCorrectCurrentRow() {
if (!transform) {
return;
}
+ int decoder_width = parent_->Size().width();
+ // Enforce 0 ≤ current row < bitmap height.
+ CHECK_GE(coord_.y(), 0);
+ CHECK_LT(coord_.y(), buffer_->Bitmap().height());
+ // Enforce decoder width == bitmap width exactly. (The bitmap rowbytes might
+ // add a bit of padding, but we are only converting one row at a time.)
+ CHECK_EQ(decoder_width, buffer_->Bitmap().width());
ImageFrame::PixelData* const row = buffer_->GetAddr(0, coord_.y());
const skcms_PixelFormat fmt = XformColorFormat();
const skcms_AlphaFormat alpha =
@@ -1144,7 +1154,7 @@ void BMPImageReader::ColorCorrectCurrentRow() {
: skcms_AlphaFormat_Unpremul;
const bool success =
skcms_Transform(row, fmt, alpha, transform->SrcProfile(), row, fmt, alpha,
- transform->DstProfile(), parent_->Size().width());
+ transform->DstProfile(), decoder_width);
DCHECK(success);
buffer_->SetPixelsChanged(true);
}

View File

@@ -1,19 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: clavin <clavin@electronjs.org>
Date: Wed, 30 Aug 2023 18:15:36 -0700
Date: Mon, 11 Dec 2023 20:43:34 -0300
Subject: fix: activate background material on windows
This patch adds a condition to the HWND message handler to allow windows
with translucent background materials to become activated.
It also ensures the lParam of WM_NCACTIVATE is set to -1 so as to not repaint
the client area, which can lead to a title bar incorrectly being displayed in
frameless windows.
This patch likely can't be upstreamed as-is, as Chromium doesn't have
this use case in mind currently.
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 13268bd89c710690eed5296f4b2157e9476f195e..37de479e95d49f4d2b1d8164c9e3f6a7bcd82612 100644
index 13268bd89c710690eed5296f4b2157e9476f195e..0491dc500896a9ce0c8ad95ada6a175c9e94f3d3 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1094,7 +1094,7 @@ void HWNDMessageHandler::FrameTypeChanged() {
@@ -1094,13 +1094,13 @@ void HWNDMessageHandler::FrameTypeChanged() {
void HWNDMessageHandler::PaintAsActiveChanged() {
if (!delegate_->HasNonClientView() || !delegate_->CanActivate() ||
@@ -22,3 +26,34 @@ index 13268bd89c710690eed5296f4b2157e9476f195e..37de479e95d49f4d2b1d8164c9e3f6a7
(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN)) {
return;
}
DefWindowProcWithRedrawLock(WM_NCACTIVATE, delegate_->ShouldPaintAsActive(),
- 0);
+ delegate_->HasFrame() ? 0 : -1);
}
void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon,
@@ -2393,17 +2393,18 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message,
if (IsVisible())
delegate_->SchedulePaint();
- // Calling DefWindowProc is only necessary if there's a system frame being
- // drawn. Otherwise it can draw an incorrect title bar and cause visual
- // corruption.
- if (!delegate_->HasFrame() ||
+ // If the window is translucent, it may have the Mica background.
+ // In that case, it's necessary to call |DefWindowProc|, but we can
+ // pass -1 in the lParam to prevent any non-client area elements from
+ // being displayed.
+ if ((!delegate_->HasFrame() && !is_translucent_) ||
delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) {
SetMsgHandled(TRUE);
return TRUE;
}
return DefWindowProcWithRedrawLock(WM_NCACTIVATE, paint_as_active || active,
- 0);
+ delegate_->HasFrame() ? 0 : -1);
}
LRESULT HWNDMessageHandler::OnNCCalcSize(BOOL mode, LPARAM l_param) {

View File

@@ -0,0 +1,279 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ryan Manuel <ryanm@cypress.io>
Date: Wed, 6 Dec 2023 14:38:07 -0600
Subject: fix font flooding in dev tools
Added in this CL: https://chromium-review.googlesource.com/c/chromium/src/+/5033885
This patch resolves an issue that has been fixed in chromium involving font requests being sent multiple times to DevTools for a single request.
This patch can be removed when chromium reaches version 121.0.6157.0.
diff --git a/AUTHORS b/AUTHORS
index 6714ac1cf3632138ba1a8f0ebc9f7b428f562449..ac5e5e98f20bcdc98a77426efc091340c3798191 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1121,6 +1121,7 @@ Rulong Chen <rulong.crl@alibaba-inc.com>
Russell Davis <russell.davis@gmail.com>
Ryan Ackley <ryanackley@gmail.com>
Ryan Gonzalez <rymg19@gmail.com>
+Ryan Manuel <rfmanuel@gmail.com>
Ryan Norton <rnorton10@gmail.com>
Ryan Sleevi <ryan-chromium-dev@sleevi.com>
Ryan Yoakum <ryoakum@skobalt.com>
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index f0f31dbd58ceb4507155e1c8f26351e14cb6f5cf..3b4b71d76b2fadaaeb5295a88e088a2388d5d525 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -1851,6 +1851,14 @@ BASE_FEATURE(kUACHOverrideBlank,
"UACHOverrideBlank",
base::FEATURE_DISABLED_BY_DEFAULT);
+// If enabled, the body of `EmulateLoadStartedForInspector` is executed only
+// once per Resource per ResourceFetcher, and thus duplicated network load
+// entries in DevTools caused by `EmulateLoadStartedForInspector` are removed.
+// https://crbug.com/1502591
+BASE_FEATURE(kEmulateLoadStartedForInspectorOncePerResource,
+ "kEmulateLoadStartedForInspectorOncePerResource",
+ base::FEATURE_ENABLED_BY_DEFAULT);
+
BASE_FEATURE(kURLSetPortCheckOverflow,
"URLSetPortCheckOverflow",
base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index b9eb81f257b3f3dfe288987ca853371f4efd300b..5ea3eb74a0a4111b0178c44b1f94f939f5f18857 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -1209,6 +1209,9 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kTimedHTMLParserBudget);
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kUACHOverrideBlank);
+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(
+ kEmulateLoadStartedForInspectorOncePerResource);
+
// Disallow setting URL ports with a value that will overflow.
// See https://crbug.com/1416017
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kURLSetPortCheckOverflow);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 5bfbe590f3200c8bdbd357347819bff1ba4e65e1..9bf0372aee79ffd62a475f9d9076b10e49634dba 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -755,6 +755,19 @@ Resource* ResourceFetcher::CachedResource(const KURL& resource_url) const {
return it->value.Get();
}
+bool ResourceFetcher::ResourceHasBeenEmulatedLoadStartedForInspector(
+ const KURL& resource_url) const {
+ if (resource_url.IsEmpty()) {
+ return false;
+ }
+ KURL url = MemoryCache::RemoveFragmentIdentifierIfNeeded(resource_url);
+ const auto it = emulated_load_started_for_inspector_resources_map_.find(url);
+ if (it == emulated_load_started_for_inspector_resources_map_.end()) {
+ return false;
+ }
+ return true;
+}
+
const HeapHashSet<Member<Resource>>
ResourceFetcher::MoveResourceStrongReferences() {
document_resource_strong_refs_total_size_ = 0;
@@ -2650,11 +2663,25 @@ void ResourceFetcher::EmulateLoadStartedForInspector(
if (CachedResource(url)) {
return;
}
+
+ if (ResourceHasBeenEmulatedLoadStartedForInspector(url)) {
+ return;
+ }
+
if (resource->ErrorOccurred()) {
// We should ideally replay the error steps, but we cannot.
return;
}
+ if (base::FeatureList::IsEnabled(
+ features::kEmulateLoadStartedForInspectorOncePerResource)) {
+ // Update the emulated load started for inspector resources map with the
+ // resource so that future emulations of the same resource won't happen.
+ String resource_url = MemoryCache::RemoveFragmentIdentifierIfNeeded(url);
+ emulated_load_started_for_inspector_resources_map_.Set(resource_url,
+ resource);
+ }
+
ResourceRequest resource_request(url);
resource_request.SetRequestContext(request_context);
resource_request.SetRequestDestination(request_destination);
@@ -2944,6 +2971,7 @@ void ResourceFetcher::Trace(Visitor* visitor) const {
visitor->Trace(loaders_);
visitor->Trace(non_blocking_loaders_);
visitor->Trace(cached_resources_map_);
+ visitor->Trace(emulated_load_started_for_inspector_resources_map_);
visitor->Trace(image_resources_);
visitor->Trace(not_loaded_image_resources_);
visitor->Trace(preloads_);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index c437d854203b419091a15bac36e6292646af28e4..455b6676131fb9454afe140a5d0915fc27288565 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -179,6 +179,7 @@ class PLATFORM_EXPORT ResourceFetcher
std::unique_ptr<WebCodeCacheLoader> CreateCodeCacheLoader();
Resource* CachedResource(const KURL&) const;
+ bool ResourceHasBeenEmulatedLoadStartedForInspector(const KURL&) const;
// Registers an callback to be called with the resource priority of the fetch
// made to the specified URL. When `new_load_only` is set to false,
@@ -563,6 +564,15 @@ class PLATFORM_EXPORT ResourceFetcher
// Weak reference to all the fetched resources.
DocumentResourceMap cached_resources_map_;
+ // When a resource is in the global memory cache but not in the
+ // cached_resources_map_ and it is referenced (e.g. when the StyleEngine
+ // processes a @font-face rule), the resource will be emulated via
+ // `EmulateLoadStartedForInspector` so that it shows up in DevTools.
+ // In order to ensure that this only occurs once per resource, we keep
+ // a weak reference to all emulated resources and only emulate resources
+ // that have not been previously emulated.
+ DocumentResourceMap emulated_load_started_for_inspector_resources_map_;
+
// document_resource_strong_refs_ keeps strong references for fonts, images,
// scripts and stylesheets within their freshness lifetime.
HeapHashSet<Member<Resource>> document_resource_strong_refs_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index ef0ff8fa688eb30f88dff855964ff6aabce70790..d32a89f8db9eeec03494271d2193e7200802710f 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -160,6 +160,8 @@ class ResourceFetcherTest : public testing::Test {
return request_;
}
+ void ClearLastRequest() { request_ = absl::nullopt; }
+
private:
absl::optional<PartialResourceRequest> request_;
};
@@ -1653,4 +1655,123 @@ TEST_F(ResourceFetcherTest, StrongReferenceThreshold) {
ASSERT_FALSE(perform_fetch.Run(KURL("http://127.0.0.1:8000/baz.png")));
}
+TEST_F(ResourceFetcherTest,
+ EmulateLoadStartedForInspectorOncePerResourceDisabled) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ features::kEmulateLoadStartedForInspectorOncePerResource);
+ auto* observer = MakeGarbageCollected<TestResourceLoadObserver>();
+
+ // Set up the initial fetcher and mark the resource as cached.
+ auto* fetcher = CreateFetcher();
+ KURL url("http://127.0.0.1:8000/foo.woff2");
+ RegisterMockedURLLoad(url);
+ FetchParameters fetch_params =
+ FetchParameters::CreateForTest(ResourceRequest(url));
+ Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
+ resource->SetStatus(ResourceStatus::kCached);
+
+ ASSERT_NE(fetcher->CachedResource(url), nullptr);
+ ASSERT_FALSE(fetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+
+ // Set up the second fetcher.
+ auto* otherContextFetcher = CreateFetcher();
+ otherContextFetcher->SetResourceLoadObserver(observer);
+
+ // Ensure that the url is initially not marked as cached or
+ // emulated and the observer's last request is empty.
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
+ ASSERT_FALSE(
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+ ASSERT_EQ(observer->GetLastRequest(), absl::nullopt);
+
+ otherContextFetcher->EmulateLoadStartedForInspector(
+ resource, url, mojom::blink::RequestContextType::FONT,
+ network::mojom::RequestDestination::kFont,
+ fetch_initiator_type_names::kCSS);
+
+ // After the first emulation, ensure that the url is not cached,
+ // is not marked as emulated and the observer's last
+ // request is not empty with the feature disabled.
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
+ ASSERT_FALSE(
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+ ASSERT_NE(observer->GetLastRequest(), absl::nullopt);
+
+ // Clear out the last request to start fresh
+ observer->ClearLastRequest();
+
+ otherContextFetcher->EmulateLoadStartedForInspector(
+ resource, url, mojom::blink::RequestContextType::FONT,
+ network::mojom::RequestDestination::kFont,
+ fetch_initiator_type_names::kCSS);
+
+ // After the second emulation, ensure that the url is not cached,
+ // the resource is not marked as emulated, and the observer's last
+ // request is not empty with the feature disabled. This means that
+ // the observer was notified with this emulation.
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
+ ASSERT_FALSE(
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+ ASSERT_NE(observer->GetLastRequest(), absl::nullopt);
+}
+
+TEST_F(ResourceFetcherTest,
+ EmulateLoadStartedForInspectorOncePerResourceEnabled) {
+ auto* observer = MakeGarbageCollected<TestResourceLoadObserver>();
+
+ // Set up the initial fetcher and mark the resource as cached.
+ auto* fetcher = CreateFetcher();
+ KURL url("http://127.0.0.1:8000/foo.woff2");
+ RegisterMockedURLLoad(url);
+ FetchParameters fetch_params =
+ FetchParameters::CreateForTest(ResourceRequest(url));
+ Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
+ resource->SetStatus(ResourceStatus::kCached);
+
+ ASSERT_NE(fetcher->CachedResource(url), nullptr);
+ ASSERT_FALSE(fetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+
+ // Set up the second fetcher.
+ auto* otherContextFetcher = CreateFetcher();
+ otherContextFetcher->SetResourceLoadObserver(observer);
+
+ // Ensure that the url is initially not cached, not marked as emulated,
+ // and the observer's last request is empty.
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
+ ASSERT_FALSE(
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+ ASSERT_EQ(observer->GetLastRequest(), absl::nullopt);
+
+ otherContextFetcher->EmulateLoadStartedForInspector(
+ resource, url, mojom::blink::RequestContextType::FONT,
+ network::mojom::RequestDestination::kFont,
+ fetch_initiator_type_names::kCSS);
+
+ // After the first emulation, ensure that the url is not cached,
+ // marked as emulated, and the observer's last request is not empty with
+ // the feature enabled.
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
+ ASSERT_TRUE(
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+ ASSERT_NE(observer->GetLastRequest(), absl::nullopt);
+
+ // Clear out the last request to start fresh
+ observer->ClearLastRequest();
+
+ otherContextFetcher->EmulateLoadStartedForInspector(
+ resource, url, mojom::blink::RequestContextType::FONT,
+ network::mojom::RequestDestination::kFont,
+ fetch_initiator_type_names::kCSS);
+
+ // After the first emulation, ensure that the url is not cached,
+ // marked as emulated, and the observer's last request is empty with
+ // the feature enabled. This means that the observer was not
+ // notified with this emulation.
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
+ ASSERT_TRUE(
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
+ ASSERT_EQ(observer->GetLastRequest(), absl::nullopt);
+}
+
} // namespace blink

View File

@@ -3,47 +3,89 @@ From: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
Date: Thu, 6 Oct 2022 18:30:53 +0200
Subject: fix: on-screen-keyboard hides on input blur in webview
Changes introduced by this patch fix issue where OSK does not hide on
input rendered inside webview is blurred. This patch should be removed
when proper fix in chromium repo is available.
Note: the issue still occurs if input rendered in webview blurred due
to touch outside of webview. It is caused by webview implementation
details. Specificaly due to webview has its own tree nodes and focused
node does not change in this case.
Work around OSK not hiding by notifying RenderWidgetHostViewAura of
focus node change via TextInputManager.
chromium-bug: https://crbug.com/1369605
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
index b190c86708d5ae7f207bae3e923609814bf68a52..16395c4b5fd5262885118095784db820508087dd 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -1041,6 +1041,12 @@ RenderWidgetHostViewChildFrame::DidUpdateVisualProperties(
return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index ee2b3bc3aabf7f5a8e3d2ad57675537f21aafaa6..52235e8022e6122fbf0293b1653b62ee9551e889 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2942,6 +2942,12 @@ void RenderWidgetHostViewAura::OnTextSelectionChanged(
}
}
+void RenderWidgetHostViewChildFrame::FocusedNodeChanged(
+ bool is_editable_node,
+ const gfx::Rect& node_bounds_in_screen) {
+ NOTREACHED();
+void RenderWidgetHostViewAura::OnFocusedInputElementChanged(
+ TextInputManager* text_input_manager,
+ RenderWidgetHostViewBase* view) {
+ FocusedNodeChanged(false, {});
+}
+
ui::TextInputType RenderWidgetHostViewChildFrame::GetTextInputType() const {
if (!text_input_manager_)
return ui::TEXT_INPUT_TYPE_NONE;
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h
index 648896b13ad4f811fdd196bd2fe5bdf62e7154ab..e2e3b414e73052b2b5b8e443ded18ae3f18fd916 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.h
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -184,6 +184,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void DisableAutoResize(const gfx::Size& new_size) override;
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
const cc::RenderFrameMetadata& metadata) override;
+ void FocusedNodeChanged(bool is_editable_node,
+ const gfx::Rect& node_bounds_in_screen) override;
void RenderWidgetHostViewAura::SetPopupChild(
RenderWidgetHostViewAura* popup_child_host_view) {
popup_child_host_view_ = popup_child_host_view;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index a50b68d69a80d05e154f0a49dfe0fd36e4a313ec..05334f6d53ccdd35e1262a16cbbbff8f67c3c500 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -628,6 +628,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
RenderWidgetHostViewBase* updated_view) override;
void OnTextSelectionChanged(TextInputManager* text_input_mangager,
RenderWidgetHostViewBase* updated_view) override;
+ void OnFocusedInputElementChanged(TextInputManager* text_input_manager,
+ RenderWidgetHostViewBase* view) override;
// RenderFrameMetadataProvider::Observer implementation.
void OnRenderFrameMetadataChangedBeforeActivation(
// Detaches |this| from the input method object.
// is_removed flag is true if this is called while the window is
diff --git a/content/browser/renderer_host/text_input_manager.cc b/content/browser/renderer_host/text_input_manager.cc
index 6c4403063fd5a57ea1d8ff3446ba74ea10090e5a..269830964194ca8fae6b3bd11d2955ab3e8ab782 100644
--- a/content/browser/renderer_host/text_input_manager.cc
+++ b/content/browser/renderer_host/text_input_manager.cc
@@ -167,6 +167,7 @@ void TextInputManager::UpdateTextInputState(
if (text_input_state.type == ui::TEXT_INPUT_TYPE_NONE &&
active_view_ != view) {
+ NotifyFocusedInputElementChanged(active_view_);
// We reached here because an IPC is received to reset the TextInputState
// for |view|. But |view| != |active_view_|, which suggests that at least
// one other view has become active and we have received the corresponding
@@ -453,6 +454,12 @@ void TextInputManager::NotifyObserversAboutInputStateUpdate(
observer.OnUpdateTextInputStateCalled(this, updated_view, did_update_state);
}
+void TextInputManager::NotifyFocusedInputElementChanged(
+ RenderWidgetHostViewBase* view) {
+ for (auto& observer : observer_list_)
+ observer.OnFocusedInputElementChanged(this, view);
+}
+
TextInputManager::SelectionRegion::SelectionRegion() = default;
TextInputManager::SelectionRegion::SelectionRegion(
diff --git a/content/browser/renderer_host/text_input_manager.h b/content/browser/renderer_host/text_input_manager.h
index 35d0355b0e181ecf38146a70559eb6070e83d6d6..47d37b5f7c9a62e1b7c91de5bd0d0d562795bc89 100644
--- a/content/browser/renderer_host/text_input_manager.h
+++ b/content/browser/renderer_host/text_input_manager.h
@@ -71,6 +71,10 @@ class CONTENT_EXPORT TextInputManager {
virtual void OnTextSelectionChanged(
TextInputManager* text_input_manager,
RenderWidgetHostViewBase* updated_view) {}
+ // Called when focused input element has changed
+ virtual void OnFocusedInputElementChanged(
+ TextInputManager* text_input_manager,
+ RenderWidgetHostViewBase* updated_view) {}
};
// Text selection bounds.
@@ -278,6 +282,7 @@ class CONTENT_EXPORT TextInputManager {
void NotifyObserversAboutInputStateUpdate(RenderWidgetHostViewBase* view,
bool did_update_state);
+ void NotifyFocusedInputElementChanged(RenderWidgetHostViewBase* view);
// The view with active text input state, i.e., a focused <input> element.
// It will be nullptr if no such view exists. Note that the active view
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index e2e7b3e5cf8f581adee596903fc19886a23832c1..dd060f4207516af6b7db21593dcbed3848d47409 100644
--- a/content/browser/web_contents/web_contents_impl.cc

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peng Huang <penghuang@chromium.org>
Date: Wed, 20 Mar 2024 16:22:16 +0000
Subject: Fix PaintImage deserialization arbitrary-read issue
(cherry picked from commit 47e8386c97ac7a84a96866fbd35422b99a01de5a)
Bug: 327183408
Change-Id: I09927fbae60b666aaa370e3aba01607cdb977a25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5370455
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1272930}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5382202
Auto-Submit: Peng Huang <penghuang@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/branch-heads/6261@{#1106}
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc
index 935dbb05a5021ffb80737e2f8e5497e887235946..6d920c33562de8d2bf11ae74101cf7ab1e929f5e 100644
--- a/cc/paint/paint_op_reader.cc
+++ b/cc/paint/paint_op_reader.cc
@@ -1532,9 +1532,10 @@ inline void PaintOpReader::DidRead(size_t bytes_read) {
// All data are aligned with PaintOpWriter::kDefaultAlignment at least.
size_t aligned_bytes =
base::bits::AlignUp(bytes_read, PaintOpWriter::kDefaultAlignment);
- memory_ += aligned_bytes;
DCHECK_LE(aligned_bytes, remaining_bytes_);
- remaining_bytes_ -= aligned_bytes;
+ bytes_read = std::min(aligned_bytes, remaining_bytes_);
+ memory_ += bytes_read;
+ remaining_bytes_ -= bytes_read;
}
} // namespace cc

View File

@@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@chromium.org>
Date: Thu, 1 Feb 2024 21:24:43 +0000
Subject: Fix racy iterator use in Node::AddConnection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Before this fix an iterator to `connections_` which requires a lock
would be dereferenced outside an unlock operation because the `it` taken
from the map isn't understood as guarded by the same lock.
This takes a Ref<NodeLink> before unlocking which'll keep the link
reference alive even if `connections_` is concurrently modified and the
entry removed (or replaced).
(cherry picked from commit 1f2cbf5833d7f00d3fcbfd1f3ef0c1aff10c04cd)
Bug: 1523704
Change-Id: I6f6fe4e34ec2c8268d4e7f33965a13e3b10f9f92
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5254025
Commit-Queue: Peter Boström <pbos@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Commit-Queue: Ken Rockot <rockot@google.com>
Auto-Submit: Peter Boström <pbos@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1254709}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5260163
Cr-Commit-Position: refs/branch-heads/6099@{#1916}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/ipcz/src/ipcz/node.cc b/third_party/ipcz/src/ipcz/node.cc
index a7162f9017d86d3ab3369d04add98527189dd33f..3a8eef652cc3381b608d89cfb6acd006d4ba378b 100644
--- a/third_party/ipcz/src/ipcz/node.cc
+++ b/third_party/ipcz/src/ipcz/node.cc
@@ -168,9 +168,10 @@ bool Node::AddConnection(const NodeName& remote_node_name,
// handling an incoming NodeConnector message, we can err on the side of
// caution (i.e. less re-entrancy in event handlers) by treating every
// case like an API call.
+ const Ref<NodeLink> link = it->second.link;
mutex_.Unlock();
const OperationContext context{OperationContext::kAPICall};
- DropConnection(context, *it->second.link);
+ DropConnection(context, *link);
mutex_.Lock();
}

View File

@@ -0,0 +1,87 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Tue, 30 Jan 2024 21:36:01 +0000
Subject: ipcz: Fix a few weak asserts
DriverMemory cloning should not weakly assert success, as it can fail in
real production scenarios. Now Clone() will return an invalid
DriverMemory object if it fails to duplicate the internal handle.
Existing callers of Clone() are already durable to an invalid output, so
this change results in graceful failures instead of undefined behavior.
This also replaces some weak asserts in DriverTransport creation with
hardening asserts. We may want to fail more gracefully if these end
up crashing a lot, but it seems unlikely.
(cherry picked from commit 4bd18c5a3a7a935716bbed197fba6d45a1122894)
Fixed: 1521571
Change-Id: Id764b33ead8bbba58e61b3270920c839479eaa4a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5240312
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1252882}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5250958
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/branch-heads/6099@{#1905}
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
diff --git a/third_party/ipcz/src/ipcz/driver_memory.cc b/third_party/ipcz/src/ipcz/driver_memory.cc
index f8761985b78409fdb5420456661b0d227030cc8f..3bdc3aaf52d166a7691b5f28ebc86cc47600f7cc 100644
--- a/third_party/ipcz/src/ipcz/driver_memory.cc
+++ b/third_party/ipcz/src/ipcz/driver_memory.cc
@@ -30,10 +30,11 @@ DriverMemory::DriverMemory(const IpczDriver& driver, size_t num_bytes)
: size_(num_bytes) {
ABSL_ASSERT(num_bytes > 0);
IpczDriverHandle handle;
- IpczResult result =
+ const IpczResult result =
driver.AllocateSharedMemory(num_bytes, IPCZ_NO_FLAGS, nullptr, &handle);
- ABSL_ASSERT(result == IPCZ_RESULT_OK);
- memory_ = DriverObject(driver, handle);
+ if (result == IPCZ_RESULT_OK) {
+ memory_ = DriverObject(driver, handle);
+ }
}
DriverMemory::DriverMemory(DriverMemory&& other) = default;
@@ -43,12 +44,14 @@ DriverMemory& DriverMemory::operator=(DriverMemory&& other) = default;
DriverMemory::~DriverMemory() = default;
DriverMemory DriverMemory::Clone() {
- ABSL_ASSERT(is_valid());
+ ABSL_HARDENING_ASSERT(is_valid());
IpczDriverHandle handle;
- IpczResult result = memory_.driver()->DuplicateSharedMemory(
+ const IpczResult result = memory_.driver()->DuplicateSharedMemory(
memory_.handle(), 0, nullptr, &handle);
- ABSL_ASSERT(result == IPCZ_RESULT_OK);
+ if (result != IPCZ_RESULT_OK) {
+ return DriverMemory();
+ }
return DriverMemory(DriverObject(*memory_.driver(), handle));
}
diff --git a/third_party/ipcz/src/ipcz/driver_transport.cc b/third_party/ipcz/src/ipcz/driver_transport.cc
index 096f1b3bed3cfbe0074b074edba21bcfceacd897..dbeb69a0a881a82c9360118a017942ec6eb920f8 100644
--- a/third_party/ipcz/src/ipcz/driver_transport.cc
+++ b/third_party/ipcz/src/ipcz/driver_transport.cc
@@ -68,14 +68,14 @@ DriverTransport::Pair DriverTransport::CreatePair(
IpczDriverHandle target_transport0 = IPCZ_INVALID_DRIVER_HANDLE;
IpczDriverHandle target_transport1 = IPCZ_INVALID_DRIVER_HANDLE;
if (transport0) {
- ABSL_ASSERT(transport1);
+ ABSL_HARDENING_ASSERT(transport1);
target_transport0 = transport0->driver_object().handle();
target_transport1 = transport1->driver_object().handle();
}
IpczResult result = driver.CreateTransports(
target_transport0, target_transport1, IPCZ_NO_FLAGS, nullptr,
&new_transport0, &new_transport1);
- ABSL_ASSERT(result == IPCZ_RESULT_OK);
+ ABSL_HARDENING_ASSERT(result == IPCZ_RESULT_OK);
auto first =
MakeRefCounted<DriverTransport>(DriverObject(driver, new_transport0));
auto second =

View File

@@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joey Arhar <jarhar@chromium.org>
Date: Wed, 21 Feb 2024 21:06:46 +0000
Subject: M122: cherry pick CVE-2024-25062 libxml fix
This patch cherry picks the CVE-2024-25062 fix from libxml:
https://gitlab.gnome.org/GNOME/libxml2/-/commit/1a66b176055d25ee635bf328c7b35b381db0b71d
Bug: 325094430
Change-Id: I526ee718269ed8700b90885630b67f00f2f95089
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5310037
Auto-Submit: Joey Arhar <jarhar@chromium.org>
Commit-Queue: David Baron <dbaron@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/branch-heads/6261@{#913}
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium
index f3e311972eb41e768c905a451ef576706434eeec..17ffbdf2734a788ffbaab9df50fda68b56e91c53 100644
--- a/third_party/libxml/README.chromium
+++ b/third_party/libxml/README.chromium
@@ -36,5 +36,6 @@ Modifications:
- LIBXML_XINCLUDE_ENABLED
- LIBXML_XPTR_ENABLED
- LIBXML_ZLIB_ENABLED
+- Cherry picked fix for CVE-2024-25062
This import was generated by the chromium/roll.py script.
diff --git a/third_party/libxml/src/xmlreader.c b/third_party/libxml/src/xmlreader.c
index 71f2f933cc3b5a1064637036aed09459f2d1ce89..82cc186ea829ea60582ea0f7056125bc3ff310f3 100644
--- a/third_party/libxml/src/xmlreader.c
+++ b/third_party/libxml/src/xmlreader.c
@@ -1445,6 +1445,7 @@ node_found:
* Handle XInclude if asked for
*/
if ((reader->xinclude) && (reader->in_xinclude == 0) &&
+ (reader->state != XML_TEXTREADER_BACKTRACK) &&
(reader->node != NULL) &&
(reader->node->type == XML_ELEMENT_NODE) &&
(reader->node->ns != NULL) &&

View File

@@ -0,0 +1,82 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Mon, 25 Mar 2024 19:28:44 +0000
Subject: webcodecs: Disable async VideoFrame readback to mitigate a race
(cherry picked from commit fdc363eb7a1c1c194a02a4cb340534b1501b0f95)
Bug: 330575496
Change-Id: I187a113528da9d1c4316186e3dd24f91dbfd818b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5386784
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1277172}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5391828
Reviewed-by: Eugene Zemtsov <eugene@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Xiaohan Wang <xhwang@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/branch-heads/6261@{#1124}
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
diff --git a/content/test/data/gpu/webcodecs/copyTo.html b/content/test/data/gpu/webcodecs/copyTo.html
index 628b891ecc5eb675d426c83a5ad235839ed7d6c1..0931feefa628af2060cd927666879a3e72ba2959 100644
--- a/content/test/data/gpu/webcodecs/copyTo.html
+++ b/content/test/data/gpu/webcodecs/copyTo.html
@@ -118,6 +118,16 @@ Take frames coming from various sources and read them using copyTo().
let frame = await source.getNextFrame();
let size = frame.allocationSize();
+ // Readback a whole frame to a regular buffer detach it
+ {
+ let buf = new ArrayBuffer(size);
+ TEST.assert(readWholeBuffer(buf) == 0, "Buffer should be zero");
+ let copy_promise = frame.copyTo(buf);
+ buf.transfer(1);
+ let layout = await copy_promise;
+ TEST.assert(layout, "layout is empty / ArrayBuffer");
+ }
+
// Readback a whole frame to a regular buffer and send it to a worker
{
let {worker, worker_promise } = makeWorker();
@@ -158,4 +168,5 @@ Take frames coming from various sources and read them using copyTo().
TEST.log('Test completed');
}
addManualTestButton([{'source_type': 'offscreen'}]);
-</script>
\ No newline at end of file
+ addManualTestButton([{'source_type': 'arraybuffer'}]);
+</script>
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
index 365b18025d5a88af4910bdc4e544210c355c4105..eb7a2c50118f6515b2984c7f0a9fadabd9a5f16e 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -79,6 +79,11 @@ namespace blink {
namespace {
+// Controls if VideoFrame.copyTo() reads GPU frames asynchronously
+BASE_FEATURE(kVideoFrameAsyncCopyTo,
+ "VideoFrameAsyncCopyTo",
+ base::FEATURE_DISABLED_BY_DEFAULT);
+
media::VideoPixelFormat ToMediaPixelFormat(V8VideoPixelFormat::Enum fmt) {
switch (fmt) {
case V8VideoPixelFormat::Enum::kI420:
@@ -1131,9 +1136,11 @@ ScriptPromise VideoFrame::copyTo(ScriptState* script_state,
} else {
DCHECK(local_frame->HasTextures());
- if (auto* resolver = CopyToAsync(script_state, local_frame, src_rect,
- destination, dest_layout)) {
- return resolver->Promise();
+ if (base::FeatureList::IsEnabled(kVideoFrameAsyncCopyTo)) {
+ if (auto* resolver = CopyToAsync(script_state, local_frame, src_rect,
+ destination, dest_layout)) {
+ return resolver->Promise();
+ }
}
if (!CopyTexturablePlanes(*local_frame, src_rect, dest_layout, buffer)) {

View File

@@ -0,0 +1,156 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Thu, 15 Feb 2024 20:30:22 +0000
Subject: Prevent MojoTrap event re-ordering
(cherry picked from commit 3557a2fcbdd8167f97ca81171be2e0da9c4f0647)
Fixed: 1508753
Change-Id: I9ec14a12e7d1d147bda63703e1d6619fa30c8a51
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5253039
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1254840}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5299857
Reviewed-by: Oksana Zhuravlova <oksamyt@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
Cr-Commit-Position: refs/branch-heads/6261@{#794}
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
diff --git a/mojo/core/ipcz_driver/mojo_trap.cc b/mojo/core/ipcz_driver/mojo_trap.cc
index 7a5765a74a7f64e584b0a080e659c88c019adcbb..2c98335dd7846fe44fd048265078dfffcb0b63f6 100644
--- a/mojo/core/ipcz_driver/mojo_trap.cc
+++ b/mojo/core/ipcz_driver/mojo_trap.cc
@@ -544,7 +544,15 @@ void MojoTrap::DispatchOrQueueEvent(Trigger& trigger,
}
dispatching_thread_ = base::PlatformThread::CurrentRef();
- DispatchEvent(event);
+
+ // If `trigger.removed` is true, then either this is the cancellation event
+ // for the trigger (in which case it's OK to dispatch), or it was cancelled on
+ // some other thread while we were blocked above. In the latter case, this
+ // event is no longer valid and cannot be dispatched.
+ // See https://crbug.com/1508753.
+ if (!trigger.removed || event.result == MOJO_RESULT_CANCELLED) {
+ DispatchEvent(event);
+ }
// NOTE: This vector is only shrunk by the clear() below, but it may
// accumulate more events during each iteration. Hence we iterate by index.
diff --git a/mojo/core/trap_unittest.cc b/mojo/core/trap_unittest.cc
index 0fd449d9598810fd34372d69d1d1599a0c88b955..4058da72eef8b5a11432b9a17d6ff3ecfd1306e8 100644
--- a/mojo/core/trap_unittest.cc
+++ b/mojo/core/trap_unittest.cc
@@ -1747,6 +1747,111 @@ TEST_F(TrapTest, TriggerDuringDestruction) {
MojoClose(b);
}
+TEST_F(TrapTest, RaceDispatchAndBlockedCancel) {
+ // Regression test for https://crbug.com/1508753. This bug was caused by
+ // reordering of a MOJO_RESULT_CANCELLED event to before some other event for
+ // the same trap context, violating an API constraint that must be upheld for
+ // memory safety in application code. The scenario which could elicit the bug
+ // was as follows:
+ //
+ // 1. A single trap is watching two pipes, P and Q.
+ // 2. Thread A closes pipe P, triggering a CANCELLED event.
+ // 3. Thread A re-arms the trap from within the CANCELLED event handler.
+ // 4. Thread B changes Q's state to elicit a event for Q (not CANCELLED).
+ // 5. Thread B dispatch is blocked because thread A is still dispatching.
+ // 6. Before thread B gets a chance to be scheduled, thread A closes Q.
+ // 7. Thread A dispatches a CANCELLED event for Q.
+ // 8. Thread B is scheduled and proceeds to dispatch its Q event. [BAD]
+
+ struct State;
+
+ struct Pipe {
+ explicit Pipe(State* state) : state(state) { CreateMessagePipe(&a, &b); }
+
+ uintptr_t context() const { return reinterpret_cast<uintptr_t>(this); }
+
+ MojoHandle a;
+ MojoHandle b;
+ bool trigger_cancelled = false;
+
+ // Back-reference to common state so it's reachable from the event handler.
+ const raw_ptr<State> state;
+ };
+
+ struct State {
+ Pipe pipe0{this};
+ Pipe pipe1{this};
+ MojoHandle trap;
+ base::WaitableEvent event;
+ };
+ State state;
+
+ // NOTE: + to turn the lambda into a function pointer.
+ const MojoTrapEventHandler event_handler = +[](const MojoTrapEvent* event) {
+ auto& pipe = *reinterpret_cast<Pipe*>(event->trigger_context);
+ auto& state = *pipe.state;
+
+ // If the bug is present, this expectation can fail flakily. No event should
+ // fire for a pipe after its watch has been cancelled.
+ EXPECT_FALSE(pipe.trigger_cancelled);
+
+ if (event->result == MOJO_RESULT_CANCELLED) {
+ pipe.trigger_cancelled = true;
+
+ if (&pipe == &state.pipe0) {
+ // When pipe0's watch is cancelled (on the main thread by closure down
+ // below) we re-arm the trap immediately. This must succeed because
+ // `pipe1.a` is now the only handle being watched, and it's still in an
+ // uninteresting state.
+ EXPECT_EQ(MOJO_RESULT_OK,
+ MojoArmTrap(state.trap, nullptr, nullptr, nullptr));
+
+ // Unblock the other thread so it can elicit a trap event on pipe1 now
+ // that the trap is re-armed. It will still block just before
+ // dispatching as long as we're still in this event handler on the main
+ // thread.
+ state.event.Signal();
+
+ // A nice long delay to make it very likely for the waiting
+ // ThreadedRunner to progress right up to its event dispatch.
+ base::PlatformThread::Sleep(base::Milliseconds(10));
+
+ // Trigger cancellation for pipe1 by closing its `a`. This will queue a
+ // CANCELLED event to fire on the same thread immediately after we
+ // return from this handler.
+ MojoClose(state.pipe1.a);
+ }
+ }
+ };
+
+ EXPECT_EQ(MOJO_RESULT_OK,
+ MojoCreateTrap(event_handler, nullptr, &state.trap));
+ EXPECT_EQ(
+ MOJO_RESULT_OK,
+ MojoAddTrigger(state.trap, state.pipe0.a, MOJO_HANDLE_SIGNAL_READABLE,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ state.pipe0.context(), nullptr));
+ EXPECT_EQ(
+ MOJO_RESULT_OK,
+ MojoAddTrigger(state.trap, state.pipe1.a, MOJO_HANDLE_SIGNAL_READABLE,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ state.pipe1.context(), nullptr));
+ EXPECT_EQ(MOJO_RESULT_OK, MojoArmTrap(state.trap, nullptr, nullptr, nullptr));
+
+ ThreadedRunner close_pipe1_b(base::BindLambdaForTesting([&] {
+ state.event.Wait();
+ MojoClose(state.pipe1.b);
+ }));
+ close_pipe1_b.Start();
+
+ // Trigger cancellation of the watch on `pipe0.a`. See event_handler above.
+ MojoClose(state.pipe0.a);
+
+ close_pipe1_b.Join();
+ MojoClose(state.pipe0.b);
+ MojoClose(state.trap);
+}
+
base::RepeatingClosure g_do_random_thing_callback;
void ReadAllMessages(const MojoTrapEvent* event) {

View File

@@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rebekah Potter <rbpotter@chromium.org>
Date: Fri, 15 Dec 2023 19:23:42 +0000
Subject: Reland mojom_ts_generator: Handle empty module path identically to
'/'
Reason for revert: Original change was reverted incorrectly.
Original change's description:
> Revert "mojom_ts_generator: Handle empty module path identically to '/'"
>
> This reverts commit 4d1f1115f0f70c7ff4493f64221fdf15810c5005.
>
> Reason for revert: The tree is down https://ci.chromium.org/ui/p/chromium/builders/ci/Linux%20Chromium%20OS%20ASan%20LSan%20Builder/82276/overview
>
> Original change's description:
> > mojom_ts_generator: Handle empty module path identically to '/'
> >
> > Fixes an issue with Python 3.11.2. Workaround originally proposed at
> > https://bugs.chromium.org/p/chromium/issues/detail?id=1422178#c4
> >
> > Bug: 1422178
> > Change-Id: I4f02cbd4a0aafbab1a7fef8a36d812f1621c75e4
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5121571
> > Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org>
> > Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#1237792}
>
> Bug: 1422178
> Change-Id: Icb352e5b437deee34100d213bd9c1bc0cedaaaf4
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5124992
> Owners-Override: Shibalik Mohapatra <shibalik@chromium.org>
> Commit-Queue: Shibalik Mohapatra <shibalik@chromium.org>
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Cr-Commit-Position: refs/heads/main@{#1237835}
Bug: 1422178
Change-Id: I2486fca59de0b28efc38020de8cd3d01a56eca98
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5125915
Commit-Queue: Demetrios Papadopoulos <dpapad@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#1238190}
diff --git a/mojo/public/tools/bindings/generators/mojom_ts_generator.py b/mojo/public/tools/bindings/generators/mojom_ts_generator.py
index d8e0cf30486690b5aa33906985642dc8f7f762f5..1c43796152811d020370aa0a42bc4fddf8b05c06 100644
--- a/mojo/public/tools/bindings/generators/mojom_ts_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_ts_generator.py
@@ -175,8 +175,10 @@ def _GetWebUiModulePath(module):
path. Otherwise, returned paths always end in a '/' and begin with either
`chrome://resources/` or a '/'."""
path = module.metadata.get('webui_module_path')
- if path is None or path == '/':
- return path
+ if path is None:
+ return None
+ if path == '' or path == '/':
+ return '/'
if _IsAbsoluteChromeResourcesPath(path):
return path.rstrip('/') + '/'
return '/{}/'.format(path.strip('/'))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bo Liu <boliu@chromium.org>
Date: Mon, 4 Dec 2023 15:01:22 +0000
Subject: Safely crash on dangling profile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bug: 1407197
Change-Id: Idcafd8f0ba2f980d06338e573489a3456e3823c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5080603
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
Commit-Queue: Bo Liu <boliu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1232704}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 0ecc7989e7bfa459c80b4fe10705781257dd9b7d..a0293f73810e2077ca53d691d3be3dbbda12faca 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -252,6 +252,11 @@ BASE_FEATURE(kBackNavigationPredictionMetrics,
"BackNavigationPredictionMetrics",
base::FEATURE_ENABLED_BY_DEFAULT);
+// Kill switch for crash immediately on dangling BrowserContext.
+BASE_FEATURE(kCrashOnDanglingBrowserContext,
+ "CrashOnDanglingBrowserContext",
+ base::FEATURE_ENABLED_BY_DEFAULT);
+
using LifecycleState = RenderFrameHost::LifecycleState;
using LifecycleStateImpl = RenderFrameHostImpl::LifecycleStateImpl;
@@ -970,11 +975,18 @@ class WebContentsOfBrowserContext : public base::SupportsUserData::Data {
env, web_contents_with_dangling_ptr_to_browser_context);
#endif // BUILDFLAG(IS_ANDROID)
- NOTREACHED()
- << "BrowserContext is getting destroyed without first closing all "
- << "WebContents (for more info see https://crbug.com/1376879#c44); "
- << "creator = " << creator;
- base::debug::DumpWithoutCrashing();
+ if (base::FeatureList::IsEnabled(kCrashOnDanglingBrowserContext)) {
+ LOG(FATAL)
+ << "BrowserContext is getting destroyed without first closing all "
+ << "WebContents (for more info see https://crbug.com/1376879#c44); "
+ << "creator = " << creator;
+ } else {
+ NOTREACHED()
+ << "BrowserContext is getting destroyed without first closing all "
+ << "WebContents (for more info see https://crbug.com/1376879#c44); "
+ << "creator = " << creator;
+ base::debug::DumpWithoutCrashing();
+ }
}
}

View File

@@ -0,0 +1,76 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joshua Peraza <jperaza@chromium.org>
Date: Tue, 5 Mar 2024 18:09:48 +0000
Subject: Update Crashpad to 37afd37401253ebcebcf6e07ce15c8cfecb1a1cc
29ac83caeb94 [Fuchsia] remove use of fuchsia mac sdk
37afd3740125 Properly update iterator
(cherry picked from commit 80b0e498bec1722e8cc310fe52698e7b690956f2)
Bug: 325296797
Change-Id: I7eb39d1bccec802f1b043eebd20ec0e658fe0e04
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5311633
Reviewed-by: Nico Weber <thakis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1264232}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5335538
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Cr-Commit-Position: refs/branch-heads/6261@{#1024}
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 9edcee3aa81a84cd38bba2660557dfc6f48e380c..bafe29b422506207a11a22f6793c38d6c5fa5a5f 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -1,8 +1,8 @@
Name: Crashpad
Short Name: crashpad
URL: https://crashpad.chromium.org/
-Version: unknown
-Revision: a7cfe95351e301512eb0efc03f92fee63c1c82b2
+Version: N/A
+Revision: 37afd37401253ebcebcf6e07ce15c8cfecb1a1cc
License: Apache 2.0
License File: crashpad/LICENSE
Security Critical: yes
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
index b7d44b11c3f8eb8275971eb29c5bcca313f70179..f6f7a31963245b47724eb75584033e68c90a90d6 100644
--- a/third_party/crashpad/crashpad/DEPS
+++ b/third_party/crashpad/crashpad/DEPS
@@ -121,16 +121,6 @@ deps = {
'0d6902558d92fe3d49ba9a8f638ddea829be595b',
'condition': 'checkout_fuchsia',
},
- 'crashpad/third_party/fuchsia/sdk/mac-amd64': {
- 'packages': [
- {
- 'package': 'fuchsia/sdk/core/mac-amd64',
- 'version': 'latest'
- },
- ],
- 'condition': 'checkout_fuchsia and host_os == "mac"',
- 'dep_type': 'cipd'
- },
'crashpad/third_party/fuchsia/sdk/linux-amd64': {
'packages': [
{
diff --git a/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc b/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
index 192b4cb10add6e3aaa70b96b86bc8ae90b90a070..476ebe019eee87d76a8bceaa885dc58f01c6af62 100644
--- a/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
+++ b/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
@@ -97,9 +97,11 @@ ModuleSnapshotSanitized::AnnotationsSimpleMap() const {
std::map<std::string, std::string> annotations =
snapshot_->AnnotationsSimpleMap();
if (allowed_annotations_) {
- for (auto kv = annotations.begin(); kv != annotations.end(); ++kv) {
- if (!KeyIsAllowed(kv->first, *allowed_annotations_)) {
- annotations.erase(kv);
+ for (auto kv = annotations.begin(); kv != annotations.end();) {
+ if (KeyIsAllowed(kv->first, *allowed_annotations_)) {
+ ++kv;
+ } else {
+ kv = annotations.erase(kv);
}
}
}

View File

@@ -1,25 +1,19 @@
{
"src/electron/patches/chromium": "src",
"src/electron/patches/boringssl": "src/third_party/boringssl/src",
"src/electron/patches/devtools_frontend": "src/third_party/devtools-frontend/src",
"src/electron/patches/ffmpeg": "src/third_party/ffmpeg",
"src/electron/patches/v8": "src/v8",
"src/electron/patches/node": "src/third_party/electron_node",
"src/electron/patches/nan": "src/third_party/nan",
"src/electron/patches/perfetto": "src/third_party/perfetto",
"src/electron/patches/squirrel.mac": "src/third_party/squirrel.mac",
"src/electron/patches/Mantle": "src/third_party/squirrel.mac/vendor/Mantle",
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"src/electron/patches/webrtc": "src/third_party/webrtc"
}
[
{ "patch_dir": "src/electron/patches/chromium", "repo": "src" },
{ "patch_dir": "src/electron/patches/boringssl", "repo": "src/third_party/boringssl/src" },
{ "patch_dir": "src/electron/patches/devtools_frontend", "repo": "src/third_party/devtools-frontend/src" },
{ "patch_dir": "src/electron/patches/ffmpeg", "repo": "src/third_party/ffmpeg" },
{ "patch_dir": "src/electron/patches/v8", "repo": "src/v8" },
{ "patch_dir": "src/electron/patches/node", "repo": "src/third_party/electron_node" },
{ "patch_dir": "src/electron/patches/nan", "repo": "src/third_party/nan" },
{ "patch_dir": "src/electron/patches/perfetto", "repo": "src/third_party/perfetto" },
{ "patch_dir": "src/electron/patches/squirrel.mac", "repo": "src/third_party/squirrel.mac" },
{ "patch_dir": "src/electron/patches/Mantle", "repo": "src/third_party/squirrel.mac/vendor/Mantle" },
{ "patch_dir": "src/electron/patches/ReactiveObjC", "repo": "src/third_party/squirrel.mac/vendor/ReactiveObjC" },
{ "patch_dir": "src/electron/patches/webrtc", "repo": "src/third_party/webrtc" },
{ "patch_dir": "src/electron/patches/libavif", "repo": "src/third_party/libavif/src" },
{ "patch_dir": "src/electron/patches/angle", "repo": "src/third_party/angle" },
{ "patch_dir": "src/electron/patches/sqlite", "repo": "src/third_party/sqlite/src" },
{ "patch_dir": "src/electron/patches/libvpx", "repo": "src/third_party/libvpx/source/libvpx" },
{ "patch_dir": "src/electron/patches/DirectXShaderCompiler", "repo": "src/third_party/dawn/third_party/dxc" }
]

View File

@@ -1 +1,2 @@
fix_expose_globals_to_allow_patching_devtools_dock.patch
fix_active_trace_index_when_updating_models.patch

View File

@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 13 Dec 2023 19:14:56 +0900
Subject: fix: active trace index when updating models
https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4660282 introduced
an index variant for tracking current active trace. When trace recording finishes
TimelinePanel.loadingComplete will update the active index via TimelinePanel.setModel,
however it also installs an event listener for resolving names from the PerformanceModel
which eventually calls TimelinePanel.updateModelAndFlameChart and this function updated
the models current active trace to default index of -1 leading to broken save functionality.
The issue got addressed in M119 and higher via https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4871439
in an unrelated feature CL.
This patch isolates the change required to address the save functionality and is only needed for M118 branch.
diff --git a/front_end/panels/timeline/TimelinePanel.ts b/front_end/panels/timeline/TimelinePanel.ts
index c10c4d02c716f68b8c6cdcb422bc7fb21a67d923..d5343b73605239b0948fae19570a9a6a8965a89f 100644
--- a/front_end/panels/timeline/TimelinePanel.ts
+++ b/front_end/panels/timeline/TimelinePanel.ts
@@ -1256,7 +1256,7 @@ export class TimelinePanel extends UI.Panel.Panel implements Client, TimelineMod
if (!this.performanceModel) {
return;
}
- this.setModel(this.performanceModel);
+ this.setModel(this.performanceModel, null, this.#traceEngineActiveTraceIndex);
this.flameChart.updateColorMapper();
}

1
patches/dxc/.patches Normal file
View File

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

1
patches/libavif/.patches Normal file
View File

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

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vignesh Venkatasubramanian <vigneshv@google.com>
Date: Tue, 28 Nov 2023 08:44:22 -0800
Subject: Do not store colorproperties until alpha item is found
colorProperties could be pointing to a dangling pointer if
findAlphaItem() resizes the meta.items array.
Manual cherry-pick of PR #1808 into the chromium-m118 branch.
diff --git a/src/read.c b/src/read.c
index e3bad9833d665cdf704726ff47fd3b0ad3e8b02a..cf9f2a797c4b996f5b9877774e7848f3006dec54 100644
--- a/src/read.c
+++ b/src/read.c
@@ -3938,7 +3938,6 @@ avifResult avifDecoderReset(avifDecoder * decoder)
avifDiagnosticsPrintf(&decoder->diag, "Primary item not found");
return AVIF_RESULT_MISSING_IMAGE_ITEM;
}
- colorProperties = &colorItem->properties;
if (!memcmp(colorItem->type, "grid", 4)) {
avifROData readData;
AVIF_CHECKRES(avifDecoderItemRead(colorItem, decoder->io, &readData, 0, 0, data->diag));
@@ -3995,6 +3994,8 @@ avifResult avifDecoderReset(avifDecoder * decoder)
}
}
+ colorProperties = &colorItem->properties;
+
// Find Exif and/or XMP metadata, if any
AVIF_CHECKRES(avifDecoderFindMetadata(decoder, data->meta, decoder->image, colorItem->id));

View File

@@ -0,0 +1,2 @@
fix_to_buffer_alloc_for_vp9_bitstream_worker_data.patch
vp9_fix_to_integer_overflow_test.patch

View File

@@ -0,0 +1,68 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marco Paniconi <marpan@google.com>
Date: Wed, 13 Mar 2024 10:58:17 -0700
Subject: Fix to buffer alloc for vp9_bitstream_worker_data
The code was using the bitstream_worker_data when it
wasn't allocated for big enough size. This is because
the existing condition was to only re-alloc the
bitstream_worker_data when current dest_size was larger
than the current frame_size. But under resolution change
where frame_size is increased, beyond the current dest_size,
we need to allow re-alloc to the new size.
The existing condition to re-alloc when dest_size is
larger than frame_size (which is not required) is kept
for now.
Also increase the dest_size to account for image format.
Added tests, for both ROW_MT=0 and 1, that reproduce
the failures in the bugs below.
Note: this issue only affects the REALTIME encoding path.
Bug: b/329088759, b/329674887, b/329179808
Change-Id: Icd65dbc5317120304d803f648d4bd9405710db6f
(cherry picked from commit c29e63728316486082dd6083c2062434b441b77d)
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index ca56d14aa1e31e4791f8772316e449b771aae4fc..88a031e5fc1cf7b6cf0a441664dbbc62006c1790 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -962,6 +962,14 @@ void vp9_bitstream_encode_tiles_buffer_dealloc(VP9_COMP *const cpi) {
}
}
+static int encode_tiles_buffer_alloc_size(VP9_COMP *const cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+ const int image_bps =
+ (8 + 2 * (8 >> (cm->subsampling_x + cm->subsampling_y))) *
+ (1 + (cm->bit_depth > 8));
+ return cpi->oxcf.width * cpi->oxcf.height * image_bps / 8;
+}
+
static void encode_tiles_buffer_alloc(VP9_COMP *const cpi) {
VP9_COMMON *const cm = &cpi->common;
int i;
@@ -972,7 +980,7 @@ static void encode_tiles_buffer_alloc(VP9_COMP *const cpi) {
memset(cpi->vp9_bitstream_worker_data, 0, worker_data_size);
for (i = 1; i < cpi->num_workers; ++i) {
cpi->vp9_bitstream_worker_data[i].dest_size =
- cpi->oxcf.width * cpi->oxcf.height;
+ encode_tiles_buffer_alloc_size(cpi);
CHECK_MEM_ERROR(&cm->error, cpi->vp9_bitstream_worker_data[i].dest,
vpx_malloc(cpi->vp9_bitstream_worker_data[i].dest_size));
}
@@ -987,8 +995,8 @@ static size_t encode_tiles_mt(VP9_COMP *cpi, uint8_t *data_ptr) {
int tile_col = 0;
if (!cpi->vp9_bitstream_worker_data ||
- cpi->vp9_bitstream_worker_data[1].dest_size >
- (cpi->oxcf.width * cpi->oxcf.height)) {
+ cpi->vp9_bitstream_worker_data[1].dest_size !=
+ encode_tiles_buffer_alloc_size(cpi)) {
vp9_bitstream_encode_tiles_buffer_dealloc(cpi);
encode_tiles_buffer_alloc(cpi);
}

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marco Paniconi <marpan@google.com>
Date: Sat, 16 Mar 2024 10:39:28 -0700
Subject: vp9: fix to integer overflow test
failure for the 16k test: issue introduced
in: c29e637283
Bug: b/329088759, b/329674887, b/329179808
Change-Id: I88e8a36b7f13223997c3006c84aec9cfa48c0bcf
(cherry picked from commit 19832b1702d5b0adf616a0e080abd5207c8445b5)
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 88a031e5fc1cf7b6cf0a441664dbbc62006c1790..d3c029da4bacafdb19aa6bfb9865ccbf2db33393 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -967,7 +967,9 @@ static int encode_tiles_buffer_alloc_size(VP9_COMP *const cpi) {
const int image_bps =
(8 + 2 * (8 >> (cm->subsampling_x + cm->subsampling_y))) *
(1 + (cm->bit_depth > 8));
- return cpi->oxcf.width * cpi->oxcf.height * image_bps / 8;
+ const int64_t size =
+ (int64_t)cpi->oxcf.width * cpi->oxcf.height * image_bps / 8;
+ return (int)size;
}
static void encode_tiles_buffer_alloc(VP9_COMP *const cpi) {

View File

@@ -1,5 +1,3 @@
refactor_alter_child_process_fork_to_use_execute_script_with.patch
feat_initialize_asar_support.patch
expose_get_builtin_module_function.patch
build_add_gn_build_files.patch
fix_add_default_values_for_variables_in_common_gypi.patch
@@ -50,3 +48,4 @@ lib_fix_broadcastchannel_initialization_location.patch
fix_handle_possible_disabled_sharedarraybuffer.patch
win_process_avoid_assert_after_spawning_store_app_4152.patch
fix_avx_detection.patch
src_preload_function_for_environment.patch

View File

@@ -26,10 +26,10 @@ index 001343b74ce236f89dca030c0fc9dd0299df0b39..6f277daf4ce846f093f634c473daec07
try {
resolvedArgv = Module._resolveFilename(process.argv[1], null, false);
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 2e35cbba2ac02494c44821af395fe0195b1ab6b5..f5b6fecf6843a6204ec532a77f39a36d33bf061d 100644
index 250a43c5455b4f9ff72dd3a34d5b0aa270f43cc6..31f5d1528c840a2926b59b2b1c82ff265588a37a 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -149,11 +149,13 @@ function patchProcessObject(expandArgv1) {
@@ -144,11 +144,13 @@ function patchProcessObject(expandArgv1) {
if (expandArgv1 && process.argv[1] &&
!StringPrototypeStartsWith(process.argv[1], '-')) {
// Expand process.argv[1] into a full path.

View File

@@ -11,7 +11,7 @@ trying to see whether or not the lines are greyed out. One possibility
would be to upstream a changed test that doesn't hardcode line numbers.
diff --git a/test/fixtures/errors/force_colors.snapshot b/test/fixtures/errors/force_colors.snapshot
index 0334a0b4faa3633aa8617b9538873e7f3540513b..fa9989f55980aeddd3fa944318488c0289e3ab6e 100644
index 0334a0b4faa3633aa8617b9538873e7f3540513b..0d503d60931278ff9a7fb41177687688119390a3 100644
--- a/test/fixtures/errors/force_colors.snapshot
+++ b/test/fixtures/errors/force_colors.snapshot
@@ -4,11 +4,12 @@ throw new Error('Should include grayed stack trace')
@@ -27,7 +27,7 @@ index 0334a0b4faa3633aa8617b9538873e7f3540513b..fa9989f55980aeddd3fa944318488c02
+ at Object..js (node:internal*modules*cjs*loader:1326:10)
+ at Module.load (node:internal*modules*cjs*loader:1126:32)
+ at node:internal*modules*cjs*loader:967:12
+ at Function._load (node:electron*js2c*asar_bundle:743:32)
+ at Function._load (node:electron*js2c*node_init:741:32)
+ at Function.executeUserEntryPoint [as runMain] (node:internal*modules*run_main:96:12)
 at node:internal*main*run_main_module:23:47

View File

@@ -8,7 +8,7 @@ to child processes spawned with `ELECTRON_RUN_AS_NODE` which is used
by the crashpad client to connect with the handler process.
diff --git a/lib/child_process.js b/lib/child_process.js
index da553f6556a06d57d7490d74a3b4dd8f0132600c..168a6c72520d6540f0dbf84a62bc5e2b2f3ae022 100644
index 59c37b97672d39a9da89ca2b78aa28a77ca78699..319d853a35d9191c64a4f21132306a774acd84e6 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -60,6 +60,7 @@ let debug = require('internal/util/debuglog').debuglog(
@@ -19,7 +19,7 @@ index da553f6556a06d57d7490d74a3b4dd8f0132600c..168a6c72520d6540f0dbf84a62bc5e2b
const {
AbortError,
@@ -163,7 +164,6 @@ function fork(modulePath, args = [], options) {
@@ -152,7 +153,6 @@ function fork(modulePath, args = [], options) {
ArrayPrototypeSplice(execArgv, index - 1, 2);
}
}
@@ -27,7 +27,7 @@ index da553f6556a06d57d7490d74a3b4dd8f0132600c..168a6c72520d6540f0dbf84a62bc5e2b
args = [...execArgv, modulePath, ...args];
if (typeof options.stdio === 'string') {
@@ -625,6 +625,21 @@ function normalizeSpawnArguments(file, args, options) {
@@ -614,6 +614,21 @@ function normalizeSpawnArguments(file, args, options) {
'options.windowsVerbatimArguments');
}

View File

@@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Thu, 13 Sep 2018 08:56:07 -0700
Subject: feat: initialize asar support
This patch initializes asar support in Node.js.
diff --git a/lib/internal/process/policy.js b/lib/internal/process/policy.js
index 8e07cb92118c84b2bc1156532cae8b033b9a48f4..2073a024ad548fe80e84cafee012b003454d6c93 100644
--- a/lib/internal/process/policy.js
+++ b/lib/internal/process/policy.js
@@ -39,9 +39,6 @@ module.exports = ObjectFreeze({
process.binding = function binding(_module) {
throw new ERR_ACCESS_DENIED('process.binding');
};
- process._linkedBinding = function _linkedBinding(_module) {
- throw new ERR_ACCESS_DENIED('process._linkedBinding');
- };
},
get manifest() {
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 250a43c5455b4f9ff72dd3a34d5b0aa270f43cc6..2e35cbba2ac02494c44821af395fe0195b1ab6b5 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -117,12 +117,17 @@ function setupUserModules() {
loadPreloadModules();
// Need to be done after --require setup.
initializeFrozenIntrinsics();
+ setupAsarSupport();
}
function refreshRuntimeOptions() {
refreshOptions();
}
+function setupAsarSupport() {
+ process._linkedBinding('electron_common_asar').initAsarSupport(require);
+}
+
function patchProcessObject(expandArgv1) {
const binding = internalBinding('process_methods');
binding.patchProcessObject(process);
diff --git a/test/fixtures/policy/process-binding/app.js b/test/fixtures/policy/process-binding/app.js
index 16e26d12a160286b1b6aaeb64b15668b05b9865b..a287d0a2363acbf24077eec040116f96ef18a7b3 100644
--- a/test/fixtures/policy/process-binding/app.js
+++ b/test/fixtures/policy/process-binding/app.js
@@ -5,6 +5,3 @@ const assert = require('assert');
assert.throws(() => { process.binding(); }, {
code: 'ERR_ACCESS_DENIED'
});
-assert.throws(() => { process._linkedBinding(); }, {
- code: 'ERR_ACCESS_DENIED'
-});

View File

@@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 30 Jul 2018 10:30:35 -0700
Subject: refactor: alter child_process.fork to use execute script with
Electron
When forking a child script, we setup a special environment to make the Electron binary run like the upstream node. On Mac, we use the helper app as node binary.
diff --git a/lib/child_process.js b/lib/child_process.js
index 59c37b97672d39a9da89ca2b78aa28a77ca78699..da553f6556a06d57d7490d74a3b4dd8f0132600c 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -137,7 +137,18 @@ function fork(modulePath, args = [], options) {
validateObject(options, 'options');
}
options = { ...options, shell: false };
+
+ // When forking a child script, we setup a special environment to make
+ // the electron binary run like upstream Node.js
+ options.env = Object.create(options.env || process.env)
+ options.env.ELECTRON_RUN_AS_NODE = 1;
+
+ if (!options.execPath && process.type && process.platform == 'darwin') {
+ options.execPath = process.helperExecPath;
+ }
+
options.execPath = options.execPath || process.execPath;
+
validateArgumentNullCheck(options.execPath, 'options.execPath');
// Prepare arguments for fork:

View File

@@ -0,0 +1,283 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Mon, 4 Mar 2024 11:41:18 +0900
Subject: src: preload function for Environment
Backport https://github.com/nodejs/node/pull/51539
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 31f5d1528c840a2926b59b2b1c82ff265588a37a..1e37bd59f53d3a194b2492c83f8e7299c42c828c 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -114,6 +114,9 @@ function setupUserModules() {
initializeESMLoader();
const CJSLoader = require('internal/modules/cjs/loader');
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
+ if (getEmbedderOptions().hasEmbedderPreload) {
+ runEmbedderPreload();
+ }
loadPreloadModules();
// Need to be done after --require setup.
initializeFrozenIntrinsics();
@@ -588,6 +591,10 @@ function initializeFrozenIntrinsics() {
}
}
+function runEmbedderPreload() {
+ internalBinding('mksnapshot').runEmbedderPreload(process, require);
+}
+
function loadPreloadModules() {
// For user code, we preload modules if `-r` is passed
const preloadModules = getOptionValue('--require');
diff --git a/src/api/environment.cc b/src/api/environment.cc
index c4caef25af670658965fc740ce03c2d2c4ed3e66..465ff36b79c36d29777c7b1abe3a35d3be5de93e 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -484,18 +484,22 @@ NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
#endif
}
-MaybeLocal<Value> LoadEnvironment(
- Environment* env,
- StartExecutionCallback cb) {
+MaybeLocal<Value> LoadEnvironment(Environment* env,
+ StartExecutionCallback cb,
+ EmbedderPreloadCallback preload) {
env->InitializeLibuv();
env->InitializeDiagnostics();
+ if (preload) {
+ env->set_embedder_preload(std::move(preload));
+ }
return StartExecution(env, cb);
}
MaybeLocal<Value> LoadEnvironment(
Environment* env,
- const char* main_script_source_utf8) {
+ const char* main_script_source_utf8,
+ EmbedderPreloadCallback preload) {
CHECK_NOT_NULL(main_script_source_utf8);
return LoadEnvironment(
env, [&](const StartExecutionCallbackInfo& info) -> MaybeLocal<Value> {
@@ -508,7 +512,8 @@ MaybeLocal<Value> LoadEnvironment(
std::vector<Local<Value>> args = {realm->process_object(),
realm->builtin_module_require()};
return realm->ExecuteBootstrapper(name.c_str(), &args);
- });
+ },
+ std::move(preload));
}
Environment* GetCurrentEnvironment(Local<Context> context) {
diff --git a/src/env-inl.h b/src/env-inl.h
index debd982c75805c51ea7d01229b9d635550060503..a6f160b6e28a01a31d6bb06fcfa384c748463c50 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -388,6 +388,14 @@ inline std::vector<double>* Environment::destroy_async_id_list() {
return &destroy_async_id_list_;
}
+inline const EmbedderPreloadCallback& Environment::embedder_preload() const {
+ return embedder_preload_;
+}
+
+inline void Environment::set_embedder_preload(EmbedderPreloadCallback fn) {
+ embedder_preload_ = std::move(fn);
+}
+
inline double Environment::new_async_id() {
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
diff --git a/src/env.h b/src/env.h
index c914b621f50bcd6bce2617fef9e48737235aa516..e8ea98f193fcf579c20c3126dd441850c608752e 100644
--- a/src/env.h
+++ b/src/env.h
@@ -933,6 +933,9 @@ class Environment : public MemoryRetainer {
#endif // HAVE_INSPECTOR
+ inline const EmbedderPreloadCallback& embedder_preload() const;
+ inline void set_embedder_preload(EmbedderPreloadCallback fn);
+
inline void set_process_exit_handler(
std::function<void(Environment*, int)>&& handler);
@@ -1101,6 +1104,7 @@ class Environment : public MemoryRetainer {
DefaultProcessExitHandler };
std::unique_ptr<Realm> principal_realm_ = nullptr;
+ EmbedderPreloadCallback embedder_preload_;
// Used by allocate_managed_buffer() and release_managed_buffer() to keep
// track of the BackingStore for a given pointer.
diff --git a/src/node.h b/src/node.h
index 26368061a909e6abc62a4cf261a5dbbd79404f1a..0dec1e311d7c00c2b830a0b2a6bde4336aebe68b 100644
--- a/src/node.h
+++ b/src/node.h
@@ -630,13 +630,33 @@ struct StartExecutionCallbackInfo {
using StartExecutionCallback =
std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>;
+using EmbedderPreloadCallback =
+ std::function<void(Environment* env,
+ v8::Local<v8::Value> process,
+ v8::Local<v8::Value> require)>;
+// Run initialization for the environment.
+//
+// The |preload| function, usually used by embedders to inject scripts,
+// will be run by Node.js before Node.js executes the entry point.
+// The function is guaranteed to run before the user land module loader running
+// any user code, so it is safe to assume that at this point, no user code has
+// been run yet.
+// The function will be executed with preload(process, require), and the passed
+// require function has access to internal Node.js modules. There is no
+// stability guarantee about the internals exposed to the internal require
+// function. Expect breakages when updating Node.js versions if the embedder
+// imports internal modules with the internal require function.
+// Worker threads created in the environment will also respect The |preload|
+// function, so make sure the function is thread-safe.
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
Environment* env,
- StartExecutionCallback cb);
+ StartExecutionCallback cb,
+ EmbedderPreloadCallback preload = nullptr);
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
Environment* env,
- const char* main_script_source_utf8);
+ const char* main_script_source_utf8,
+ EmbedderPreloadCallback preload = nullptr);
NODE_EXTERN void FreeEnvironment(Environment* env);
// Set a callback that is called when process.exit() is called from JS,
diff --git a/src/node_options.cc b/src/node_options.cc
index 7ad8d80faee840e4dd224d946871b2ff08b0c23c..25842fd531fc7e1485bcd75f1f92aa9bc0640862 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1220,6 +1220,12 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
Boolean::New(isolate, env->no_global_search_paths()))
.IsNothing()) return;
+ if (ret->Set(context,
+ FIXED_ONE_BYTE_STRING(env->isolate(), "hasEmbedderPreload"),
+ Boolean::New(isolate, env->embedder_preload() != nullptr))
+ .IsNothing())
+ return;
+
args.GetReturnValue().Set(ret);
}
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
index bfa048a4a8aa183e747dec84b11b1c1d847db2dd..970cec6c6e9c5e9646bfd758a2cf908e6b5799cf 100644
--- a/src/node_snapshotable.cc
+++ b/src/node_snapshotable.cc
@@ -1462,6 +1462,17 @@ void SerializeSnapshotableObjects(Realm* realm,
namespace mksnapshot {
+void RunEmbedderPreload(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(env->embedder_preload());
+ CHECK_EQ(args.Length(), 2);
+ Local<Value> process_obj = args[0];
+ Local<Value> require_fn = args[1];
+ CHECK(process_obj->IsObject());
+ CHECK(require_fn->IsFunction());
+ env->embedder_preload()(env, process_obj, require_fn);
+}
+
void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());
Local<String> filename = args[0].As<String>();
@@ -1515,6 +1526,7 @@ void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
+ SetMethod(context, target, "runEmbedderPreload", RunEmbedderPreload);
SetMethod(context, target, "compileSerializeMain", CompileSerializeMain);
SetMethod(context, target, "setSerializeCallback", SetSerializeCallback);
SetMethod(context, target, "setDeserializeCallback", SetDeserializeCallback);
@@ -1525,6 +1537,7 @@ void Initialize(Local<Object> target,
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
+ registry->Register(RunEmbedderPreload);
registry->Register(CompileSerializeMain);
registry->Register(SetSerializeCallback);
registry->Register(SetDeserializeCallback);
diff --git a/src/node_worker.cc b/src/node_worker.cc
index 6a49144ec4f2059fe75983609b0768e4c2b1817d..13b0445370c70cf3765a4af44336c16ac2e1035d 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -60,6 +60,7 @@ Worker::Worker(Environment* env,
thread_id_(AllocateEnvironmentThreadId()),
name_(name),
env_vars_(env_vars),
+ embedder_preload_(env->embedder_preload()),
snapshot_data_(snapshot_data) {
Debug(this, "Creating new worker instance with thread id %llu",
thread_id_.id);
@@ -354,8 +355,12 @@ void Worker::Run() {
}
Debug(this, "Created message port for worker %llu", thread_id_.id);
- if (LoadEnvironment(env_.get(), StartExecutionCallback{}).IsEmpty())
+ if (LoadEnvironment(env_.get(),
+ StartExecutionCallback{},
+ std::move(embedder_preload_))
+ .IsEmpty()) {
return;
+ }
Debug(this, "Loaded environment for worker %llu", thread_id_.id);
}
diff --git a/src/node_worker.h b/src/node_worker.h
index a77c416735a79feb3f54e40d72a98c8903a20ccd..deab68576f6330f8bcfb4703fd05dbb9c515e473 100644
--- a/src/node_worker.h
+++ b/src/node_worker.h
@@ -113,6 +113,7 @@ class Worker : public AsyncWrap {
std::unique_ptr<MessagePortData> child_port_data_;
std::shared_ptr<KVStore> env_vars_;
+ EmbedderPreloadCallback embedder_preload_;
// A raw flag that is used by creator and worker threads to
// sync up on pre-mature termination of worker - while in the
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
index 547c8ddbffe243113bfe47a51072bb8f1541b94f..9f1fec4c4e47376c3b93a549f5c7ddf8e7ed3ac6 100644
--- a/test/cctest/test_environment.cc
+++ b/test/cctest/test_environment.cc
@@ -749,3 +749,31 @@ TEST_F(EnvironmentTest, RequestInterruptAtExit) {
node::FreeIsolateData(isolate_data);
context->Exit();
}
+
+TEST_F(EnvironmentTest, EmbedderPreload) {
+ v8::HandleScope handle_scope(isolate_);
+ v8::Local<v8::Context> context = node::NewContext(isolate_);
+ v8::Context::Scope context_scope(context);
+
+ node::EmbedderPreloadCallback preload = [](node::Environment* env,
+ v8::Local<v8::Value> process,
+ v8::Local<v8::Value> require) {
+ CHECK(process->IsObject());
+ CHECK(require->IsFunction());
+ process.As<v8::Object>()
+ ->Set(env->context(),
+ v8::String::NewFromUtf8Literal(env->isolate(), "prop"),
+ v8::String::NewFromUtf8Literal(env->isolate(), "preload"))
+ .Check();
+ };
+
+ std::unique_ptr<node::Environment, decltype(&node::FreeEnvironment)> env(
+ node::CreateEnvironment(isolate_data_, context, {}, {}),
+ node::FreeEnvironment);
+
+ v8::Local<v8::Value> main_ret =
+ node::LoadEnvironment(env.get(), "return process.prop;", preload)
+ .ToLocalChecked();
+ node::Utf8Value main_ret_str(isolate_, main_ret);
+ EXPECT_EQ(std::string(*main_ret_str), "preload");
+}

1
patches/sqlite/.patches Normal file
View File

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

View File

@@ -0,0 +1,323 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: dan <Dan Kennedy>
Date: Thu, 2 Nov 2023 21:02:53 +0000
Subject: Fix a spurious "misuse of aggregate function" error that could occur
when an aggregate function was used within the FROM clause of a sub-select of
the select that owns the aggregate. e.g. "SELECT (SELECT x FROM (SELECT
sum(t1.a) AS x)) FROM t1". [forum:/forumpost/c9970a37ed | Forum post
c9970a37ed].
FossilOrigin-Name: 4470f657d2069972d02a00983252dec1f814d90c0d8d0906e320e955111e8c11
(cherry picked from commit 5e4233a9e48b124d4d342b757b34e4ae849f5cf8)
diff --git a/amalgamation/rename_exports.h b/amalgamation/rename_exports.h
index 1dd9873cd698b9708c1e0897e6f270b5dd4e20c1..3b9835c71a5117dfeb249f30d930047c8722962c 100644
--- a/amalgamation/rename_exports.h
+++ b/amalgamation/rename_exports.h
@@ -1,4 +1,4 @@
-// Copyright 2023 The Chromium Authors. All rights reserved.
+// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/amalgamation/sqlite3.c b/amalgamation/sqlite3.c
index 19637a9234893df86d3d7b12b16617bca56f36e4..3b0548b328bc750665c7d0a67302c5f6097fde4e 100644
--- a/amalgamation/sqlite3.c
+++ b/amalgamation/sqlite3.c
@@ -458,7 +458,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.42.0"
#define SQLITE_VERSION_NUMBER 3042000
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -18921,6 +18921,7 @@ struct NameContext {
int nRef; /* Number of names resolved by this context */
int nNcErr; /* Number of errors encountered while resolving names */
int ncFlags; /* Zero or more NC_* flags defined below */
+ int nNestedSelect; /* Number of nested selects using this NC */
Select *pWinSelect; /* SELECT statement for any window functions */
};
@@ -105274,11 +105275,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
while( pNC2
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
){
- pExpr->op2++;
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
pNC2 = pNC2->pNext;
}
assert( pDef!=0 || IN_RENAME_OBJECT );
if( pNC2 && pDef ){
+ pExpr->op2 += pNC2->nNestedSelect;
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
@@ -105839,6 +105841,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
/* Recursively resolve names in all subqueries in the FROM clause
*/
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
for(i=0; i<p->pSrc->nSrc; i++){
SrcItem *pItem = &p->pSrc->a[i];
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
@@ -105863,6 +105866,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
}
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
diff --git a/amalgamation/sqlite3.h b/amalgamation/sqlite3.h
index 820dbeeb157b79d3380e089f1fdd5862a4cab087..c3738817186bbfd60aa7d19a3327d6a4ca118bc3 100644
--- a/amalgamation/sqlite3.h
+++ b/amalgamation/sqlite3.h
@@ -148,7 +148,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.42.0"
#define SQLITE_VERSION_NUMBER 3042000
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
/*
** CAPI3REF: Run-Time Library Version Numbers
diff --git a/amalgamation_dev/rename_exports.h b/amalgamation_dev/rename_exports.h
index 1dd9873cd698b9708c1e0897e6f270b5dd4e20c1..3b9835c71a5117dfeb249f30d930047c8722962c 100644
--- a/amalgamation_dev/rename_exports.h
+++ b/amalgamation_dev/rename_exports.h
@@ -1,4 +1,4 @@
-// Copyright 2023 The Chromium Authors. All rights reserved.
+// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/amalgamation_dev/sqlite3.c b/amalgamation_dev/sqlite3.c
index 36a6a8306fffaf38ff6d2feb6541c0eccd8df8fc..b10707a5fb419fc64694de2642371e43899022b8 100644
--- a/amalgamation_dev/sqlite3.c
+++ b/amalgamation_dev/sqlite3.c
@@ -458,7 +458,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.42.0"
#define SQLITE_VERSION_NUMBER 3042000
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -18934,6 +18934,7 @@ struct NameContext {
int nRef; /* Number of names resolved by this context */
int nNcErr; /* Number of errors encountered while resolving names */
int ncFlags; /* Zero or more NC_* flags defined below */
+ int nNestedSelect; /* Number of nested selects using this NC */
Select *pWinSelect; /* SELECT statement for any window functions */
};
@@ -105287,11 +105288,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
while( pNC2
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
){
- pExpr->op2++;
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
pNC2 = pNC2->pNext;
}
assert( pDef!=0 || IN_RENAME_OBJECT );
if( pNC2 && pDef ){
+ pExpr->op2 += pNC2->nNestedSelect;
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
@@ -105852,6 +105854,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
/* Recursively resolve names in all subqueries in the FROM clause
*/
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
for(i=0; i<p->pSrc->nSrc; i++){
SrcItem *pItem = &p->pSrc->a[i];
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
@@ -105876,6 +105879,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
}
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
diff --git a/amalgamation_dev/sqlite3.h b/amalgamation_dev/sqlite3.h
index 820dbeeb157b79d3380e089f1fdd5862a4cab087..c3738817186bbfd60aa7d19a3327d6a4ca118bc3 100644
--- a/amalgamation_dev/sqlite3.h
+++ b/amalgamation_dev/sqlite3.h
@@ -148,7 +148,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.42.0"
#define SQLITE_VERSION_NUMBER 3042000
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
/*
** CAPI3REF: Run-Time Library Version Numbers
diff --git a/manifest b/manifest
index 0841fab32a918f21970cf1806a984261f1aaccfb..e7b2f86954fa8078cb3211b5e5cfcb319b50b6dc 100644
--- a/manifest
+++ b/manifest
@@ -634,14 +634,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c 6350675966bd0e7ac3a464af9dbfe26db6f0d4237f4e1f1acdb17b12ad371e6e
F src/printf.c b9320cdbeca0b336c3f139fd36dd121e4167dd62b35fbe9ccaa9bab44c0af38d
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
-F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032
+F src/resolve.c 9bcc9021a5b849ba8ccd2103147b75a3a98d885e00212b48672fe1ed8356338b
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 738c3a3d6929f8be66c319bad17f6b297bd60a4eb14006075c48a28487dc7786
F src/shell.c.in a8971a2ae4adee5f0a73d7a6c095026e8a2958ff3e9f56887a014df07733ca0c
F src/sqlite.h.in c14a4471fcd897a03631ac7ad3d05505e895e7b6419ec5b96cae9bc4df7a9fc6
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
-F src/sqliteInt.h a3ced8b9ebc573189c87b69f24bf10d2b9cd3cefefaae52623a2fa79e6fdd408
+F src/sqliteInt.h 522f19804d86e193dbfd966cd0dd033e0f6ec092e60c3812ae066657fe152653
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -731,7 +731,7 @@ F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867d
F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggfault.test 777f269d0da5b0c2524c7ff6d99ae9a93db4f1b1839a914dd2a12e3035c29829
-F test/aggnested.test 7269d07ac879fce161cb26c8fabe65cba5715742fac8a1fccac570dcdaf28f00
+F test/aggnested.test e1977bdc0a154b99c139b879b78c46030aa6ee97fb06bf65d6784a536e25b743
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
F test/alter.test 313073774ab5c3f2ef1d3f0d03757c9d3a81284ae7e1b4a6ca34db088f886896
@@ -1920,7 +1920,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
-F test/window1.test 5ba48e9d33231e6ef16f21426bade9ccc52abf65a10587bff90a6c14fe174594
+F test/window1.test 95d0d3e43a54600beba759f9a9f4f4bf546a596b1a8cc3f70dd26bf22ce7e41a
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
diff --git a/src/resolve.c b/src/resolve.c
index adfcc8dbe9cf41581a23cfc42a6d699bf86d384f..b453a5b456ea1e0db814e1bd13c3fbe706a19a38 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -1212,11 +1212,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
while( pNC2
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
){
- pExpr->op2++;
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
pNC2 = pNC2->pNext;
}
assert( pDef!=0 || IN_RENAME_OBJECT );
if( pNC2 && pDef ){
+ pExpr->op2 += pNC2->nNestedSelect;
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
@@ -1777,6 +1778,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
/* Recursively resolve names in all subqueries in the FROM clause
*/
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
for(i=0; i<p->pSrc->nSrc; i++){
SrcItem *pItem = &p->pSrc->a[i];
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
@@ -1801,6 +1803,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
}
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 2c893770b04e06932b9c4405ff9b41a13aff68d0..ab94b56c638724a9de8ea2da49c944fb85a1923f 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3332,6 +3332,7 @@ struct NameContext {
int nRef; /* Number of names resolved by this context */
int nNcErr; /* Number of errors encountered while resolving names */
int ncFlags; /* Zero or more NC_* flags defined below */
+ int nNestedSelect; /* Number of nested selects using this NC */
Select *pWinSelect; /* SELECT statement for any window functions */
};
diff --git a/test/aggnested.test b/test/aggnested.test
index 1b8b608803912d5d8b7a7562dd31ec4a46627da4..6599fbf90940e49ce3467c67b7c8800aa90b17c0 100644
--- a/test/aggnested.test
+++ b/test/aggnested.test
@@ -358,6 +358,60 @@ do_execsql_test 6.2.2 {
FROM t2 GROUP BY 'constant_string';
} {{}}
+#-------------------------------------------------------------------------
+reset_db
+
+do_execsql_test 7.0 {
+ CREATE TABLE invoice (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ amount DOUBLE PRECISION DEFAULT NULL,
+ name VARCHAR(100) DEFAULT NULL
+ );
+
+ INSERT INTO invoice (amount, name) VALUES
+ (4.0, 'Michael'), (15.0, 'Bara'), (4.0, 'Michael'), (6.0, 'John');
+}
+
+do_execsql_test 7.1 {
+ SELECT sum(amount), name
+ from invoice
+ group by name
+ having (select v > 6 from (select sum(amount) v) t)
+} {
+ 15.0 Bara
+ 8.0 Michael
+}
+
+do_execsql_test 7.2 {
+ SELECT (select 1 from (select sum(amount))) FROM invoice
+} {1}
+
+do_execsql_test 8.0 {
+ CREATE TABLE t1(x INT);
+ INSERT INTO t1 VALUES(100);
+ INSERT INTO t1 VALUES(20);
+ INSERT INTO t1 VALUES(3);
+ SELECT (SELECT y FROM (SELECT sum(x) AS y) AS t2 ) FROM t1;
+} {123}
+
+do_execsql_test 8.1 {
+ SELECT (
+ SELECT y FROM (
+ SELECT z AS y FROM (SELECT sum(x) AS z) AS t2
+ )
+ ) FROM t1;
+} {123}
+
+do_execsql_test 8.2 {
+ SELECT (
+ SELECT a FROM (
+ SELECT y AS a FROM (
+ SELECT z AS y FROM (SELECT sum(x) AS z) AS t2
+ )
+ )
+ ) FROM t1;
+} {123}
+
diff --git a/test/window1.test b/test/window1.test
index 783a739e3f1428f107932319a53e9cde91e79557..8044d43547718bb54b301c185adf60bf70ab1ae8 100644
--- a/test/window1.test
+++ b/test/window1.test
@@ -1881,7 +1881,7 @@ do_catchsql_test 57.3 {
SELECT max(y) OVER( ORDER BY (SELECT x FROM (SELECT sum(y) AS x FROM t1)))
)
FROM t3;
-} {1 {misuse of aggregate: sum()}}
+} {0 5}
# 2020-06-06 ticket 1f6f353b684fc708
reset_db

View File

@@ -2,3 +2,13 @@ build_gn.patch
do_not_export_private_v8_symbols_on_windows.patch
fix_build_deprecated_attribute_for_older_msvc_versions.patch
chore_allow_customizing_microtask_policy_per_context.patch
cherry-pick-cbd09b2ca928.patch
merged_turboshaft_fix_structuraloptimization_because_of_ignored.patch
cherry-pick-389ea9be7d68.patch
cherry-pick-46cb67e3b296.patch
cherry-pick-78dd4b31847a.patch
merged_wasm_add_bounds_check_in_tier-up_of_wasm-to-js_wrapper.patch
merged_parser_fix_home_object_proxy_to_work_off-thread.patch
merged_wasm_check_for_type-definition_count_limit.patch
merged_runtime_recreate_enum_cache_on_map_update_if_any_previous.patch
merged_wasm_check_the_cached_memory_for_growability.patch

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