[go: nahoru, domu]

[M123] Fix crash in TabPickupInfobarDelegate::FetchFavIconImage

The block is asynchronously using `this`. Use a Callback instead
of a block to cancel block on object deletion.

(cherry picked from commit 1681aeb742f4d242e86c0432ff9903755313a9a2)

Bug: 329033812
Change-Id: I03cb669c09bf49900316a98f6f5758792d6318e6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5358004
Auto-Submit: Olivier Robin <olivierrobin@chromium.org>
Reviewed-by: Gauthier Ambard <gambard@chromium.org>
Commit-Queue: Olivier Robin <olivierrobin@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1271443}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5367007
Commit-Queue: Krishna Govind <govind@chromium.org>
Reviewed-by: Krishna Govind <govind@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/6312@{#574}
Cr-Branched-From: 6711dcdae48edaf98cbc6964f90fac85b7d9986e-refs/heads/main@{#1262506}
diff --git a/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.h b/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.h
index 4636c2e5..f8b1d56 100644
--- a/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.h
+++ b/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.h
@@ -49,6 +49,9 @@
   bool EqualsDelegate(infobars::InfoBarDelegate* delegate) const override;
 
  private:
+  // Called when a Favicon has been fetched.
+  void FaviconFetched(ProceduralBlock block_handler,
+                      FaviconAttributes* attributes);
   // Session name.
   std::string session_name_;
   // Time the session is last modified.
@@ -66,6 +69,8 @@
   raw_ptr<Browser> browser_ = nullptr;
   // Loads favicons.
   raw_ptr<FaviconLoader> favicon_loader_ = nullptr;
+
+  base::WeakPtrFactory<TabPickupInfobarDelegate> weak_factory_{this};
 };
 
 #endif  // IOS_CHROME_BROWSER_PERMISSIONS_PERMISSIONS_INFOBAR_DELEGATE_H_
diff --git a/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.mm b/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.mm
index a20764b..778bd4c 100644
--- a/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.mm
+++ b/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.mm
@@ -4,6 +4,8 @@
 
 #import "ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_infobar_delegate.h"
 
+#import "base/functional/bind.h"
+#import "base/functional/callback_helpers.h"
 #import "base/metrics/histogram_functions.h"
 #import "components/infobars/core/infobar_delegate.h"
 #import "components/sync_sessions/open_tabs_ui_delegate.h"
@@ -56,12 +58,10 @@
   }
   favicon_loader_->FaviconForPageUrl(
       tab_url_, kDesiredSmallFaviconSizePt, kMinFaviconSizePt,
-      /*fallback_to_google_server=*/true, ^(FaviconAttributes* attributes) {
-        if (!attributes.usesDefaultImage) {
-          favicon_image_ = attributes.faviconImage;
-          block_handler();
-        }
-      });
+      /*fallback_to_google_server=*/true,
+      base::CallbackToBlock(
+          base::BindRepeating(&TabPickupInfobarDelegate::FaviconFetched,
+                              weak_factory_.GetWeakPtr(), block_handler)));
 }
 
 void TabPickupInfobarDelegate::OpenDistantTab() {
@@ -116,3 +116,14 @@
     infobars::InfoBarDelegate* delegate) const {
   return delegate->GetIdentifier() == GetIdentifier();
 }
+
+#pragma mark - Private methods
+
+void TabPickupInfobarDelegate::FaviconFetched(ProceduralBlock block_handler,
+                                              FaviconAttributes* attributes) {
+  DCHECK(block_handler);
+  if (!attributes.usesDefaultImage) {
+    favicon_image_ = attributes.faviconImage;
+    block_handler();
+  }
+}