Fix crash when using CefJSDialogHandler with the default dialog implementation (issue #2329)

This commit is contained in:
Marshall Greenblatt
2017-12-21 16:47:20 -05:00
parent 2fe9f7bd31
commit f052e282dd

View File

@ -19,9 +19,9 @@ namespace {
class CefJSDialogCallbackImpl : public CefJSDialogCallback { class CefJSDialogCallbackImpl : public CefJSDialogCallback {
public: public:
CefJSDialogCallbackImpl( using Callback = content::JavaScriptDialogManager::DialogClosedCallback;
content::JavaScriptDialogManager::DialogClosedCallback callback)
: callback_(std::move(callback)) {} CefJSDialogCallbackImpl(Callback callback) : callback_(std::move(callback)) {}
~CefJSDialogCallbackImpl() override { ~CefJSDialogCallbackImpl() override {
if (!callback_.is_null()) { if (!callback_.is_null()) {
// The callback is still pending. Cancel it now. // The callback is still pending. Cancel it now.
@ -45,16 +45,15 @@ class CefJSDialogCallbackImpl : public CefJSDialogCallback {
} }
} }
void Disconnect() { callback_.Reset(); } Callback Disconnect() WARN_UNUSED_RESULT { return std::move(callback_); }
private: private:
static void CancelNow( static void CancelNow(Callback callback) {
content::JavaScriptDialogManager::DialogClosedCallback callback) {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
std::move(callback).Run(false, base::string16()); std::move(callback).Run(false, base::string16());
} }
content::JavaScriptDialogManager::DialogClosedCallback callback_; Callback callback_;
IMPLEMENT_REFCOUNTING(CefJSDialogCallbackImpl); IMPLEMENT_REFCOUNTING(CefJSDialogCallbackImpl);
}; };
@ -106,8 +105,9 @@ void CefJavaScriptDialogManager::RunJavaScriptDialog(
return; return;
} }
callbackPtr->Disconnect(); // |callback| may be null if the user executed it despite returning false.
if (*did_suppress_message) callback = callbackPtr->Disconnect();
if (callback.is_null() || *did_suppress_message)
return; return;
} }
} }
@ -128,6 +128,7 @@ void CefJavaScriptDialogManager::RunJavaScriptDialog(
const base::string16& display_url = const base::string16& display_url =
url_formatter::FormatUrlForSecurityDisplay(origin_url); url_formatter::FormatUrlForSecurityDisplay(origin_url);
DCHECK(!callback.is_null());
runner_->Run(browser_, message_type, display_url, message_text, runner_->Run(browser_, message_type, display_url, message_text,
default_prompt_text, default_prompt_text,
base::Bind(&CefJavaScriptDialogManager::DialogClosed, base::Bind(&CefJavaScriptDialogManager::DialogClosed,
@ -164,7 +165,10 @@ void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
if (handled) if (handled)
return; return;
callbackPtr->Disconnect(); // |callback| may be null if the user executed it despite returning false.
callback = callbackPtr->Disconnect();
if (callback.is_null())
return;
} }
} }
@ -179,6 +183,7 @@ void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
dialog_running_ = true; dialog_running_ = true;
DCHECK(!callback.is_null());
runner_->Run(browser_, content::JAVASCRIPT_DIALOG_TYPE_CONFIRM, runner_->Run(browser_, content::JAVASCRIPT_DIALOG_TYPE_CONFIRM,
base::string16(), // display_url base::string16(), // display_url
message_text, message_text,