From 4799b61742201faeabe535f7d71f31c75bd19cf1 Mon Sep 17 00:00:00 2001 From: "electron-roller[bot]" <84116207+electron-roller[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 18:49:22 -0700 Subject: [PATCH] chore: bump chromium to 148.0.7778.40 (42-x-y) (#51126) * chore: bump chromium in DEPS to 148.0.7778.40 * chore: update patches * chore: update patches after rebase --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: John Kleinschmidt --- DEPS | 2 +- patches/chromium/.patches | 7 - .../build_add_electron_tracing_category.patch | 2 +- ..._depend_on_packed_resource_integrity.patch | 6 +- patches/chromium/can_create_window.patch | 4 +- .../chromium/cherry-pick-1b69067db7d2.patch | 103 ----- .../chromium/cherry-pick-847b11ad2fa3.patch | 216 ---------- .../chromium/cherry-pick-b173791bf402.patch | 53 --- .../chromium/cherry-pick-be87466afecb.patch | 224 ----------- .../chromium/cherry-pick-c0390bcd64ba.patch | 4 +- .../chromium/cherry-pick-d513cd2fe668.patch | 59 --- .../chromium/cherry-pick-dc5e20c4c055.patch | 78 ---- .../chromium/cherry-pick-fc79e8cc2dfc.patch | 368 ------------------ ...xpose_setuseragent_on_networkcontext.patch | 6 +- ...moothing_css_rule_and_blink_painting.patch | 2 +- ...screen_rendering_with_viz_compositor.patch | 4 +- ...ding_non-standard_schemes_in_iframes.patch | 6 +- ..._background_throttling_in_compositor.patch | 6 +- ...from_localframe_requestexecutescript.patch | 2 +- patches/chromium/frame_host_manager.patch | 4 +- ..._avoid_private_macos_api_usage.patch.patch | 6 +- ...emote_certificate_verification_logic.patch | 8 +- .../chromium/notification_provenance.patch | 6 +- .../support_mixed_sandbox_with_zygote.patch | 4 +- patches/chromium/webview_fullscreen.patch | 4 +- .../worker_context_will_destroy.patch | 2 +- ...feat_add_hook_to_notify_script_ready.patch | 2 +- patches/config.json | 4 +- patches/dawn/.patches | 1 - patches/dawn/cherry-pick-7c11e1188705.patch | 118 ------ patches/pdfium/.patches | 1 - patches/pdfium/cherry-pick-bce2e6728279.patch | 36 -- 32 files changed, 41 insertions(+), 1307 deletions(-) delete mode 100644 patches/chromium/cherry-pick-1b69067db7d2.patch delete mode 100644 patches/chromium/cherry-pick-847b11ad2fa3.patch delete mode 100644 patches/chromium/cherry-pick-b173791bf402.patch delete mode 100644 patches/chromium/cherry-pick-be87466afecb.patch delete mode 100644 patches/chromium/cherry-pick-d513cd2fe668.patch delete mode 100644 patches/chromium/cherry-pick-dc5e20c4c055.patch delete mode 100644 patches/chromium/cherry-pick-fc79e8cc2dfc.patch delete mode 100644 patches/dawn/cherry-pick-7c11e1188705.patch delete mode 100644 patches/pdfium/cherry-pick-bce2e6728279.patch diff --git a/DEPS b/DEPS index 54d14cd3fa..6f138eced4 100644 --- a/DEPS +++ b/DEPS @@ -2,7 +2,7 @@ gclient_gn_args_from = 'src' vars = { 'chromium_version': - '148.0.7778.5', + '148.0.7778.40', 'node_version': 'v24.15.0', 'nan_version': diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 1867e66a62..df4ba33e47 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -149,11 +149,4 @@ fix_fire_menu_popup_start_for_dynamically_created_aria_menus.patch feat_allow_enabling_extensions_on_custom_protocols.patch fix_initialize_com_on_desktopmedialistcapturethread_on_windows.patch fix_use_fresh_lazynow_for_onendworkitemimpl_after_didruntask.patch -cherry-pick-b173791bf402.patch -cherry-pick-be87466afecb.patch cherry-pick-c0390bcd64ba.patch -cherry-pick-1b69067db7d2.patch -cherry-pick-d513cd2fe668.patch -cherry-pick-dc5e20c4c055.patch -cherry-pick-847b11ad2fa3.patch -cherry-pick-fc79e8cc2dfc.patch diff --git a/patches/chromium/build_add_electron_tracing_category.patch b/patches/chromium/build_add_electron_tracing_category.patch index c055ad77dd..35873e0182 100644 --- a/patches/chromium/build_add_electron_tracing_category.patch +++ b/patches/chromium/build_add_electron_tracing_category.patch @@ -8,7 +8,7 @@ categories in use are known / declared. This patch is required for us to introduce a new Electron category for Electron-specific tracing. diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h -index 440349df6c5767fe3f93b51f78b33bf9d3bb5c1a..85c6f973788938b6a48a7a89e9fa803dc1030580 100644 +index 8bc03cb77ebdfe991e0ebe05aa187dfdea8c2764..976221d0303036ecae500b7861931ff96e9ea0c1 100644 --- a/base/trace_event/builtin_categories.h +++ b/base/trace_event/builtin_categories.h @@ -133,6 +133,7 @@ PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS( diff --git a/patches/chromium/build_do_not_depend_on_packed_resource_integrity.patch b/patches/chromium/build_do_not_depend_on_packed_resource_integrity.patch index c7929b3366..63b208fadd 100644 --- a/patches/chromium/build_do_not_depend_on_packed_resource_integrity.patch +++ b/patches/chromium/build_do_not_depend_on_packed_resource_integrity.patch @@ -28,7 +28,7 @@ index 0af4d4b75d0519fabcb5d48bd9d5bd465bc80e92..eb6b23655afaa268f25d99301a0853aa ":chrome_dll", ":chrome_exe_version", diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn -index e91f97276866bd500720962c74acaca2c22fff7c..22867153821d2b1e83feb1a2a7a6b8c26ba776eb 100644 +index cf5a56ee6eeeba1b7060e558874612c44f564560..fc0914f7f1feb615516c2120a37329a106874633 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn @@ -7737,6 +7737,10 @@ test("unit_tests") { @@ -42,7 +42,7 @@ index e91f97276866bd500720962c74acaca2c22fff7c..22867153821d2b1e83feb1a2a7a6b8c2 deps += [ "//chrome:other_version", "//chrome//services/util_win:unit_tests", -@@ -8711,6 +8715,10 @@ test("unit_tests") { +@@ -8712,6 +8716,10 @@ test("unit_tests") { "../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc", ] @@ -53,7 +53,7 @@ index e91f97276866bd500720962c74acaca2c22fff7c..22867153821d2b1e83feb1a2a7a6b8c2 sources += [ # The importer code is not used on Android. "../common/importer/firefox_importer_utils_unittest.cc", -@@ -8767,7 +8775,7 @@ test("unit_tests") { +@@ -8768,7 +8776,7 @@ test("unit_tests") { # TODO(crbug.com/417513088): Maybe merge with the non-android `deps` declaration above? deps += [ "../browser/screen_ai:screen_ai_install_state", diff --git a/patches/chromium/can_create_window.patch b/patches/chromium/can_create_window.patch index 9dc90564ad..ef3f936699 100644 --- a/patches/chromium/can_create_window.patch +++ b/patches/chromium/can_create_window.patch @@ -9,10 +9,10 @@ potentially prevent a window from being created. TODO(loc): this patch is currently broken. diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc -index ac474e220d411dec278c40448f038b25e6788d2a..e4ff8f11bed9e53f3134068492ac94b4c9bb4df2 100644 +index e416207b5f421b15827f0aa186234f425f9100df..d3a9d1b30dbbf7952203f0c93a068f493550fa79 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc -@@ -10228,6 +10228,7 @@ void RenderFrameHostImpl::CreateNewWindow( +@@ -10242,6 +10242,7 @@ void RenderFrameHostImpl::CreateNewWindow( last_committed_origin_, params->window_container_type, params->target_url, params->referrer.To(), params->frame_name, params->disposition, *params->features, diff --git a/patches/chromium/cherry-pick-1b69067db7d2.patch b/patches/chromium/cherry-pick-1b69067db7d2.patch deleted file mode 100644 index 5cffacb5db..0000000000 --- a/patches/chromium/cherry-pick-1b69067db7d2.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vasilii Sukhanov -Date: Wed, 8 Apr 2026 07:48:21 -0700 -Subject: Fix cross-domain password leak via manual-fallback preview - -In PasswordManualFallbackFlow::DidSelectSuggestion, when a user selects -a password suggestion, the browser process sends the cleartext password -to the renderer for previewing. If the suggestion is cross-domain, this -leak happens without consent or auth. - -This CL fixes this by omitting the password in the preview message for -all the cases by sending the fake string. - -Fixed: 498269651 -Change-Id: Ic9546114c453f05de1030f05c7a9830b39d73038 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7735152 -Commit-Queue: Vasilii Sukhanov -Reviewed-by: Anna Tsvirchkova -Cr-Commit-Position: refs/heads/main@{#1611490} - -diff --git a/components/password_manager/core/browser/password_manual_fallback_flow.cc b/components/password_manager/core/browser/password_manual_fallback_flow.cc -index 6fd5468b061949c7f4a45a29b07e1325bde629e3..47bd86d5fd70a849a13b6837a98f3009fbc10ea6 100644 ---- a/components/password_manager/core/browser/password_manual_fallback_flow.cc -+++ b/components/password_manager/core/browser/password_manual_fallback_flow.cc -@@ -213,12 +213,13 @@ void PasswordManualFallbackFlow::DidSelectSuggestion( - if (!form) { - return; - } -+ const auto payload = -+ suggestion.GetPayload(); - password_manager_driver_->PreviewSuggestionById( - form->username_element_renderer_id, - form->password_element_renderer_id, - GetUsernameFromLabel(suggestion.labels[0][0].value), -- suggestion.GetPayload() -- .password); -+ std::u16string(payload.password.length(), '*')); - break; - } - case autofill::SuggestionType::kPasswordFieldByFieldFilling: -diff --git a/components/password_manager/core/browser/password_manual_fallback_flow_unittest.cc b/components/password_manager/core/browser/password_manual_fallback_flow_unittest.cc -index 8b51bbcab5ec65562eed443ea9ba80dbaf8cba63..b99c6531aeb2d4c46e0a88cc0478e18c117c2bb6 100644 ---- a/components/password_manager/core/browser/password_manual_fallback_flow_unittest.cc -+++ b/components/password_manager/core/browser/password_manual_fallback_flow_unittest.cc -@@ -656,7 +656,7 @@ TEST_F(PasswordManualFallbackFlowTest, - EXPECT_CALL(driver(), PreviewSuggestionById(form.username_element_renderer_id, - form.password_element_renderer_id, - std::u16string(u"username"), -- std::u16string(u"password"))); -+ std::u16string(u"********"))); - Suggestion suggestion = autofill::test::CreateAutofillSuggestion( - SuggestionType::kPasswordEntry, u"google.com", - CreateTestPasswordDetails()); -@@ -667,6 +667,40 @@ TEST_F(PasswordManualFallbackFlowTest, - flow().DidSelectSuggestion(suggestion); - } - -+// Test that password manual fallback suggestion is previewed without password -+// if the suggestion is cross-domain. -+TEST_F(PasswordManualFallbackFlowTest, -+ SelectFillFullFormSuggestion_CrossDomain_TriggeredOnAPasswordForm) { -+ InitializeFlow(); -+ ProcessPasswordStoreUpdates(); -+ -+ PasswordForm form; -+ form.username_element_renderer_id = MakeFieldRendererId(); -+ form.password_element_renderer_id = MakeFieldRendererId(); -+ // Simulate that the field is/isn't classified as target filling password. -+ EXPECT_CALL(password_form_cache(), -+ GetPasswordForm(_, form.username_element_renderer_id)) -+ .WillRepeatedly(Return(&form)); -+ -+ flow().RunFlow(form.username_element_renderer_id, gfx::RectF{}, -+ TextDirection::LEFT_TO_RIGHT); -+ -+ // Expect that the password is empty in the preview call. -+ EXPECT_CALL(driver(), PreviewSuggestionById(form.username_element_renderer_id, -+ form.password_element_renderer_id, -+ std::u16string(u"username"), -+ std::u16string(u"********"))); -+ Suggestion suggestion = autofill::test::CreateAutofillSuggestion( -+ SuggestionType::kPasswordEntry, u"google.com", -+ Suggestion::PasswordSuggestionDetails(u"username", u"password", -+ "https://cross-domain.com/", -+ u"cross-domain.com", -+ /*is_cross_domain=*/true)); -+ suggestion.labels = {{Suggestion::Text(u"username")}}; -+ suggestion.acceptability = Suggestion::Acceptability::kAcceptable; -+ flow().DidSelectSuggestion(suggestion); -+} -+ - // Test that only password field is previewed if the credential doesn't have - // a username saved for it. - TEST_F(PasswordManualFallbackFlowTest, -@@ -687,7 +721,7 @@ TEST_F(PasswordManualFallbackFlowTest, - EXPECT_CALL(driver(), PreviewSuggestionById(FieldRendererId(), - form.password_element_renderer_id, - std::u16string(), -- std::u16string(u"password"))); -+ std::u16string(u"********"))); - Suggestion suggestion = autofill::test::CreateAutofillSuggestion( - SuggestionType::kPasswordEntry, u"google.com", - CreateTestPasswordDetails()); diff --git a/patches/chromium/cherry-pick-847b11ad2fa3.patch b/patches/chromium/cherry-pick-847b11ad2fa3.patch deleted file mode 100644 index ac460cf282..0000000000 --- a/patches/chromium/cherry-pick-847b11ad2fa3.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Joey Arhar -Date: Fri, 10 Apr 2026 12:19:11 -0700 -Subject: Fix crashes when restoring with - -When restoring form control state, the DOM could be modified to add or -remove more listed elements to the form if a select element is being -restored which has a selectedcontent element. - -Fixed: 499384399 -Change-Id: I18f69c30ae25396c53625f7a3172626b79de3ae3 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7732030 -Reviewed-by: Joey Arhar -Commit-Queue: Joey Arhar -Reviewed-by: Dominic Farolino -Cr-Commit-Position: refs/heads/main@{#1613032} - -diff --git a/third_party/blink/renderer/core/html/forms/form_controller.cc b/third_party/blink/renderer/core/html/forms/form_controller.cc -index abacf373d30debc17498eaeb7cd940972aed2a3a..c4cb59678eeacc2d3fb9f69a30df8674154dbf37 100644 ---- a/third_party/blink/renderer/core/html/forms/form_controller.cc -+++ b/third_party/blink/renderer/core/html/forms/form_controller.cc -@@ -492,8 +492,10 @@ void FormController::RestoreControlStateIn(HTMLFormElement& form) { - if (!document_->HasFinishedParsing()) - return; - EventQueueScope scope; -- const ListedElement::List& elements = form.ListedElements(); -- for (const auto& control : elements) { -+ // Make a copy of the list because the DOM could be modified during -+ // restoration of a with a element. -+ DocumentState::ControlList control_list_copy( -+ document_state_->GetControlList()); -+ for (auto& control : control_list_copy) { - auto* owner = OwnerFormForState(*control); - if (!owner) - RestoreControlStateFor(*control); -diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites -index ef47961c57cd15f8c59a4554165568c7f13c0d0a..54331107dd22c6b534327ffd5c282ca3220345de 100644 ---- a/third_party/blink/web_tests/VirtualTestSuites -+++ b/third_party/blink/web_tests/VirtualTestSuites -@@ -3067,7 +3067,7 @@ - ], - "bases": [ - "external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-in-option-crash.html", -- "external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.html", -+ "external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.optional.html", - "external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-color.html", - "external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-nested.html", - "external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontentelement-attr.tentative.html" -diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/resources/selectedcontent-input.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/resources/selectedcontent-input.html -new file mode 100644 -index 0000000000000000000000000000000000000000..847f42ac304835c2049cf434a4dec68814ad533c ---- /dev/null -+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/resources/selectedcontent-input.html -@@ -0,0 +1,27 @@ -+ -+ -+
-+ -+
-+ -+ -diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.html -deleted file mode 100644 -index da5fe450abbae0d19826021f114cc6388f97bc57..0000000000000000000000000000000000000000 ---- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.html -+++ /dev/null -@@ -1,35 +0,0 @@ -- -- -- -- -- -- -- -- -- -- -- -diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.optional.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.optional.html -new file mode 100644 -index 0000000000000000000000000000000000000000..1d0064659cd9df06d6267261bf0b39b3fb29aeef ---- /dev/null -+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/selectedcontent-restore.optional.html -@@ -0,0 +1,76 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ diff --git a/patches/chromium/cherry-pick-b173791bf402.patch b/patches/chromium/cherry-pick-b173791bf402.patch deleted file mode 100644 index a716a51bea..0000000000 --- a/patches/chromium/cherry-pick-b173791bf402.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: p0-tato -Date: Mon, 13 Apr 2026 14:50:07 -0700 -Subject: Fix dangling pointers in OpenXrSpatialFrameworkManager - -Pointers to vector elements were collected during emplace_back, -which invalidates them on reallocation. Split into two loops -and reserve the correct capacity. - -Bug: 497724498 -Change-Id: I204534bc1bd1522fe03db86f03c2c3e0d285631c -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7735242 -Commit-Queue: Brian Sheedy -Reviewed-by: Brian Sheedy -Reviewed-by: Brandon Jones -Cr-Commit-Position: refs/heads/main@{#1613990} - -diff --git a/AUTHORS b/AUTHORS -index 700ad1f495549eac39242e5d3b489245eb1b633d..5ef10597084e19b283209ee9833c56a7a0346187 100644 ---- a/AUTHORS -+++ b/AUTHORS -@@ -736,6 +736,7 @@ Jihoon Chung - Jihun Brent Kim - Jihwan Marc Kim - Jihye Hyun -+Jihyeon Jeong - Jihyeon Lee - Jim Wu - Jin Yang -diff --git a/device/vr/openxr/openxr_spatial_framework_manager.cc b/device/vr/openxr/openxr_spatial_framework_manager.cc -index 2fd3609f277dc425d38a9acf9895b1ad02d64c72..b6f82c5c2999073aad9c43811fe9561c670992f9 100644 ---- a/device/vr/openxr/openxr_spatial_framework_manager.cc -+++ b/device/vr/openxr/openxr_spatial_framework_manager.cc -@@ -74,12 +74,15 @@ OpenXrSpatialFrameworkManager::OpenXrSpatialFrameworkManager( - // to help abstract some of the details of creating the child structs, even - // though at present we only have a configuration base. - std::vector capability_configs; -- std::vector -- capability_config_ptrs; -+ capability_configs.reserve(capability_configuration.size()); - for (auto& [capability, components] : capability_configuration) { - capability_configs.emplace_back(capability, components); -- capability_config_ptrs.push_back( -- capability_configs.back().GetAsBaseHeader()); -+ } -+ -+ std::vector -+ capability_config_ptrs; -+ for (auto& config : capability_configs) { -+ capability_config_ptrs.push_back(config.GetAsBaseHeader()); - } - - XrSpatialContextCreateInfoEXT create_info = { diff --git a/patches/chromium/cherry-pick-be87466afecb.patch b/patches/chromium/cherry-pick-be87466afecb.patch deleted file mode 100644 index 9f0c2ea532..0000000000 --- a/patches/chromium/cherry-pick-be87466afecb.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jonathan Ross -Date: Wed, 8 Apr 2026 17:15:45 -0700 -Subject: gl: Make DCOMPSurfaceRegistry thread-safe - -DCOMPSurfaceRegistry is accessed from both the GPU IO thread (via -GpuServiceImpl) and the GPU main scheduler thread (via DCOMPTexture). -The underlying base::flat_map is not thread-safe, leading to potential -container corruption and crashes (UAF, BOf) during concurrent access. - -This CL adds a base::Lock to protect all accesses to the map and -includes a new multi-threaded stress test to verify the fix. - -Bug: 493315759 -Change-Id: Ibb7ef5e602f222410fde06a61fb3f5e571e7a70f -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7737061 -Reviewed-by: Sunny Sachanandani -Commit-Queue: Jonathan Ross -Cr-Commit-Position: refs/heads/main@{#1611867} - -diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn -index 3584b693370b5199456608a26ceb763f6e9c3446..1cb66199a0b8adf2035a05fecc411c67180f7e80 100644 ---- a/ui/gl/BUILD.gn -+++ b/ui/gl/BUILD.gn -@@ -552,6 +552,7 @@ test("gl_unittests") { - if (is_win) { - sources += [ - "dcomp_presenter_unittest.cc", -+ "dcomp_surface_registry_unittest.cc", - "delegated_ink_point_renderer_gpu_unittest.cc", - "gl_fence_win_unittest.cc", - "hdr_metadata_helper_win_unittest.cc", -diff --git a/ui/gl/dcomp_surface_registry.cc b/ui/gl/dcomp_surface_registry.cc -index 352cc298b9ea97361ae2a7d668b7d7e9eb455cd5..410f76f8980438abae32b6c89e7083ae48cf1699 100644 ---- a/ui/gl/dcomp_surface_registry.cc -+++ b/ui/gl/dcomp_surface_registry.cc -@@ -3,8 +3,11 @@ - // found in the LICENSE file. - - #include "ui/gl/dcomp_surface_registry.h" -+ -+#include "base/check.h" - #include "base/logging.h" - #include "base/no_destructor.h" -+#include "base/synchronization/lock.h" - - namespace gl { - -@@ -20,8 +23,11 @@ base::UnguessableToken DCOMPSurfaceRegistry::RegisterDCOMPSurfaceHandle( - base::win::ScopedHandle surface) { - DVLOG(1) << __func__; - base::UnguessableToken token = base::UnguessableToken::Create(); -- DCHECK(surface_handle_map_.find(token) == surface_handle_map_.end()); -- surface_handle_map_[token] = std::move(surface); -+ { -+ base::AutoLock lock(lock_); -+ DCHECK(surface_handle_map_.find(token) == surface_handle_map_.end()); -+ surface_handle_map_[token] = std::move(surface); -+ } - DVLOG(1) << __func__ << ": Surface handle registered with token " << token; - return token; - } -@@ -29,12 +35,14 @@ base::UnguessableToken DCOMPSurfaceRegistry::RegisterDCOMPSurfaceHandle( - void DCOMPSurfaceRegistry::UnregisterDCOMPSurfaceHandle( - const base::UnguessableToken& token) { - DVLOG(1) << __func__; -+ base::AutoLock lock(lock_); - surface_handle_map_.erase(token); - } - - base::win::ScopedHandle DCOMPSurfaceRegistry::TakeDCOMPSurfaceHandle( - const base::UnguessableToken& token) { - DVLOG(1) << __func__; -+ base::AutoLock lock(lock_); - auto surface_iter = surface_handle_map_.find(token); - if (surface_iter != surface_handle_map_.end()) { - // Take ownership. -diff --git a/ui/gl/dcomp_surface_registry.h b/ui/gl/dcomp_surface_registry.h -index 803a3cc6398f0777504063118920998869086d7f..7cd9fdbfe8669bc97d4b664fdb29573ec2ea26de 100644 ---- a/ui/gl/dcomp_surface_registry.h -+++ b/ui/gl/dcomp_surface_registry.h -@@ -7,6 +7,7 @@ - - #include "base/containers/flat_map.h" - #include "base/no_destructor.h" -+#include "base/synchronization/lock.h" - #include "base/unguessable_token.h" - #include "base/win/scoped_handle.h" - #include "ui/gl/gl_export.h" -@@ -44,7 +45,9 @@ class GL_EXPORT DCOMPSurfaceRegistry { - ~DCOMPSurfaceRegistry(); - - base::flat_map -- surface_handle_map_; -+ surface_handle_map_ GUARDED_BY(lock_); -+ -+ base::Lock lock_; - }; - - } // namespace gl -diff --git a/ui/gl/dcomp_surface_registry_unittest.cc b/ui/gl/dcomp_surface_registry_unittest.cc -new file mode 100644 -index 0000000000000000000000000000000000000000..595e2388e9f50df33214359ecef0c135d94610b8 ---- /dev/null -+++ b/ui/gl/dcomp_surface_registry_unittest.cc -@@ -0,0 +1,118 @@ -+// Copyright 2026 The Chromium Authors -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "ui/gl/dcomp_surface_registry.h" -+ -+#include -+ -+#include -+#include -+#include -+ -+#include "base/memory/raw_ptr.h" -+#include "base/synchronization/lock.h" -+#include "base/unguessable_token.h" -+#include "base/win/scoped_handle.h" -+#include "testing/gtest/include/gtest/gtest.h" -+ -+namespace gl { -+ -+namespace { -+ -+class DCOMPSurfaceRegistryTest : public testing::Test { -+ public: -+ void SetUp() override { registry_ = DCOMPSurfaceRegistry::GetInstance(); } -+ -+ protected: -+ raw_ptr registry_; -+}; -+ -+} // namespace -+ -+// Stress test for concurrent access to DCOMPSurfaceRegistry using the -+// barrier pattern to ensure TSAN consistently catches data races. -+// -+// Without proper synchronization (e.g., base::Lock), this test would likely -+// fail in the following ways: -+// 1. Memory Corruption (UAF/HeapBOf): base::flat_map uses a contiguous -+// std::vector. If one thread triggers a reallocation during an insertion -+// while another thread is searching or erasing, the latter will hold an -+// invalidated iterator or pointer. -+// 2. Container Inconsistency: Concurrent insertions and erasures can leave -+// the map in an unsorted or corrupted state, leading to failed lookups -+// for valid tokens. -+// 3. Sanitizer Triggers: ASan would detect container-overflow or -+// heap-use-after-free, and TSan would flag a data race. -+TEST_F(DCOMPSurfaceRegistryTest, ConcurrentRegisterAndTake) { -+ const int kOpsPerThread = 100; -+ -+ std::vector tokens; -+ base::Lock tokens_lock; -+ -+ std::atomic start_flag{false}; -+ std::atomic threads_ready{0}; -+ -+ auto register_worker = [&]() { -+ threads_ready++; -+ while (!start_flag.load(std::memory_order_acquire)) { -+ std::this_thread::yield(); -+ } -+ -+ for (int i = 0; i < kOpsPerThread; ++i) { -+ base::win::ScopedHandle handle( -+ ::CreateEvent(nullptr, FALSE, FALSE, nullptr)); -+ base::UnguessableToken token = -+ registry_->RegisterDCOMPSurfaceHandle(std::move(handle)); -+ { -+ base::AutoLock lock(tokens_lock); -+ tokens.push_back(token); -+ } -+ } -+ }; -+ -+ auto take_worker = [&]() { -+ threads_ready++; -+ while (!start_flag.load(std::memory_order_acquire)) { -+ std::this_thread::yield(); -+ } -+ -+ int taken = 0; -+ while (taken < kOpsPerThread) { -+ base::UnguessableToken token; -+ { -+ base::AutoLock lock(tokens_lock); -+ if (!tokens.empty()) { -+ token = tokens.back(); -+ tokens.pop_back(); -+ } -+ } -+ if (!token.is_empty()) { -+ base::win::ScopedHandle handle = -+ registry_->TakeDCOMPSurfaceHandle(token); -+ taken++; -+ } else { -+ std::this_thread::yield(); -+ } -+ } -+ }; -+ -+ // With the barrier pattern, two threads are sufficient to trigger -+ // the race condition for TSAN. -+ std::thread t1(register_worker); -+ std::thread t2(take_worker); -+ -+ // Wait until both threads are ready at the starting line. -+ while (threads_ready.load(std::memory_order_relaxed) < 2) { -+ std::this_thread::yield(); -+ } -+ -+ // Signal the staring flag to allow both threads to race from the initialized -+ // state. -+ start_flag.store(true, std::memory_order_release); -+ -+ t1.join(); -+ t2.join(); -+} -+ -+} // namespace gl diff --git a/patches/chromium/cherry-pick-c0390bcd64ba.patch b/patches/chromium/cherry-pick-c0390bcd64ba.patch index 3d5fdc3eeb..b76acc6b30 100644 --- a/patches/chromium/cherry-pick-c0390bcd64ba.patch +++ b/patches/chromium/cherry-pick-c0390bcd64ba.patch @@ -197,10 +197,10 @@ index 0000000000000000000000000000000000000000..b0f15909bebda29fc2ec689a6d3b15d7 + +} // namespace content diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn -index 4521cc9e247c44248627c12b9eda0961f837d744..6ea61eb47fcde420261a9dd7e7e3feefa31f87d2 100644 +index be51e4f3e5de4ed82ba2752293ea58a9a672128c..8e2354d7918c3d86dde086c6647cb0c2656ab3c3 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn -@@ -2680,6 +2680,7 @@ test("content_unittests") { +@@ -2681,6 +2681,7 @@ test("content_unittests") { "../browser/fenced_frame/redacted_fenced_frame_config_mojom_traits_unittest.cc", "../browser/file_system/browser_file_system_helper_unittest.cc", "../browser/file_system/file_system_operation_runner_unittest.cc", diff --git a/patches/chromium/cherry-pick-d513cd2fe668.patch b/patches/chromium/cherry-pick-d513cd2fe668.patch deleted file mode 100644 index 71a85092f6..0000000000 --- a/patches/chromium/cherry-pick-d513cd2fe668.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kenichi Ishibashi -Date: Fri, 10 Apr 2026 17:14:24 -0700 -Subject: [CORS] Block forbidden methods for no-cors requests - -Previously, forbidden methods like TRACE and TRACK were allowed when -the request mode was no-cors, and only CONNECT was unconditionally -blocked. - -This CL updates CorsURLLoaderFactory::IsValidRequest to block all -forbidden methods regardless of the request mode. The unit test is -also updated to reflect this new restriction. - -Bug: 498765210 -Change-Id: Ie451a3c2b8fa7aafdebade8b3ba517be3ce255f8 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7743444 -Reviewed-by: mmenke -Commit-Queue: Kenichi Ishibashi -Cr-Commit-Position: refs/heads/main@{#1613186} - -diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc -index 6a1eb075b0ed581bf81c43a0439da12eff20664c..bf02d6663b47413e47ebfe9ae4ba5799787f69ae 100644 ---- a/services/network/cors/cors_url_loader_factory.cc -+++ b/services/network/cors/cors_url_loader_factory.cc -@@ -910,13 +910,8 @@ bool CorsURLLoaderFactory::IsValidRequest( - return false; - } - -- // Don't allow forbidden methods for any requests except RequestMode::kNoCors. -- // Don't allow CONNECT method for any request. -- if ((request.mode != mojom::RequestMode::kNoCors && -- cors::IsForbiddenMethod(request.method)) || -- (request.mode == mojom::RequestMode::kNoCors && -- base::EqualsCaseInsensitiveASCII( -- request.method, net::HttpRequestHeaders::kConnectMethod))) { -+ // Don't allow forbidden methods. -+ if (cors::IsForbiddenMethod(request.method)) { - mojo::ReportBadMessage("CorsURLLoaderFactory: Forbidden method"); - return false; - } -diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc -index e9bbbc2013e6fb9498bec0982c045ea8b937a207..23a9e8093aa8d6cafb9a949d4a1dae86bd52a99d 100644 ---- a/services/network/cors/cors_url_loader_unittest.cc -+++ b/services/network/cors/cors_url_loader_unittest.cc -@@ -109,11 +109,10 @@ TEST_F(CorsURLLoaderTest, ForbiddenMethods) { - std::string forbidden_method; - bool expect_allowed_for_no_cors; - } kTestCases[] = { -- // CONNECT is never allowed, while TRACE and TRACK are allowed only with -- // RequestMode::kNoCors. -+ // CONNECT, TRACE and TRACK are not allowed for any mode. - {"CONNECT", false}, -- {"TRACE", true}, -- {"TRACK", true}, -+ {"TRACE", false}, -+ {"TRACK", false}, - }; - for (const auto& test_case : kTestCases) { - SCOPED_TRACE(test_case.forbidden_method); diff --git a/patches/chromium/cherry-pick-dc5e20c4c055.patch b/patches/chromium/cherry-pick-dc5e20c4c055.patch deleted file mode 100644 index 396dcb2137..0000000000 --- a/patches/chromium/cherry-pick-dc5e20c4c055.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sunny Sachanandani -Date: Wed, 8 Apr 2026 16:29:57 -0700 -Subject: [gpu] Fix OOB write due to unvalidated get_offset - -A compromised GPU process can provide an invalid get_offset to the -CommandBufferHelper (e.g., via shared memory). This offset is used to -calculate available space and could lead to out-of-bounds writes in the -Browser process if not validated. - -This change adds a bounds check in -CommandBufferHelper::UpdateCachedState to ensure that the cached -get_offset is within the valid range [0, total_entry_count_]. If an -invalid offset is detected, it forces a context loss, frees the ring -buffer, and marks the helper as unusable, preventing further operations. - -Bug: 498782145 -Test: CommandBufferHelperTest.* -Change-Id: I8c64e546ecdc90a5a22d15e57ff762a86a6a6964 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7739951 -Reviewed-by: Vasiliy Telezhnikov -Auto-Submit: Sunny Sachanandani -Commit-Queue: Sunny Sachanandani -Cr-Commit-Position: refs/heads/main@{#1611853} - -diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc -index ccda45b133c6a9f2ee60ccc8900bd4a4ce328394..5aea0c81b29b3507099f399c374f3cb372a3100e 100644 ---- a/gpu/command_buffer/client/cmd_buffer_helper.cc -+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc -@@ -158,6 +158,17 @@ void CommandBufferHelper::UpdateCachedState(const CommandBuffer::State& state) { - service_on_old_buffer_ = - (state.set_get_buffer_count != set_get_buffer_count_); - cached_get_offset_ = service_on_old_buffer_ ? 0 : state.get_offset; -+ -+ if (!service_on_old_buffer_ && -+ (cached_get_offset_ < 0 || cached_get_offset_ > total_entry_count_)) { -+ command_buffer_->ForceLostContext(error::kGuilty); -+ FreeRingBuffer(); -+ usable_ = false; -+ context_lost_ = true; -+ cached_get_offset_ = 0; // Safe fallback -+ return; -+ } -+ - cached_last_token_read_ = state.token; - // Don't transition from a lost context to a working context. - context_lost_ |= error::IsError(state.error); -diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc -index 5b1e5fae133ef75a99dab4ba1f8d2beddef68138..31e46714756ee30bf2fc3353693b6d49be8f6076 100644 ---- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc -+++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc -@@ -70,6 +70,8 @@ class CommandBufferHelperTest : public testing::Test { - return helper_->immediate_entry_count_; - } - -+ int32_t TotalEntryCount() const { return helper_->total_entry_count_; } -+ - // Adds a command to the buffer through the helper, while adding it as an - // expected call on the API mock. - void AddCommandWithExpect(error::Error _return, -@@ -655,6 +657,17 @@ TEST_F(CommandBufferHelperTest, IsContextLost) { - EXPECT_TRUE(helper_->IsContextLost()); - } - -+TEST_F(CommandBufferHelperTest, TestInvalidGetOffset) { -+ EXPECT_FALSE(helper_->IsContextLost()); -+ EXPECT_TRUE(helper_->usable()); -+ -+ command_buffer_->SetGetOffsetForTest(TotalEntryCount() + 1); -+ helper_->RefreshCachedToken(); // calls UpdateCachedState internally. -+ -+ EXPECT_TRUE(helper_->IsContextLost()); -+ EXPECT_FALSE(helper_->usable()); -+} -+ - // Checks helper's 'flush generation' updates. - TEST_F(CommandBufferHelperTest, TestFlushGeneration) { - // Explicit flushing only. diff --git a/patches/chromium/cherry-pick-fc79e8cc2dfc.patch b/patches/chromium/cherry-pick-fc79e8cc2dfc.patch deleted file mode 100644 index 274b359afa..0000000000 --- a/patches/chromium/cherry-pick-fc79e8cc2dfc.patch +++ /dev/null @@ -1,368 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eugene Zemtsov -Date: Wed, 8 Apr 2026 18:32:31 -0700 -Subject: media: Zero-copy VP9 alpha decoding in VpxVideoDecoder - -Configures the VP9 alpha decoder to use `memory_pool_` for external -frame buffers, eliminating the need for `libyuv::CopyPlane`. - -The `VideoFrame` now wraps the alpha data directly from the pool using -a second destruction observer. `AllocateAlphaPlaneForFrameBuffer` and -`alpha_data` tracking are removed from `FrameBufferPool`. - -Bug: 500066234 -Change-Id: I6e7cf13bcc8a5a1759acfd51961859c4c57fcbf2 -Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7737984 -Reviewed-by: Ted (Chromium) Meyer -Commit-Queue: Eugene Zemtsov -Reviewed-by: Dale Curtis -Cr-Commit-Position: refs/heads/main@{#1611919} - -diff --git a/media/base/frame_buffer_pool.cc b/media/base/frame_buffer_pool.cc -index ceb0313c1fa36483ac545a6440737da035a1224c..59bc0790178aa2eb2e6960ef396c96ae18bbba09 100644 ---- a/media/base/frame_buffer_pool.cc -+++ b/media/base/frame_buffer_pool.cc -@@ -56,7 +56,6 @@ struct FrameBufferPool::FrameBuffer { - // Not using std::vector as resize() calls take a really long time - // for large buffers. - BytesArray data; -- BytesArray alpha_data; - bool held_by_library = false; - // Needs to be a counter since a frame buffer might be used multiple times. - int held_by_frame = 0; -@@ -155,24 +154,6 @@ void FrameBufferPool::ReleaseFrameBuffer(void* fb_priv) { - } - } - --base::span FrameBufferPool::AllocateAlphaPlaneForFrameBuffer( -- size_t min_size, -- void* fb_priv) { -- base::AutoLock lock(lock_); -- DCHECK(fb_priv); -- -- auto* frame_buffer = static_cast(fb_priv); -- DCHECK(IsUsedLocked(frame_buffer)); -- if (frame_buffer->alpha_data.size() < min_size) { -- // Free the existing |alpha_data| first so that the memory can be reused, -- // if possible. -- frame_buffer->alpha_data = {}; -- frame_buffer->alpha_data = AllocateMemory(min_size, zero_initialize_memory_, -- force_allocation_error_); -- } -- return frame_buffer->alpha_data; --} -- - base::OnceClosure FrameBufferPool::CreateFrameCallback(void* fb_priv) { - base::AutoLock lock(lock_); - -@@ -210,10 +191,9 @@ bool FrameBufferPool::OnMemoryDump( - size_t bytes_reserved = 0; - for (const auto& frame_buffer : frame_buffers_) { - if (IsUsedLocked(frame_buffer.get())) { -- bytes_used += frame_buffer->data.size() + frame_buffer->alpha_data.size(); -+ bytes_used += frame_buffer->data.size(); - } -- bytes_reserved += -- frame_buffer->data.size() + frame_buffer->alpha_data.size(); -+ bytes_reserved += frame_buffer->data.size(); - } - - memory_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, -diff --git a/media/base/frame_buffer_pool.h b/media/base/frame_buffer_pool.h -index ac839b8e8bfa00d2fea203be5248a56f04cecc71..2ccb01676b0e8e1e3ca1b3cb60f2883538f2f13c 100644 ---- a/media/base/frame_buffer_pool.h -+++ b/media/base/frame_buffer_pool.h -@@ -48,11 +48,6 @@ class MEDIA_EXPORT FrameBufferPool - // Called when a frame buffer allocation is no longer needed. - void ReleaseFrameBuffer(void* fb_priv); - -- // Allocates (or reuses) room for an alpha plane on a given frame buffer. -- // |fb_priv| must be a value previously returned by GetFrameBuffer(). -- base::span AllocateAlphaPlaneForFrameBuffer(size_t min_size, -- void* fb_priv); -- - // Generates a "no_longer_needed" closure that holds a reference to this pool; - // |fb_priv| must be a value previously returned by GetFrameBuffer(). The - // callback may be called on any thread. -diff --git a/media/base/frame_buffer_pool_unittest.cc b/media/base/frame_buffer_pool_unittest.cc -index 893e941f9f9b6d7eaff98b3e9ae4278861a2b0fd..8b50896e7544e34589614216373b566598b30ec6 100644 ---- a/media/base/frame_buffer_pool_unittest.cc -+++ b/media/base/frame_buffer_pool_unittest.cc -@@ -32,12 +32,6 @@ TEST(FrameBufferPool, BasicFunctionality) { - EXPECT_NE(buf1.data(), buf2.data()); - std::ranges::fill(buf2, 0); - -- auto alpha = pool->AllocateAlphaPlaneForFrameBuffer(kBufferSize, priv1); -- ASSERT_FALSE(alpha.empty()); -- EXPECT_NE(alpha.data(), buf1.data()); -- EXPECT_NE(alpha.data(), buf2.data()); -- std::ranges::fill(alpha, 0); -- - EXPECT_EQ(2u, pool->get_pool_size_for_testing()); - - // Frames are not released immediately, so this should still show two frames. -@@ -52,7 +46,6 @@ TEST(FrameBufferPool, BasicFunctionality) { - EXPECT_EQ(1u, pool->get_pool_size_for_testing()); - - std::ranges::fill(buf1, 0); -- std::ranges::fill(alpha, 0); - - // This will release all memory since we're in the shutdown state. - std::move(frame_release_cb).Run(); -@@ -132,13 +125,6 @@ TEST(FrameBufferPool, DoesClearAllocations) { - } - EXPECT_FALSE(nonzero); - -- auto alpha_buf = pool->AllocateAlphaPlaneForFrameBuffer(kBufferSize, priv1); -- nonzero = false; -- for (size_t i = 0; i < kBufferSize; i++) { -- nonzero |= !!alpha_buf[i]; -- } -- EXPECT_FALSE(nonzero); -- - pool->Shutdown(); - } - -diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc -index ca1e45ed3cddcbf878f03c233f982b04425287f5..fe1b8b9b0686ed0b89737097087fca00cb1677c6 100644 ---- a/media/filters/vpx_video_decoder.cc -+++ b/media/filters/vpx_video_decoder.cc -@@ -250,7 +250,21 @@ bool VpxVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) { - - DCHECK(!vpx_codec_alpha_); - vpx_codec_alpha_ = InitializeVpxContext(config); -- return !!vpx_codec_alpha_; -+ if (!vpx_codec_alpha_) { -+ return false; -+ } -+ -+ if (config.codec() == VideoCodec::kVP9) { -+ if (vpx_codec_set_frame_buffer_functions( -+ vpx_codec_alpha_.get(), &GetVP9FrameBuffer, &ReleaseVP9FrameBuffer, -+ memory_pool_.get())) { -+ DLOG(ERROR) << "Failed to configure external buffers for alpha. " -+ << vpx_codec_error(vpx_codec_alpha_.get()); -+ return false; -+ } -+ } -+ -+ return true; - } - - void VpxVideoDecoder::CloseDecoder() { -@@ -546,20 +560,13 @@ bool VpxVideoDecoder::CopyVpxImageToVideoFrame( - if (memory_pool_) { - DCHECK_EQ(VideoCodec::kVP9, config_.codec()); - if (vpx_image_alpha) { -+ CHECK_GT(vpx_image_alpha->stride[VPX_PLANE_Y], 0); - size_t alpha_plane_size = - vpx_image_alpha->stride[VPX_PLANE_Y] * vpx_image_alpha->d_h; -- auto alpha_plane = memory_pool_->AllocateAlphaPlaneForFrameBuffer( -- alpha_plane_size, vpx_image->fb_priv); -- if (alpha_plane.empty()) { -- error_status_ = DecoderStatus::Codes::kOutOfMemory; -- // In case of OOM, abort copy. -- return false; -- } -- libyuv::CopyPlane(vpx_image_alpha->planes[VPX_PLANE_Y], -- vpx_image_alpha->stride[VPX_PLANE_Y], -- alpha_plane.data(), -- vpx_image_alpha->stride[VPX_PLANE_Y], -- vpx_image_alpha->d_w, vpx_image_alpha->d_h); -+ // SAFETY: libvpx guarantees that the Y plane has at least `stride * d_h` -+ // bytes available. -+ auto alpha_plane = UNSAFE_BUFFERS(base::span( -+ vpx_image_alpha->planes[VPX_PLANE_Y], alpha_plane_size)); - *video_frame = VideoFrame::WrapExternalYuvaData( - codec_format, coded_size, gfx::Rect(visible_size), natural_size, - vpx_image->stride[VPX_PLANE_Y], vpx_image->stride[VPX_PLANE_U], -@@ -575,8 +582,14 @@ bool VpxVideoDecoder::CopyVpxImageToVideoFrame( - if (!(*video_frame)) - return false; - -- video_frame->get()->AddDestructionObserver( -- memory_pool_->CreateFrameCallback(vpx_image->fb_priv)); -+ (*video_frame) -+ ->AddDestructionObserver( -+ memory_pool_->CreateFrameCallback(vpx_image->fb_priv)); -+ if (vpx_image_alpha) { -+ (*video_frame) -+ ->AddDestructionObserver( -+ memory_pool_->CreateFrameCallback(vpx_image_alpha->fb_priv)); -+ } - return true; - } - -diff --git a/media/filters/vpx_video_decoder.h b/media/filters/vpx_video_decoder.h -index f53da976ba4ba9dc39c6f03c99d5937b82650399..8f8f07e419b7d16c52f550edd97af6f235fbd2ac 100644 ---- a/media/filters/vpx_video_decoder.h -+++ b/media/filters/vpx_video_decoder.h -@@ -102,8 +102,8 @@ class MEDIA_EXPORT VpxVideoDecoder : public OffloadableVideoDecoder { - std::unique_ptr vpx_codec_; - std::unique_ptr vpx_codec_alpha_; - -- // |memory_pool_| is a single-threaded memory pool used for VP9 decoding -- // with no alpha. |frame_pool_| is used for all other cases. -+ // |memory_pool_| is a thread-safe memory pool used for zero-copy VP9 decoding -+ // (both with and without alpha). |frame_pool_| is used for VP8. - scoped_refptr memory_pool_; - VideoFramePool frame_pool_; - -diff --git a/media/filters/vpx_video_decoder_unittest.cc b/media/filters/vpx_video_decoder_unittest.cc -index 8fba2b469656c7bd60b555bf6dea02b7b37ee701..bb32fa8e7d59f5a3136a48a2ef14dda08a95fff0 100644 ---- a/media/filters/vpx_video_decoder_unittest.cc -+++ b/media/filters/vpx_video_decoder_unittest.cc -@@ -175,6 +175,28 @@ class VpxVideoDecoderTest : public testing::Test { - output_frames_.push_back(std::move(frame)); - } - -+ // Extracts the compressed video data from the AVPacket and also checks for -+ // side data containing an alpha channel. If found, it copies the alpha data -+ // into the DecoderBuffer's side data. This is necessary because FFmpeg -+ // demuxes alpha channel data as side data associated with the video packet. -+ static scoped_refptr CreateBufferWithAlphaFromPacket( -+ const AVPacket* packet) { -+ auto buffer = DecoderBuffer::CopyFrom(AVPacketData(*packet)); -+ size_t side_data_size = 0; -+ uint8_t* side_data_ptr = av_packet_get_side_data( -+ packet, AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size); -+ if (side_data_size > 8) { -+ // SAFETY: The best we can do here is trust the size reported by ffmpeg. -+ auto side_data = -+ UNSAFE_BUFFERS(base::span(side_data_ptr, side_data_size)); -+ if (base::U64FromBigEndian(side_data.first<8u>()) == 1) { -+ buffer->WritableSideData().alpha_data = -+ base::HeapArray::CopiedFrom(side_data.subspan(8u)); -+ } -+ } -+ return buffer; -+ } -+ - MOCK_METHOD1(DecodeDone, void(DecoderStatus)); - - base::test::TaskEnvironment task_env_; -@@ -292,6 +314,68 @@ TEST_F(VpxVideoDecoderTest, SimpleFrameReuse) { - EXPECT_EQ(old_y_data, output_frames_.back()->data(VideoFrame::Plane::kY)); - } - -+TEST_F(VpxVideoDecoderTest, SimpleAlphaFrameReuse) { -+ VideoDecoderConfig config = TestVideoConfig::Normal(VideoCodec::kVP9); -+ config.Initialize( -+ config.codec(), config.profile(), -+ VideoDecoderConfig::AlphaMode::kHasAlpha, config.color_space_info(), -+ config.video_transformation(), config.coded_size(), config.visible_rect(), -+ config.natural_size(), config.extra_data(), config.encryption_scheme()); -+ InitializeWithConfig(config); -+ scoped_refptr alpha_frame = ReadTestDataFile("bear-vp9a.webm"); -+ -+ // Read frames from the webm file. -+ InMemoryUrlProtocol protocol(*alpha_frame, false); -+ FFmpegGlue glue(&protocol); -+ ASSERT_TRUE(glue.OpenContext()); -+ -+ auto packet = ScopedAVPacket::Allocate(); -+ -+ // Decode first frame -+ ASSERT_GE(av_read_frame(glue.format_context(), packet.get()), 0); -+ auto buffer = CreateBufferWithAlphaFromPacket(packet.get()); -+ Decode(buffer); -+ av_packet_unref(packet.get()); -+ -+ ASSERT_EQ(1u, output_frames_.size()); -+ scoped_refptr frame = std::move(output_frames_.front()); -+ EXPECT_EQ(PIXEL_FORMAT_I420A, frame->format()); -+ const uint8_t* old_y_data = frame->data(VideoFrame::Plane::kY); -+ const uint8_t* old_a_data = frame->data(VideoFrame::Plane::kA); -+ output_frames_.pop_back(); -+ -+ // Clear frame reference to return the frame to the pool. -+ frame = nullptr; -+ -+ // Decode second frame. -+ Decode(buffer); -+ const uint8_t* mid_y_data = -+ output_frames_.front()->data(VideoFrame::Plane::kY); -+ const uint8_t* mid_a_data = -+ output_frames_.front()->data(VideoFrame::Plane::kA); -+ output_frames_.clear(); -+ -+ // Issuing another decode should reuse buffers from the pool. -+ Decode(buffer); -+ -+ ASSERT_EQ(1u, output_frames_.size()); -+ const uint8_t* new_y_data = -+ output_frames_.back()->data(VideoFrame::Plane::kY); -+ const uint8_t* new_a_data = -+ output_frames_.back()->data(VideoFrame::Plane::kA); -+ -+ // The pool is shared, so buffers might be reused in a different order (e.g. Y -+ // might get the buffer previously used for A). Because libvpx allocates the -+ // new frame before releasing the old reference frame, we need to check across -+ // all previously allocated buffers. -+ bool reused_y = new_y_data == old_y_data || new_y_data == old_a_data || -+ new_y_data == mid_y_data || new_y_data == mid_a_data; -+ bool reused_a = new_a_data == old_y_data || new_a_data == old_a_data || -+ new_a_data == mid_y_data || new_a_data == mid_a_data; -+ EXPECT_TRUE(reused_y); -+ EXPECT_TRUE(reused_a); -+} -+ - TEST_F(VpxVideoDecoderTest, SimpleFormatChange) { - scoped_refptr large_frame = - ReadTestDataFile("vp9-I-frame-1280x720"); -@@ -311,10 +395,41 @@ TEST_F(VpxVideoDecoderTest, FrameValidAfterPoolDestruction) { - - // Write to the Y plane. The memory tools should detect a - // use-after-free if the storage was actually removed by pool destruction. -- UNSAFE_TODO( -- memset(output_frames_.front()->writable_data(VideoFrame::Plane::kY), 0xff, -- output_frames_.front()->rows(VideoFrame::Plane::kY) * -- output_frames_.front()->stride(VideoFrame::Plane::kY))); -+ std::ranges::fill( -+ output_frames_.front()->writable_span(VideoFrame::Plane::kY), 0xff); -+} -+ -+TEST_F(VpxVideoDecoderTest, AlphaFrameValidAfterPoolDestruction) { -+ VideoDecoderConfig config = TestVideoConfig::Normal(VideoCodec::kVP9); -+ config.Initialize( -+ config.codec(), config.profile(), -+ VideoDecoderConfig::AlphaMode::kHasAlpha, config.color_space_info(), -+ config.video_transformation(), config.coded_size(), config.visible_rect(), -+ config.natural_size(), config.extra_data(), config.encryption_scheme()); -+ InitializeWithConfig(config); -+ scoped_refptr alpha_frame = ReadTestDataFile("bear-vp9a.webm"); -+ -+ InMemoryUrlProtocol protocol(*alpha_frame, false); -+ FFmpegGlue glue(&protocol); -+ ASSERT_TRUE(glue.OpenContext()); -+ -+ auto packet = ScopedAVPacket::Allocate(); -+ ASSERT_GE(av_read_frame(glue.format_context(), packet.get()), 0); -+ auto buffer = CreateBufferWithAlphaFromPacket(packet.get()); -+ Decode(std::move(buffer)); -+ av_packet_unref(packet.get()); -+ -+ ASSERT_EQ(1u, output_frames_.size()); -+ EXPECT_EQ(PIXEL_FORMAT_I420A, output_frames_.front()->format()); -+ -+ Destroy(); -+ -+ // Write to the Y and A planes. The memory tools should detect a -+ // use-after-free if the storage was actually removed by pool destruction. -+ std::ranges::fill( -+ output_frames_.front()->writable_span(VideoFrame::Plane::kY), 0xff); -+ std::ranges::fill( -+ output_frames_.front()->writable_span(VideoFrame::Plane::kA), 0xff); - } - - // The test stream uses profile 2, which needs high bit depth support in libvpx. -@@ -362,8 +477,7 @@ TEST_F(VpxVideoDecoderTest, MemoryPoolAllowsMultipleDisplay) { - Destroy(); - - // ASAN will be very unhappy with this line if the above is incorrect. -- UNSAFE_TODO(memset(last_frame->writable_data(VideoFrame::Plane::kY), 0, -- last_frame->row_bytes(VideoFrame::Plane::kY))); -+ std::ranges::fill(last_frame->writable_span(VideoFrame::Plane::kY), 0); - } - #endif // !defined(LIBVPX_NO_HIGH_BIT_DEPTH) && !defined(ARCH_CPU_ARM_FAMILY) - diff --git a/patches/chromium/expose_setuseragent_on_networkcontext.patch b/patches/chromium/expose_setuseragent_on_networkcontext.patch index 33f8d8f926..68c34bec66 100644 --- a/patches/chromium/expose_setuseragent_on_networkcontext.patch +++ b/patches/chromium/expose_setuseragent_on_networkcontext.patch @@ -33,10 +33,10 @@ index 0ab8187b0db8ae6db46d81738f653a2bc4c566f6..de3d55e85c22317f7f9375eb94d0d5d4 } // namespace net diff --git a/services/network/network_context.cc b/services/network/network_context.cc -index cf1001557f2f59747ceb394ab2c93b4bf379dafb..2e16a8d19e1ccfbfc838ed33ecac3375f1e81b17 100644 +index f19c3cf6e7e50098c6fe3cda1f6db3bcc1fe7e90..fd0ef3275b205e94e3fa1914d4e64023cdf702dd 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc -@@ -1994,6 +1994,13 @@ void NetworkContext::SetNetworkConditions( +@@ -1993,6 +1993,13 @@ void NetworkContext::SetNetworkConditions( std::move(network_conditions)); } @@ -51,7 +51,7 @@ index cf1001557f2f59747ceb394ab2c93b4bf379dafb..2e16a8d19e1ccfbfc838ed33ecac3375 // This may only be called on NetworkContexts created with the constructor // that calls MakeURLRequestContext(). diff --git a/services/network/network_context.h b/services/network/network_context.h -index 04e6e884dccbb680a39f2b9c8a54de162e056a30..672dd48040586190b761e2db554ba0767d254f62 100644 +index 8d0a055792936286c96047b9a70670f93e2ae5b1..dad6a445ee3f6a0eb3d55d29fae643bde5bf706d 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h @@ -332,6 +332,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext diff --git a/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch b/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch index 226799fb61..23deb0fe34 100644 --- a/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch +++ b/patches/chromium/feat_corner_smoothing_css_rule_and_blink_painting.patch @@ -314,7 +314,7 @@ index 18f283e625101318ee14b50e6e765dfd1c9a1a44..44a3a55974c9e4b9e715574075f25661 auto DrawAsSinglePath = [&]() { diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 -index 89301f737c6a1f4043a47366db604967159b7cb6..0f6417f6933f3f71f39b4a06ac229efd3ac7634b 100644 +index e35efdeaa064e185dcd31822be2d077bd4add7db..9c207b3927535ceeecb6f73a36f51566500c9ebb 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5 @@ -215,6 +215,10 @@ diff --git a/patches/chromium/feat_enable_offscreen_rendering_with_viz_compositor.patch b/patches/chromium/feat_enable_offscreen_rendering_with_viz_compositor.patch index 051affa5dc..d70bb3cd00 100644 --- a/patches/chromium/feat_enable_offscreen_rendering_with_viz_compositor.patch +++ b/patches/chromium/feat_enable_offscreen_rendering_with_viz_compositor.patch @@ -619,7 +619,7 @@ index 2f462f0deb5fc8a637457243fb5d5849fc214d14..695869b83cefaa24af93a2e11b39de05 + Draw(gfx.mojom.Rect damage_rect) => (); }; diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h -index 97f26777528c3b21255b74ccf411ff2d3b243215..d45839ebc7b07ade2ca382e15b1d48dcf7d29106 100644 +index fbe5a8e6458970652723f91a426541220b394a18..c2e748b92103c582802af9b973ebe0c3770ba44d 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h @@ -89,6 +89,7 @@ class DisplayPrivate; @@ -656,7 +656,7 @@ index 97f26777528c3b21255b74ccf411ff2d3b243215..d45839ebc7b07ade2ca382e15b1d48dc // Sets the root of the layer tree drawn by this Compositor. The root layer // must have no parent. The compositor's root layer is reset if the root layer // is destroyed. NULL can be passed to reset the root layer, in which case the -@@ -632,6 +645,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver, +@@ -631,6 +644,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver, simple_begin_frame_observers_; std::unique_ptr host_begin_frame_observer_; diff --git a/patches/chromium/fix_crash_loading_non-standard_schemes_in_iframes.patch b/patches/chromium/fix_crash_loading_non-standard_schemes_in_iframes.patch index 3e38236dc2..16920adf54 100644 --- a/patches/chromium/fix_crash_loading_non-standard_schemes_in_iframes.patch +++ b/patches/chromium/fix_crash_loading_non-standard_schemes_in_iframes.patch @@ -28,10 +28,10 @@ The patch should be removed in favor of either: Upstream bug https://bugs.chromium.org/p/chromium/issues/detail?id=1081397. diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc -index 7532fbb742624d86c342df29a7621867fa99180b..45cbb6bcaf16307a6949473ddb62a2be95031199 100644 +index e321b9acde92b212dd9591a2e72868a2ad64406b..1150972064845f46717e1c184e4dde911bc1a019 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc -@@ -11915,6 +11915,11 @@ url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() { +@@ -11929,6 +11929,11 @@ url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() { target_rph_id); } @@ -44,7 +44,7 @@ index 7532fbb742624d86c342df29a7621867fa99180b..45cbb6bcaf16307a6949473ddb62a2be // origin of |common_params.url| and/or |common_params.initiator_origin|. url::Origin resolved_origin = url::Origin::Resolve( diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc -index 1fd466b975fc5347e01bf5f6368e0b4fe89f7c5f..b77eb4ae99103d84ac6f1cb53fd1fe94814c7d05 100644 +index b98cf42ff36bbdbb65e59cd6cae1d0db02472319..ab65d53255cfea81a1a27849cd41f2d37e2d514d 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc @@ -2357,6 +2357,7 @@ Frame* DocumentLoader::CalculateOwnerFrame() { diff --git a/patches/chromium/fix_disabling_background_throttling_in_compositor.patch b/patches/chromium/fix_disabling_background_throttling_in_compositor.patch index 985bbbbac1..22cdaa1f92 100644 --- a/patches/chromium/fix_disabling_background_throttling_in_compositor.patch +++ b/patches/chromium/fix_disabling_background_throttling_in_compositor.patch @@ -53,10 +53,10 @@ index 3aec78e17de2012689c813145f78226867ac879a..5cb8f51c9ef6ac098629970d195eb593 void Compositor::SetSeamlessRefreshRates( const std::vector& seamless_refresh_rates) { diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h -index d45839ebc7b07ade2ca382e15b1d48dcf7d29106..2c24993f1a509856966bb4a1302db97d976ad4ba 100644 +index c2e748b92103c582802af9b973ebe0c3770ba44d..b36dfec6bec2009b7761ec4ce3739a7f50f1196b 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h -@@ -516,6 +516,10 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver, +@@ -515,6 +515,10 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver, const cc::LayerTreeSettings& GetLayerTreeSettings() const; @@ -67,7 +67,7 @@ index d45839ebc7b07ade2ca382e15b1d48dcf7d29106..2c24993f1a509856966bb4a1302db97d size_t saved_events_metrics_count_for_testing() const { return host_->saved_events_metrics_count_for_testing(); } -@@ -732,6 +736,12 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver, +@@ -731,6 +735,12 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver, // See go/report-ux-metrics-at-painting for details. bool animation_started_ = false; diff --git a/patches/chromium/fix_return_v8_value_from_localframe_requestexecutescript.patch b/patches/chromium/fix_return_v8_value_from_localframe_requestexecutescript.patch index 037a037557..e0ea7fe158 100644 --- a/patches/chromium/fix_return_v8_value_from_localframe_requestexecutescript.patch +++ b/patches/chromium/fix_return_v8_value_from_localframe_requestexecutescript.patch @@ -211,7 +211,7 @@ index f2c94689450f0333a144ccf82cf147c194896e6b..1c2e9fe36c297f7d614d9ca290e4d13c const mojom::blink::UserActivationOption user_activation_option_; const mojom::blink::LoadEventBlockingOption blocking_option_; diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc -index 7d4039de028e6c7ef87e93792961c338032b261d..41d0a336dc4c91c74c57383f9203f7bca7675b66 100644 +index 9107414c2c689b7d1cb51b0eb861425d275d9cf1..b7fed34978a207d195af371a9c5bde02d19ee664 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc @@ -300,6 +300,7 @@ void ExecuteScriptsInMainWorld( diff --git a/patches/chromium/frame_host_manager.patch b/patches/chromium/frame_host_manager.patch index b44ac58e16..fc30e7b640 100644 --- a/patches/chromium/frame_host_manager.patch +++ b/patches/chromium/frame_host_manager.patch @@ -6,10 +6,10 @@ Subject: frame_host_manager.patch Allows embedder to intercept site instances created by chromium. diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc -index f9179c9f42b16b5c73b7102700410f2d1b83aeab..abce85bb4fb63d1662bbc9ad28a1047f97c6d3c4 100644 +index 25ee8cf3da9ffbef6798548cc458f74e41b97fdd..32dcee38dde1587596d24d1433fcdeb310fca4b6 100644 --- a/content/browser/renderer_host/render_frame_host_manager.cc +++ b/content/browser/renderer_host/render_frame_host_manager.cc -@@ -4913,6 +4913,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest( +@@ -4915,6 +4915,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest( request->ResetStateForSiteInstanceChange(); } diff --git a/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch b/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch index 0f50f92266..5f0e9bdd42 100644 --- a/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch +++ b/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch @@ -1209,7 +1209,7 @@ index a1068589ad844518038ee7bc15a3de9bc5cba525..1ff781c49f086ec8015c7d3c44567dbe } // namespace content diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn -index ec792aa7e050550721cd221bfe8ff335e22e90ef..4521cc9e247c44248627c12b9eda0961f837d744 100644 +index 19f17632aecf606bf7b39cf1a2fda068e10ddfec..be51e4f3e5de4ed82ba2752293ea58a9a672128c 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn @@ -701,6 +701,7 @@ static_library("test_support") { @@ -1229,7 +1229,7 @@ index ec792aa7e050550721cd221bfe8ff335e22e90ef..4521cc9e247c44248627c12b9eda0961 } mojom("content_test_mojo_bindings") { -@@ -2078,6 +2081,7 @@ test("content_browsertests") { +@@ -2079,6 +2082,7 @@ test("content_browsertests") { "//ui/shell_dialogs", "//ui/snapshot", "//ui/webui:test_support", @@ -1237,7 +1237,7 @@ index ec792aa7e050550721cd221bfe8ff335e22e90ef..4521cc9e247c44248627c12b9eda0961 ] if (!(is_chromeos && target_cpu == "arm64" && current_cpu == "arm")) { -@@ -3446,6 +3450,7 @@ test("content_unittests") { +@@ -3447,6 +3451,7 @@ test("content_unittests") { "//ui/shell_dialogs", "//ui/webui:test_support", "//url", diff --git a/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch b/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch index c3e2fa0500..8a3051a1ae 100644 --- a/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch +++ b/patches/chromium/network_service_allow_remote_certificate_verification_logic.patch @@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement session.setCertificateVerifyCallback. diff --git a/services/network/network_context.cc b/services/network/network_context.cc -index 68b3acc5a4e67fee975fd982f252cbf46c28ccac..cf1001557f2f59747ceb394ab2c93b4bf379dafb 100644 +index 1f070b2d00e2b0848939433172066b735702c596..f19c3cf6e7e50098c6fe3cda1f6db3bcc1fe7e90 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc @@ -173,6 +173,11 @@ @@ -148,7 +148,7 @@ index 68b3acc5a4e67fee975fd982f252cbf46c28ccac..cf1001557f2f59747ceb394ab2c93b4b void NetworkContext::CreateURLLoaderFactory( mojo::PendingReceiver receiver, mojom::URLLoaderFactoryParamsPtr params) { -@@ -2800,6 +2917,10 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext( +@@ -2799,6 +2916,10 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext( cert_verifier = std::make_unique( std::make_unique( std::move(cert_verifier))); @@ -160,7 +160,7 @@ index 68b3acc5a4e67fee975fd982f252cbf46c28ccac..cf1001557f2f59747ceb394ab2c93b4b builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier( diff --git a/services/network/network_context.h b/services/network/network_context.h -index 54a5feca1fbec658039826304f27283bd9d9c15a..04e6e884dccbb680a39f2b9c8a54de162e056a30 100644 +index 911b03040d084dc14c9b1f4b8ebe79dfff3e4ead..8d0a055792936286c96047b9a70670f93e2ae5b1 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h @@ -122,6 +122,7 @@ class SimpleUrlPatternMatcher; @@ -180,7 +180,7 @@ index 54a5feca1fbec658039826304f27283bd9d9c15a..04e6e884dccbb680a39f2b9c8a54de16 void ResetURLLoaderFactories() override; void GetViaObliviousHttp( mojom::ObliviousHttpRequestPtr request, -@@ -1002,6 +1005,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext +@@ -1004,6 +1007,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext std::vector dismount_closures_; #endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED) diff --git a/patches/chromium/notification_provenance.patch b/patches/chromium/notification_provenance.patch index ff97379ca7..4a62daca7f 100644 --- a/patches/chromium/notification_provenance.patch +++ b/patches/chromium/notification_provenance.patch @@ -133,10 +133,10 @@ index 9bf238e64af483294ae3c3f18a4e9aed49a8658d..b9b2a4c8c387b8e8b4eb1f02fc0f891c const GURL& document_url, const WeakDocumentPtr& weak_document_ptr, diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc -index bdf3d9ca4192818a33438dde4dd23ba40996bf00..3d7ccd3becf0ff3cc7003b9159dec7765d5f82c6 100644 +index f23e46639380c47e2da7681ac3273f9712755be6..d703187dda67bab4804dc619a0562de4d75ff2ff 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc -@@ -2385,7 +2385,7 @@ void RenderProcessHostImpl::CreateNotificationService( +@@ -2389,7 +2389,7 @@ void RenderProcessHostImpl::CreateNotificationService( case RenderProcessHost::NotificationServiceCreatorType::kSharedWorker: case RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker: { storage_partition_impl_->GetPlatformNotificationContext()->CreateService( @@ -145,7 +145,7 @@ index bdf3d9ca4192818a33438dde4dd23ba40996bf00..3d7ccd3becf0ff3cc7003b9159dec776 creator_type, std::move(receiver)); break; } -@@ -2393,7 +2393,7 @@ void RenderProcessHostImpl::CreateNotificationService( +@@ -2397,7 +2397,7 @@ void RenderProcessHostImpl::CreateNotificationService( CHECK(rfh); storage_partition_impl_->GetPlatformNotificationContext()->CreateService( diff --git a/patches/chromium/support_mixed_sandbox_with_zygote.patch b/patches/chromium/support_mixed_sandbox_with_zygote.patch index eedce664ea..7e18d76fdd 100644 --- a/patches/chromium/support_mixed_sandbox_with_zygote.patch +++ b/patches/chromium/support_mixed_sandbox_with_zygote.patch @@ -22,10 +22,10 @@ However, the patch would need to be reviewed by the security team, as it does touch a security-sensitive class. diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc -index 3d7ccd3becf0ff3cc7003b9159dec7765d5f82c6..5cf51c7984697b1a79048338516e1d7e1cc9dc4b 100644 +index d703187dda67bab4804dc619a0562de4d75ff2ff..a5d1bafd8944afd9588d18ae8896c09f3bbce7f9 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc -@@ -1955,6 +1955,10 @@ bool RenderProcessHostImpl::Init() { +@@ -1957,6 +1957,10 @@ bool RenderProcessHostImpl::Init() { std::unique_ptr sandbox_delegate = std::make_unique( *cmd_line, IsPdf(), IsJitDisabled()); diff --git a/patches/chromium/webview_fullscreen.patch b/patches/chromium/webview_fullscreen.patch index 853bf3ada0..cf1d93f4de 100644 --- a/patches/chromium/webview_fullscreen.patch +++ b/patches/chromium/webview_fullscreen.patch @@ -15,10 +15,10 @@ Note that we also need to manually update embedder's `api::WebContents::IsFullscreenForTabOrPending` value. diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc -index e4ff8f11bed9e53f3134068492ac94b4c9bb4df2..17c3b5c78c3ef08e0b901f3ace8bb07ee78e4cab 100644 +index d3a9d1b30dbbf7952203f0c93a068f493550fa79..546b5a14b9d5923e0a9e7b231041b937dbd71560 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc -@@ -9260,6 +9260,17 @@ void RenderFrameHostImpl::EnterFullscreen( +@@ -9274,6 +9274,17 @@ void RenderFrameHostImpl::EnterFullscreen( } } diff --git a/patches/chromium/worker_context_will_destroy.patch b/patches/chromium/worker_context_will_destroy.patch index 0413e3d012..3d61ac465a 100644 --- a/patches/chromium/worker_context_will_destroy.patch +++ b/patches/chromium/worker_context_will_destroy.patch @@ -26,7 +26,7 @@ index 1f6c015c361b3146db760643e3670a110634d75b..d4d9c10d3420a5ff998aeb593ea6a255 // An empty URL is returned if the URL is not overriden. virtual GURL OverrideFlashEmbedWithHTML(const GURL& url); diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc -index 416d53d0cce178de992074b0c0371bca2e4ed900..cd0e4d7ea77ffe9fd09982ef2d9f5d57df8e2995 100644 +index 23a05a16b40b859465f7953aef8052686cbeece9..10c2a75c7106b4803d53bec02c9c347a3ca28cfe 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc @@ -935,6 +935,12 @@ void RendererBlinkPlatformImpl::WillStopWorkerThread() { diff --git a/patches/chromium/worker_feat_add_hook_to_notify_script_ready.patch b/patches/chromium/worker_feat_add_hook_to_notify_script_ready.patch index 97ca2166cc..4a94fa829c 100644 --- a/patches/chromium/worker_feat_add_hook_to_notify_script_ready.patch +++ b/patches/chromium/worker_feat_add_hook_to_notify_script_ready.patch @@ -35,7 +35,7 @@ index d4d9c10d3420a5ff998aeb593ea6a25556d1215e..d64fef6bfc37264dcdc1bbea22eb5c4e // from the worker thread. virtual void WillDestroyWorkerContextOnWorkerThread( diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc -index cd0e4d7ea77ffe9fd09982ef2d9f5d57df8e2995..3a96f5f084061c30344552a01b3d3a7260dad65e 100644 +index 10c2a75c7106b4803d53bec02c9c347a3ca28cfe..9879ba58b68720151ab438ca85df9a30e2ad0c6f 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc @@ -947,6 +947,12 @@ void RendererBlinkPlatformImpl::WorkerContextCreated( diff --git a/patches/config.json b/patches/config.json index 1cbbf66ba4..e16ddfda0e 100644 --- a/patches/config.json +++ b/patches/config.json @@ -11,7 +11,5 @@ { "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/reclient-configs", "repo": "src/third_party/engflow-reclient-configs" }, - { "patch_dir": "src/electron/patches/sqlite", "repo": "src/third_party/sqlite/src" }, - { "patch_dir": "src/electron/patches/dawn", "repo": "src/third_party/dawn" }, - { "patch_dir": "src/electron/patches/pdfium", "repo": "src/third_party/pdfium" } + { "patch_dir": "src/electron/patches/sqlite", "repo": "src/third_party/sqlite/src" } ] diff --git a/patches/dawn/.patches b/patches/dawn/.patches index a633c1adca..e69de29bb2 100644 --- a/patches/dawn/.patches +++ b/patches/dawn/.patches @@ -1 +0,0 @@ -cherry-pick-7c11e1188705.patch diff --git a/patches/dawn/cherry-pick-7c11e1188705.patch b/patches/dawn/cherry-pick-7c11e1188705.patch deleted file mode 100644 index ee528e8d86..0000000000 --- a/patches/dawn/cherry-pick-7c11e1188705.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lokbondo Kung -Date: Tue, 7 Apr 2026 19:22:22 -0700 -Subject: [dawn][native] Check for waiting for idle before updating serials. - -- In the ExecutionQueue, we need to make sure to check whether a thread - is waiting for idle prior to updating the completed serial. Otherwise, - as the bug below points out, it's possible for the thread that's - waiting for idle (which just waits for the completed serial to reach - a certain value), to complete and destroy the Queue before the rest of - the UpdateSerial call completes. - -Bug: 497969820 -Change-Id: I7b9dba50f4ccb1aa8dfced122801e17db3ee4e0e -Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/300595 -Reviewed-by: Kai Ninomiya -Commit-Queue: Loko Kung - -diff --git a/src/dawn/native/ExecutionQueue.cpp b/src/dawn/native/ExecutionQueue.cpp -index 8be4e707e92ce1b3d94e4bb8fec3e332e8f17fb3..2bb5a6af253f17178332da4088fefbf922463b08 100644 ---- a/src/dawn/native/ExecutionQueue.cpp -+++ b/src/dawn/native/ExecutionQueue.cpp -@@ -253,20 +253,21 @@ void ExecutionQueueBase::UpdateCompletedSerialTo(QueuePriority priority, - } - - void ExecutionQueueBase::UpdateCompletedSerialToInternal(QueuePriority priority, -- ExecutionSerial completedSerial, -- bool forceTasks) { -+ ExecutionSerial newCompletedSerial, -+ bool forceTasksForDestroy) { - QueuePriorityArray>>* processors = nullptr; - std::vector tasks; - -- // We update the completed serial as soon as possible before waiting for callback rights so -- // that we almost always process as many callbacks as possible. -- ExecutionSerial serial = mCompletedSerial.Use([&](auto old) { -- *old = std::max(*old, static_cast(completedSerial)); -- return ExecutionSerial(*old); -- }); -- -- mState.Use([&](auto state) { -- if (state->mWaitingForIdle && !forceTasks) { -+ // Note that we need to determine whether we are waiting for idle before updating the completed -+ // serial because some backends WaitForIdleForDestructionImpl may be implemented via a call to -+ // WaitForQueueSerial which (by default without overrides), waits on the completed serial value. -+ // If we updated the serial value before checking the other pieces of state, a thread destroying -+ // the Queue calling WaitForIdleForDestruction, could end up being woken up and destroying the -+ // Queue device before the rest of this function completes. By checking the state first before -+ // updating the serial, however, we avoid waking up the thread that's waiting for idle until we -+ // have completed using the queue. -+ bool waitingForIdle = mState.Use([&](auto state) { -+ if (state->mWaitingForIdle && !forceTasksForDestroy) { - // If we are waiting for idle, then the callbacks will be fired there. It is currently - // necessary to avoid calling the callbacks in this function and doing it in the - // |WaitForIdleForDestruction| call because |WaitForIdleForDestruction| is called while -@@ -274,8 +275,11 @@ void ExecutionQueueBase::UpdateCompletedSerialToInternal(QueuePriority priority, - // device lock. As a result, if the main thread is waiting for idle, and another thread - // is trying to update the completed serial and call callbacks, it could deadlock. Once - // we update |WaitForIdleForDestruction| to release the device lock on the wait, we may -- // be able to simplify the code here. -- return; -+ // be able to simplify the code here. Note that skipping this when -+ // |forceTasksForDestroy| is currently ok because that branch is only called when we are -+ // also holding the device lock, either via a Destroy or via an error that is being -+ // handled. -+ return true; - } - - // Wait until we can exclusively call callbacks. -@@ -284,16 +288,22 @@ void ExecutionQueueBase::UpdateCompletedSerialToInternal(QueuePriority priority, - // Call all callbacks that for the given priority and anything of higher priority as well. - processors = &state->mWaitingProcessors; - for (QueuePriority p = QueuePriority::Highest; p >= priority; p -= 1) { -- PopWaitingTasksInto(serial, state->mWaitingTasks[p], tasks); -+ PopWaitingTasksInto(newCompletedSerial, state->mWaitingTasks[p], tasks); - } - state->mCallingCallbacks = true; -+ return false; -+ }); -+ -+ // Update the serial now that we know whether we are waiting for idle. -+ mCompletedSerial.Use([&](auto completedSerial) { -+ *completedSerial = std::max(*completedSerial, static_cast(newCompletedSerial)); - }); - - // Always call the processors before processing individual tasks. - if (processors) { - for (QueuePriority p = QueuePriority::Highest; p >= priority; p -= 1) { - for (auto& processor : (*processors)[p]) { -- processor->UpdateCompletedSerialTo(serial); -+ processor->UpdateCompletedSerialTo(newCompletedSerial); - } - } - } -@@ -304,7 +314,9 @@ void ExecutionQueueBase::UpdateCompletedSerialToInternal(QueuePriority priority, - task(); - } - -- mState->mCallingCallbacks = false; -+ if (!waitingForIdle) { -+ mState->mCallingCallbacks = false; -+ } - } - - MaybeError ExecutionQueueBase::EnsureCommandsFlushed(ExecutionSerial serial) { -diff --git a/src/dawn/native/ExecutionQueue.h b/src/dawn/native/ExecutionQueue.h -index 9140f9eb08458fd7163dfa724e5452f800c7dc6f..c0bfd75e2d9e6701e7f61a09c3d10b1ef5c3c200 100644 ---- a/src/dawn/native/ExecutionQueue.h -+++ b/src/dawn/native/ExecutionQueue.h -@@ -183,7 +183,7 @@ class ExecutionQueueBase : public ApiObjectBase { - - void UpdateCompletedSerialToInternal(QueuePriority priority, - ExecutionSerial completedSerial, -- bool forceTasks = false); -+ bool forceTasksForDestroy = false); - - // |mCompletedSerial| tracks the last completed command serial that the fence has returned. - // |mLastSubmittedSerial| tracks the last submitted command serial. diff --git a/patches/pdfium/.patches b/patches/pdfium/.patches index 50ecd2a46d..e69de29bb2 100644 --- a/patches/pdfium/.patches +++ b/patches/pdfium/.patches @@ -1 +0,0 @@ -cherry-pick-bce2e6728279.patch diff --git a/patches/pdfium/cherry-pick-bce2e6728279.patch b/patches/pdfium/cherry-pick-bce2e6728279.patch deleted file mode 100644 index e4a6ba33b7..0000000000 --- a/patches/pdfium/cherry-pick-bce2e6728279.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tom Sepez -Date: Tue, 7 Apr 2026 15:50:30 -0700 -Subject: Use safe arithmetic in CFX_PSRenderer::DrawDIBits() - -Hardening suggestion from the AI bot. - -Bug: 500036290 -Change-Id: Ie521629d06ba944f610b941a8c9e9505fa29aea7 -Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/145731 -Reviewed-by: Lei Zhang -Commit-Queue: Tom Sepez - -diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp -index b38f1a2b7c3271769e609763be2e183f2890ebb3..b8710e50ed01233b2aefbf1760e26e05964b315e 100644 ---- a/core/fxge/win32/cfx_psrenderer.cpp -+++ b/core/fxge/win32/cfx_psrenderer.cpp -@@ -620,8 +620,16 @@ bool CFX_PSRenderer::DrawDIBits(RetainPtr bitmap, - encoder_iface_->pJpegEncodeFunc(bitmap, &output_buf, &output_size)) { - filter = "/DCTDecode filter "; - } else { -- int src_pitch = width * bytes_per_pixel; -- output_size = height * src_pitch; -+ FX_SAFE_UINT32 safe_pitch = bytes_per_pixel; -+ safe_pitch *= width; -+ FX_SAFE_UINT32 safe_output_size = safe_pitch; -+ safe_output_size *= height; -+ if (!safe_output_size.IsValid()) { -+ WriteString("\nQ\n"); -+ return false; -+ } -+ uint32_t src_pitch = safe_pitch.ValueOrDie(); -+ output_size = safe_output_size.ValueOrDie(); - output_buf = FX_Alloc(uint8_t, output_size); - for (int row = 0; row < height; row++) { - const uint8_t* src_scan = bitmap->GetScanline(row).data();