diff --git a/components/payments/content/secure_payment_confirmation_controller.cc b/components/payments/content/secure_payment_confirmation_controller.cc index d0e4f98bc728d..719e6c7552f6d 100644 --- a/components/payments/content/secure_payment_confirmation_controller.cc +++ b/components/payments/content/secure_payment_confirmation_controller.cc @@ -130,7 +130,15 @@ void SecurePaymentConfirmationController::OnConfirm() { SecurePaymentRequestOutcome::kAccept); is_dialog_showing_ = false; + // CloseDialog() -> Widget::Close() can synchronously trigger activation + // observers that destroy the hosting WebContents and therefore `this` + // (via ~PaymentRequest -> ChromePaymentRequestDelegate::CloseDialog() -> + // spc_dialog_.reset()). See https://crbug.com/521495992. + auto weak_this = weak_ptr_factory_.GetWeakPtr(); CloseDialog(); + if (!weak_this) { + return; + } if (!request_) { return; @@ -163,7 +171,12 @@ void SecurePaymentConfirmationController::OnAnotherWay() { SecurePaymentRequestOutcome::kAnotherWay); is_dialog_showing_ = false; + // CloseDialog() can synchronously delete `this`. See OnConfirm() above. + auto weak_this = weak_ptr_factory_.GetWeakPtr(); CloseDialog(); + if (!weak_this) { + return; + } if (!request_) { return; @@ -189,7 +202,12 @@ void SecurePaymentConfirmationController::OnCancel() { } is_dialog_showing_ = false; + // CloseDialog() can synchronously delete `this`. See OnConfirm() above. + auto weak_this = weak_ptr_factory_.GetWeakPtr(); CloseDialog(); + if (!weak_this) { + return; + } if (!request_) { return; @@ -209,7 +227,12 @@ void SecurePaymentConfirmationController::OnOptOut() { } is_dialog_showing_ = false; + // CloseDialog() can synchronously delete `this`. See OnConfirm() above. + auto weak_this = weak_ptr_factory_.GetWeakPtr(); CloseDialog(); + if (!weak_this) { + return; + } if (!request_) { return;