CVE-2026-87609
Overview
Background
- Send Tab To Self (STTS)
- a Chrome sync feature that pushes a URL “entry” from one signed-in device to another so it can be reopened, surfaced on iOS via an infobar.
- `SendTabToSelfBrowserAgent`
- the iOS per-browser object that observes the
SendTabToSelfModelfor remotely-added entries and shows an infobar on the active, visibleWebState. - Pending entry
- an STTS entry that arrived while the active tab was not yet visible, so its display is deferred until the tab is shown or another tab is activated.
- `SendTabToSelfModel::RemoveEntryRemotely`
- the model owns each
SendTabToSelfEntry; a remote removal (or history clearing) destroys the entry object and then notifies observers.
Root Cause Analysis
When a remote STTS entry arrived while the active WebState was not visible, SendTabToSelfBrowserAgent cached a raw pointer to the model-owned SendTabToSelfEntry in pending_entry_ and waited for the tab to become visible. Because the model destroys an entry before notifying observers of its removal (as the fake’s reordered RemoveEntryRemotely now reproduces), any subsequent destruction of that entry — for example during history clearing or a remote removal — left pending_entry_ dangling. The removal-notification handler (DismissEntries, per the commit message) then dereferenced pending_entry_->GetGUID(), and the deferred display paths would likewise pass the freed pointer to DisplayInfoBar, both reading through freed heap memory.
The fix stores the entry’s stable GUID in std::optional<std::string> pending_entry_guid_ instead of a pointer, compares GUIDs by value in the removal handler, and re-resolves the live entry through model_->GetEntryByGUID(...) (null-checking the result) before any display, so a freed entry is never dereferenced.
Attack Path
- Establish sync state
The victim is signed in with Send Tab To Self enabled, so remotely-shared entries flow into the local
SendTabToSelfModeland are observed bySendTabToSelfBrowserAgent. - Deliver entry to a hidden tab
A remote entry is added while the active
WebStateis not visible, so the agent stores a rawpending_entry_pointer instead of displaying an infobar immediately. - Free the entry
The same entry is destroyed while still pending (remote removal via
RemoveEntryRemotely, or entries cleared during history clearing), and the model frees theSendTabToSelfEntrybefore notifying observers, leavingpending_entry_dangling. - Trigger the dereference
The removal handler
DismissEntriesreadspending_entry_->GetGUID()on the freed object, or, if that path is missed, showing/activating the tab passes the freedpending_entry_toDisplayInfoBar, producing a heap use-after-free read. - Escalate (inferred) With heap grooming to control the contents of the reallocated slot, the dangling read could be steered toward further memory disclosure or corruption; the patch itself only demonstrates the freed-memory read.
Impact Assessment
SendTabToSelfEntry in the iOS browser process. The patch demonstrates a freed-memory read (GetGUID() / infobar fields); any escalation to broader information disclosure or code execution is (inferred). The vendor advisory rates this medium severity and does not report in-the-wild exploitation; NVD scores it CVSS 9.6.Changed Functions
| Function | Change | Notes |
|---|---|---|
forcomponents/send_tab_to_self/fake_send_tab_to_self_model.cc |
modified | |
ifios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.mm |
modified | |
TEST_Fios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm |
modified | |
SendTabToSelfBrowserAgentToastDisabledTestios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm |
modified |
Files Changed
components/send_tab_to_self/fake_send_tab_to_self_model.ccios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.hcomponents/send_tab_to_self/fake_send_tab_to_self_model.hios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mmios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.mm
Audit Directions
- Raw pointers to sync/model-owned objects across a deferralFlag any observer or browser agent that caches a
raw_ptrto a model-owned entity (STTS entries, bookmarks, history rows) to use later; prefer a stable key re-resolved from the owner at point of use. - Destroy-before-notify orderingAudit models whose removal path frees an object before firing
OnEntriesRemovedRemotely-style notifications, since observers may still hold and dereference references to the just-freed object during the callback. - Fake/mock divergence from production orderingWhere a fake reorders operations relative to the real implementation (here, erase vs. notify), tests can mask lifetime bugs; align fakes with real destruction ordering and add coverage for the removed-while-pending window.
Patch
From 3c0d8469dea16aaeb7bc9feb1d01cdaa5131945e Mon Sep 17 00:00:00 2001
From: Michael Tatarski <mtatarski@google.com>
Date: Mon, 17 Aug 2026 06:31:33 -0700
Subject: [PATCH] [STTS][iOS] Fix UAF by tracking pending entry via GUID
SendTabToSelfBrowserAgent previously held a raw pointer to a pending
SendTabToSelfEntry when a remote entry arrived while the active tab was
not visible. If entries were destroyed prior to notifying observers
(e.g. during history clearing), dereferencing the pointer in
DismissEntries caused a heap-use-after-free.
This change stores the GUID string instead of a raw pointer and resolves
the entry dynamically from the model when displaying the infobar.
Fixed: 547322272
Change-Id: I841a2469f40aa18308b18a50d55ec832bd4540bc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8252063
Commit-Queue: Michael Tatarski <mtatarski@google.com>
Reviewed-by: Marc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1680497}
---
diff --git a/components/send_tab_to_self/fake_send_tab_to_self_model.cc b/components/send_tab_to_self/fake_send_tab_to_self_model.cc
index 564b63a..177456e 100644
--- a/components/send_tab_to_self/fake_send_tab_to_self_model.cc
+++ b/components/send_tab_to_self/fake_send_tab_to_self_model.cc
@@ -259,13 +259,13 @@
return results;
}
-void FakeSendTabToSelfModel::RemoveEntryRemotely(const std::string& guid) {
+void FakeSendTabToSelfModel::RemoveEntryRemotely(std::string guid) {
auto it = entries_.find(guid);
if (it != entries_.end()) {
+ entries_.erase(it);
for (auto& observer : observers_) {
observer.OnEntriesRemovedRemotely({guid});
}
- entries_.erase(it);
}
}
diff --git a/components/send_tab_to_self/fake_send_tab_to_self_model.h b/components/send_tab_to_self/fake_send_tab_to_self_model.h
index cc74669a..6094e7d 100644
--- a/components/send_tab_to_self/fake_send_tab_to_self_model.h
+++ b/components/send_tab_to_self/fake_send_tab_to_self_model.h
@@ -94,8 +94,9 @@
std::vector<const SendTabToSelfEntry*> AddEntriesRemotely(
std::vector<RemoteEntryParams> entries_params);
- // Simulates an entry being removed from a remote device.
- void RemoveEntryRemotely(const std::string& guid);
+ // Removes the entry corresponding to the `guid` from the local model and
+ // notify observers that the entry was removed remotely.
+ void RemoveEntryRemotely(std::string guid);
const std::string& last_opened_guid() const { return last_opened_guid_; }
const std::string& last_dismissed_guid() const {
diff --git a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.h b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.h
index 328cf5cb..de9b50b 100644
--- a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.h
+++ b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.h
@@ -155,8 +155,9 @@
// Owned by the SendTabToSelfSyncService which should outlive this class
raw_ptr<send_tab_to_self::SendTabToSelfModel> model_ = nullptr;
- // The pending SendTabToSelf entry to display an InfoBar for.
- raw_ptr<const send_tab_to_self::SendTabToSelfEntry> pending_entry_ = nullptr;
+ // The GUID of the pending SendTabToSelf entry to display an InfoBar for,
+ // if any.
+ std::optional<std::string> pending_entry_guid_;
// The WebState that is being observed for activation, if any.
raw_ptr<web::WebState> pending_web_state_ = nullptr;
diff --git a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.mm b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.mm
index cbbdcc57..a35217ed 100644
--- a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.mm
+++ b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.mm
@@ -287,7 +287,10 @@
// Pick the most recently shared entry since only one infobar can be shown
// at a time.
- pending_entry_ = GetMostRecentlySharedEntry(new_entries);
+ const send_tab_to_self::SendTabToSelfEntry* entry =
+ GetMostRecentlySharedEntry(new_entries);
+ pending_entry_guid_ =
+ entry ? std::make_optional(entry->GetGUID()) : std::nullopt;
return;
}
@@ -309,8 +312,8 @@
return;
}
- if (pending_entry_ &&
- std::ranges::contains(guids, pending_entry_->GetGUID())) {
+ if (pending_entry_guid_ &&
+ std::ranges::contains(guids, *pending_entry_guid_)) {
CleanUpObserversAndVariables();
}
@@ -353,10 +356,16 @@
return;
}
- if (pending_entry_) {
- DisplayInfoBar(new_active, pending_entry_, /*opened_tab_count=*/1);
- CleanUpObserversAndVariables();
+ if (!pending_entry_guid_) {
+ return;
}
+
+ const send_tab_to_self::SendTabToSelfEntry* entry =
+ model_->GetEntryByGUID(*pending_entry_guid_);
+ if (entry) {
+ DisplayInfoBar(new_active, entry, /*opened_tab_count=*/1);
+ }
+ CleanUpObserversAndVariables();
}
#pragma mark - WebStateObserver
@@ -368,10 +377,14 @@
return;
}
- DCHECK(pending_entry_);
+ DCHECK(pending_entry_guid_.has_value());
DCHECK(pending_web_state_);
- DisplayInfoBar(pending_web_state_, pending_entry_, /*opened_tab_count=*/1);
+ const send_tab_to_self::SendTabToSelfEntry* entry =
+ model_->GetEntryByGUID(*pending_entry_guid_);
+ if (entry) {
+ DisplayInfoBar(pending_web_state_, entry, /*opened_tab_count=*/1);
+ }
CleanUpObserversAndVariables();
}
@@ -410,7 +423,7 @@
}
void SendTabToSelfBrowserAgent::CleanUpObserversAndVariables() {
- pending_entry_ = nullptr;
+ pending_entry_guid_.reset();
web_state_observation_.Reset();
pending_web_state_ = nullptr;
diff --git a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
index 6400e4a..b70f0c2 100644
--- a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
+++ b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
@@ -397,6 +397,126 @@
EXPECT_EQ(0UL, infobar_manager->infobars().size());
}
+// Tests that when an entry is added while the active WebState is not visible,
+// and then the entry is removed remotely (deallocated), showing the WebState
+// afterwards does not show an InfoBar or cause a use-after-free crash.
+TEST_F(SendTabToSelfBrowserAgentTest, TestRemoteRemovePendingNotVisibleTab) {
+ // Add a web state, active but not visible.
+ web::WebState* web_state =
+ AppendNewWebState(GURL("http://www.blank.com"),
+ /*activate=*/true, /*is_visible=*/false);
+ InfoBarManagerImpl* infobar_manager =
+ InfoBarManagerImpl::FromWebState(web_state);
+ EXPECT_EQ(0UL, infobar_manager->infobars().size());
+
+ // Remote entry added while tab is not visible (so pending_entry_guid_ is
+ // set).
+ const SendTabToSelfEntry* entry = model_->AddEntryRemotely(
+ GURL("http://www.test.com/test-1"), "title", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(entry);
+ std::string guid = entry->GetGUID();
+
+ // No visible web state, so expect no infobar yet.
+ EXPECT_EQ(0UL, infobar_manager->infobars().size());
+
+ // Remove the entry remotely (which erases the entry and calls
+ // DismissEntries).
+ model_->RemoveEntryRemotely(guid);
+
+ // Show the web state.
+ web_state->WasShown();
+
+ // No infobar should be added since the pending entry was removed.
+ EXPECT_EQ(0UL, infobar_manager->infobars().size());
+}
+
+// Tests that removing an unrelated entry remotely removes its InfoBar but
+// preserves the pending entry for a not-yet-visible WebState.
+TEST_F(SendTabToSelfBrowserAgentTest,
+ TestRemoteRemoveUnrelatedEntryPreservesPending) {
+ // Add first web state, active and visible.
+ web::WebState* web_state1 = AppendNewWebState(GURL("http://www.blank.com"));
+ InfoBarManagerImpl* infobar_manager1 =
+ InfoBarManagerImpl::FromWebState(web_state1);
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+
+ // Add an entry for the visible web state.
+ const SendTabToSelfEntry* entry1 = model_->AddEntryRemotely(
+ GURL("http://www.test.com/first"), "title1", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(entry1);
+ std::string guid1 = entry1->GetGUID();
+ EXPECT_EQ(1UL, infobar_manager1->infobars().size());
+
+ // Add second web state, active but not visible.
+ web::WebState* web_state2 =
+ AppendNewWebState(GURL("http://www.blank.com"),
+ /*activate=*/true, /*is_visible=*/false);
+ InfoBarManagerImpl* infobar_manager2 =
+ InfoBarManagerImpl::FromWebState(web_state2);
+ EXPECT_EQ(0UL, infobar_manager2->infobars().size());
+
+ // Add the pending entry for the non-visible web state.
+ const SendTabToSelfEntry* pending_entry = model_->AddEntryRemotely(
+ GURL("http://www.test.com/pending"), "title2", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(pending_entry);
+ std::string pending_guid = pending_entry->GetGUID();
+ EXPECT_EQ(0UL, infobar_manager2->infobars().size());
+
+ // Remove the first entry remotely.
+ model_->RemoveEntryRemotely(guid1);
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+
+ // Show the second web state.
+ web_state2->WasShown();
+
+ // An infobar for the pending entry should now be added to the second web
+ // state.
+ ASSERT_EQ(1UL, infobar_manager2->infobars().size());
+ infobars::InfoBar* infobar = infobar_manager2->infobars()[0];
+ auto* delegate =
+ static_cast<send_tab_to_self::IOSSendTabToSelfInfoBarDelegate*>(
+ infobar->delegate());
+ EXPECT_EQ(pending_guid, delegate->GetGUID());
+}
+
+// Tests that when an entry is added while the active WebState is not visible,
+// and then the entry is removed remotely (deallocated), switching to another
+// active WebState does not show an InfoBar or cause a use-after-free crash.
+TEST_F(SendTabToSelfBrowserAgentTest,
+ TestRemoteRemovePendingNotVisibleTabSwitchesActiveTab) {
+ // Add a web state, active but not visible.
+ web::WebState* web_state1 =
+ AppendNewWebState(GURL("http://www.blank.com"),
+ /*activate=*/true, /*is_visible=*/false);
+ InfoBarManagerImpl* infobar_manager1 =
+ InfoBarManagerImpl::FromWebState(web_state1);
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+
+ // Remote entry added while tab 1 is not visible (so pending_entry_guid_ is
+ // set).
+ const SendTabToSelfEntry* entry = model_->AddEntryRemotely(
+ GURL("http://www.test.com/test-1"), "title", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(entry);
+ std::string guid = entry->GetGUID();
+
+ // Remove the entry remotely (which erases the entry and calls
+ // DismissEntries).
+ model_->RemoveEntryRemotely(guid);
+
+ // Add and activate a second web state.
+ web::WebState* web_state2 = AppendNewWebState(GURL("http://www.blank.com"));
+ InfoBarManagerImpl* infobar_manager2 =
+ InfoBarManagerImpl::FromWebState(web_state2);
+
+ // No infobar should be added to either web state since the entry was removed.
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+ EXPECT_EQ(0UL, infobar_manager2->infobars().size());
+}
+
// Tests that SendTabToSelfLoadNavigationUserData is correctly attached or
// detached when TabWillLoadUrl is triggered.
TEST_F(SendTabToSelfBrowserAgentTest, TestTabWillLoadUrl) {
@@ -759,8 +879,7 @@
public:
SendTabToSelfBrowserAgentToastEnabledTest()
: SendTabToSelfBrowserAgentTest(
- {send_tab_to_self::kSendTabToSelfPostSendToast},
- {}) {}
+ {send_tab_to_self::kSendTabToSelfPostSendToast}) {}
};
class SendTabToSelfBrowserAgentToastDisabledTest
Regression Test / PoC
diff --git a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
index 6400e4a..b70f0c2 100644
--- a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
+++ b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
@@ -397,6 +397,126 @@
EXPECT_EQ(0UL, infobar_manager->infobars().size());
}
+// Tests that when an entry is added while the active WebState is not visible,
+// and then the entry is removed remotely (deallocated), showing the WebState
+// afterwards does not show an InfoBar or cause a use-after-free crash.
+TEST_F(SendTabToSelfBrowserAgentTest, TestRemoteRemovePendingNotVisibleTab) {
+ // Add a web state, active but not visible.
+ web::WebState* web_state =
+ AppendNewWebState(GURL("http://www.blank.com"),
+ /*activate=*/true, /*is_visible=*/false);
+ InfoBarManagerImpl* infobar_manager =
+ InfoBarManagerImpl::FromWebState(web_state);
+ EXPECT_EQ(0UL, infobar_manager->infobars().size());
+
+ // Remote entry added while tab is not visible (so pending_entry_guid_ is
+ // set).
+ const SendTabToSelfEntry* entry = model_->AddEntryRemotely(
+ GURL("http://www.test.com/test-1"), "title", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(entry);
+ std::string guid = entry->GetGUID();
+
+ // No visible web state, so expect no infobar yet.
+ EXPECT_EQ(0UL, infobar_manager->infobars().size());
+
+ // Remove the entry remotely (which erases the entry and calls
+ // DismissEntries).
+ model_->RemoveEntryRemotely(guid);
+
+ // Show the web state.
+ web_state->WasShown();
+
+ // No infobar should be added since the pending entry was removed.
+ EXPECT_EQ(0UL, infobar_manager->infobars().size());
+}
+
+// Tests that removing an unrelated entry remotely removes its InfoBar but
+// preserves the pending entry for a not-yet-visible WebState.
+TEST_F(SendTabToSelfBrowserAgentTest,
+ TestRemoteRemoveUnrelatedEntryPreservesPending) {
+ // Add first web state, active and visible.
+ web::WebState* web_state1 = AppendNewWebState(GURL("http://www.blank.com"));
+ InfoBarManagerImpl* infobar_manager1 =
+ InfoBarManagerImpl::FromWebState(web_state1);
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+
+ // Add an entry for the visible web state.
+ const SendTabToSelfEntry* entry1 = model_->AddEntryRemotely(
+ GURL("http://www.test.com/first"), "title1", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(entry1);
+ std::string guid1 = entry1->GetGUID();
+ EXPECT_EQ(1UL, infobar_manager1->infobars().size());
+
+ // Add second web state, active but not visible.
+ web::WebState* web_state2 =
+ AppendNewWebState(GURL("http://www.blank.com"),
+ /*activate=*/true, /*is_visible=*/false);
+ InfoBarManagerImpl* infobar_manager2 =
+ InfoBarManagerImpl::FromWebState(web_state2);
+ EXPECT_EQ(0UL, infobar_manager2->infobars().size());
+
+ // Add the pending entry for the non-visible web state.
+ const SendTabToSelfEntry* pending_entry = model_->AddEntryRemotely(
+ GURL("http://www.test.com/pending"), "title2", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(pending_entry);
+ std::string pending_guid = pending_entry->GetGUID();
+ EXPECT_EQ(0UL, infobar_manager2->infobars().size());
+
+ // Remove the first entry remotely.
+ model_->RemoveEntryRemotely(guid1);
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+
+ // Show the second web state.
+ web_state2->WasShown();
+
+ // An infobar for the pending entry should now be added to the second web
+ // state.
+ ASSERT_EQ(1UL, infobar_manager2->infobars().size());
+ infobars::InfoBar* infobar = infobar_manager2->infobars()[0];
+ auto* delegate =
+ static_cast<send_tab_to_self::IOSSendTabToSelfInfoBarDelegate*>(
+ infobar->delegate());
+ EXPECT_EQ(pending_guid, delegate->GetGUID());
+}
+
+// Tests that when an entry is added while the active WebState is not visible,
+// and then the entry is removed remotely (deallocated), switching to another
+// active WebState does not show an InfoBar or cause a use-after-free crash.
+TEST_F(SendTabToSelfBrowserAgentTest,
+ TestRemoteRemovePendingNotVisibleTabSwitchesActiveTab) {
+ // Add a web state, active but not visible.
+ web::WebState* web_state1 =
+ AppendNewWebState(GURL("http://www.blank.com"),
+ /*activate=*/true, /*is_visible=*/false);
+ InfoBarManagerImpl* infobar_manager1 =
+ InfoBarManagerImpl::FromWebState(web_state1);
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+
+ // Remote entry added while tab 1 is not visible (so pending_entry_guid_ is
+ // set).
+ const SendTabToSelfEntry* entry = model_->AddEntryRemotely(
+ GURL("http://www.test.com/test-1"), "title", kDeviceID,
+ send_tab_to_self::PageContext(), send_tab_to_self::NavigationHistory());
+ ASSERT_TRUE(entry);
+ std::string guid = entry->GetGUID();
+
+ // Remove the entry remotely (which erases the entry and calls
+ // DismissEntries).
+ model_->RemoveEntryRemotely(guid);
+
+ // Add and activate a second web state.
+ web::WebState* web_state2 = AppendNewWebState(GURL("http://www.blank.com"));
+ InfoBarManagerImpl* infobar_manager2 =
+ InfoBarManagerImpl::FromWebState(web_state2);
+
+ // No infobar should be added to either web state since the entry was removed.
+ EXPECT_EQ(0UL, infobar_manager1->infobars().size());
+ EXPECT_EQ(0UL, infobar_manager2->infobars().size());
+}
+
// Tests that SendTabToSelfLoadNavigationUserData is correctly attached or
// detached when TabWillLoadUrl is triggered.
TEST_F(SendTabToSelfBrowserAgentTest, TestTabWillLoadUrl) {
@@ -759,8 +879,7 @@
public:
SendTabToSelfBrowserAgentToastEnabledTest()
: SendTabToSelfBrowserAgentTest(
- {send_tab_to_self::kSendTabToSelfPostSendToast},
- {}) {}
+ {send_tab_to_self::kSendTabToSelfPostSendToast}) {}
};
class SendTabToSelfBrowserAgentToastDisabledTest