Skip to content

Commit

Permalink
[iOS] - Fix alert continuation leak when WebKit automatically cancels…
Browse files Browse the repository at this point in the history
… the request (#27069)

Fix alert continuation leak when WebKit automatically cancels the request.
  • Loading branch information
Brandon-T authored Dec 20, 2024
1 parent 6a75a93 commit 144e1e4
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ extension BrowserViewController: WKNavigationDelegate {
guard var requestURL = navigationAction.request.url else {
return (.cancel, preferences)
}

let tab = tab(for: webView)
if tab?.isExternalAppAlertPresented == true {
tab?.externalAppPopup?.dismissWithType(dismissType: .noAnimation)
tab?.externalAppPopupContinuation?.resume(with: .success(false))
tab?.externalAppPopupContinuation = nil
tab?.externalAppPopup = nil
}

if InternalURL.isValid(url: requestURL) {
if navigationAction.navigationType != .backForward, navigationAction.isInternalUnprivileged,
navigationAction.sourceFrame != nil || navigationAction.targetFrame?.isMainFrame == false
Expand Down Expand Up @@ -204,7 +213,6 @@ extension BrowserViewController: WKNavigationDelegate {

// First special case are some schemes that are about Calling. We prompt the user to confirm this action. This
// gives us the exact same behaviour as Safari.
let tab = tab(for: webView)

if ["sms", "tel", "facetime", "facetime-audio"].contains(requestURL.scheme) {
let shouldOpen = await handleExternalURL(
Expand Down Expand Up @@ -1264,6 +1272,8 @@ extension BrowserViewController {
titleSize: 21
)

tab?.externalAppPopup = popup

if isSuppressActive {
popup.addButton(title: Strings.suppressAlertsActionTitle, type: .destructive) {
[weak tab] () -> PopupViewDismissType in
Expand Down Expand Up @@ -1322,10 +1332,17 @@ extension BrowserViewController {

tab?.externalAppAlertCounter += 1

return await withCheckedContinuation { continuation in
showExternalSchemeAlert(isSuppressActive: tab?.externalAppAlertCounter ?? 0 > 2) {
continuation.resume(with: .success($0))
return await withTaskCancellationHandler {
return await withCheckedContinuation { [weak tab] continuation in
tab?.externalAppPopupContinuation = continuation
showExternalSchemeAlert(isSuppressActive: tab?.externalAppAlertCounter ?? 0 > 2) {
tab?.externalAppPopupContinuation = nil
continuation.resume(with: .success($0))
}
}
} onCancel: { [weak tab] in
tab?.externalAppPopupContinuation?.resume(with: .success(false))
tab?.externalAppPopupContinuation = nil
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions ios/brave-ios/Sources/Brave/Frontend/Browser/Tab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import BraveCore
import BraveShields
import BraveUI
import BraveWallet
import CertificateUtilities
import Data
Expand Down Expand Up @@ -429,6 +430,8 @@ class Tab: NSObject {

/// Boolean tracking custom url-scheme alert presented
var isExternalAppAlertPresented = false
var externalAppPopup: AlertPopupView?
var externalAppPopupContinuation: CheckedContinuation<Bool, Never>?
var externalAppAlertCounter = 0
var isExternalAppAlertSuppressed = false
var externalAppURLDomain: String?
Expand Down

0 comments on commit 144e1e4

Please sign in to comment.