Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in Omnibox
DescriptionInappropriate implementation in Omnibox
ComponentOmnibox
Bug ClassLogic Error
Tracker438226517
Fix commitcb2f93701240 (chromium/src) +57/-1
CISA KEVNot listed
CreditedHafiizh
Disclosed2025-09-30

Files Changed

  • chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
  • chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
From cb2f937012403bbfa165cc067d2923223afcf86e Mon Sep 17 00:00:00 2001
From: Patrick Noland <[email protected]>
Date: Thu, 28 Aug 2025 14:12:21 -0700
Subject: [PATCH] [mobar] Force re-measure of coordinator layout on leaving mobar

This avoids a bug in CoordinatorLayout where a stale list of children
can cause a ClassCastException after reparenting.

Bug: 438226517
Change-Id: I2924109bfeb7fd8c855317a27dff730446b78a0b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6896264
Reviewed-by: Tomasz Wiszkowski <[email protected]>
Commit-Queue: Patrick Noland <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1508003}
---

diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
index b129393d..f81cc14b 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
@@ -241,6 +241,14 @@
             mToolbar.getProgressBar().setVisibility(View.VISIBLE);
             mToolbarView.setVisibility(View.VISIBLE);
             mToolbarContainer.removeView(mLocationBarView);
+            // CoordinatorLayout only updates its processed list of children at measure time, even
+            // if a child is removed. This can cause problems if a reparented former child has a new
+            // type of LayoutParams, triggering a ClassCastException. We work around this by forcing
+            // a re-measure.
+            mToolbarContainer.forceLayout();
+            mToolbarContainer.measure(
+                    mToolbarContainer.getMeasuredWidthAndState(),
+                    mToolbarContainer.getMeasuredHeightAndState());
             mToolbar.restoreLocationBarView();
             setBackgroundColor(Color.TRANSPARENT);
         }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
index c237447..502e57c59 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
@@ -22,6 +22,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -45,11 +46,21 @@
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.layouts.LayoutStateProvider;
 import org.chromium.chrome.browser.layouts.LayoutType;
+import org.chromium.chrome.browser.omnibox.LocationBarCoordinator;
+import org.chromium.chrome.browser.omnibox.LocationBarCoordinatorPhone;
+import org.chromium.chrome.browser.omnibox.NewTabPageDelegate;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
 import org.chromium.chrome.browser.theme.SurfaceColorUpdateUtils;
+import org.chromium.chrome.browser.theme.ThemeColorProvider;
+import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
 import org.chromium.chrome.browser.toolbar.ToolbarFeatures;
 import org.chromium.chrome.browser.toolbar.ToolbarHairlineView;
 import org.chromium.chrome.browser.toolbar.ToolbarProgressBar;
+import org.chromium.chrome.browser.toolbar.back_button.BackButtonCoordinator;
+import org.chromium.chrome.browser.toolbar.forward_button.ForwardButtonCoordinator;
+import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator;
+import org.chromium.chrome.browser.toolbar.reload_button.ReloadButtonCoordinator;
 import org.chromium.chrome.browser.toolbar.top.CaptureReadinessResult.TopToolbarAllowCaptureReason;
 import org.chromium.chrome.browser.toolbar.top.CaptureReadinessResult.TopToolbarBlockCaptureReason;
 import org.chromium.chrome.browser.toolbar.top.ToolbarControlContainer.ToolbarViewResourceAdapter;
@@ -57,7 +68,9 @@
 import org.chromium.chrome.browser.toolbar.top.ToolbarControlContainer.ToolbarViewResourceCoordinatorLayout;
 import org.chromium.components.browser_ui.desktop_windowing.AppHeaderState;
 import org.chromium.components.browser_ui.widget.TouchEventObserver;
+import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.ui.base.TestActivity;
+import org.chromium.url.GURL;
 
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.BooleanSupplier;
@@ -79,11 +92,23 @@
     @Mock private View mLocationBarView;
     @Mock private ToolbarHairlineView mToolbarHairline;
     @Mock private Toolbar mToolbar;
+    @Mock private ToggleTabStackButtonCoordinator mTabSwitcherButtonCoordinator;
     @Mock private ToolbarProgressBar mProgressBar;
     @Mock private Tab mTab;
     @Mock private LayoutStateProvider mLayoutStateProvider;
     @Mock private FullscreenManager mFullscreenManager;
     @Mock private TouchEventObserver mTouchEventObserver;
+    @Mock private LocationBarCoordinator mLocationBarCoordinator;
+    @Mock private LocationBarCoordinatorPhone mLocationBarCoordinatorPhone;
+    @Mock private MenuButtonCoordinator mMenuButtonCoordinator;
+    @Mock private ToolbarDataProvider mToolbarDataProvider;
+    @Mock private ReloadButtonCoordinator mReloadButtonCoordinator;
+    @Mock private BackButtonCoordinator mBackButtonCoordinator;
+    @Mock private ForwardButtonCoordinator mForwardButtonCoordinator;
+    @Mock private HomeButtonDisplay mHomeButtonDisplay;
+    @Mock private ThemeColorProvider mThemeColorProvider;
+    @Mock private IncognitoStateProvider mIncognitoStateProvider;
+    @Mock private NewTabPageDelegate mNewTabPageDelegate;
 
     private final Supplier<Tab> mTabSupplier = () -> mTab;
     private final ObservableSupplierImpl<Boolean> mCompositorInMotionSupplier =
@@ -535,6 +560,28 @@
                 mLayoutStateProviderSupplier,
                 mFullscreenManager);
 
+        ToolbarPhone toolbarPhone = controlContainer.findViewById(R.id.toolbar);
+        doReturn(mLocationBarCoordinatorPhone).when(mLocationBarCoordinator).getPhoneCoordinator();
+        doReturn(mNewTabPageDelegate).when(mToolbarDataProvider).getNewTabPageDelegate();
+        doReturn(new GURL(UrlConstants.ABOUT_URL)).when(mToolbarDataProvider).getCurrentGurl();
+        toolbarPhone.setLocationBarCoordinator(mLocationBarCoordinator);
+        toolbarPhone.initialize(
+                mToolbarDataProvider,
+                null,
+                mMenuButtonCoordinator,
+                mTabSwitcherButtonCoordinator,
+                null,
+                null,
+                null,
+                mProgressBar,
+                mReloadButtonCoordinator,
+                mBackButtonCoordinator,
+                mForwardButtonCoordinator,
+                mHomeButtonDisplay,
+                /* extensionToolbarCoordinator= */ null,
+                mThemeColorProvider,
+                mIncognitoStateProvider);
+
         controlContainer.toggleLocationBarOnlyMode(true);
         verify(mProgressBar).setVisibility(View.GONE);
         verify(mToolbarView).setVisibility(View.GONE);
@@ -546,8 +593,9 @@
                 mLocationBarView,
                 toolbarViewResourceFrameLayout.getChildAt(
                         toolbarViewResourceFrameLayout.getChildCount() - 1));
-        // check that location bar is parented to container view
 
+        MarginLayoutParams layoutParams = new MarginLayoutParams(500, 100);
+        doReturn(layoutParams).when(mLocationBarCoordinatorPhone).getMarginLayoutParams();
         controlContainer.toggleLocationBarOnlyMode(false);
         verify(mProgressBar).setVisibility(View.VISIBLE);
         verify(mToolbarView).setVisibility(View.VISIBLE);
Loading diff…

Original Bug Report

reported by [email protected]

Address Bar Spoofing on Android

redacted
View on issue tracker