From 0058d5b9dd56ba0453be3297231484917441f7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Fri, 27 Jun 2014 17:40:49 +0200 Subject: Prevent premature deletion of JavaScript alert dialog object. This fixes a crash on Windows when dismissing a JavaScript dialog. It was caused by the JavaScriptDialogController object deleting itself and its private object from a method call and subsequently trying to run the JavaScript dialog callback. Task-number: QTBUG-39883 Change-Id: I74300c53943ec7ebc492362ef7d75d83aa1f8051 Reviewed-by: Pierre Rossi --- src/core/javascript_dialog_controller.cpp | 5 +++-- src/core/javascript_dialog_manager_qt.cpp | 6 +++--- src/core/javascript_dialog_manager_qt.h | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/core/javascript_dialog_controller.cpp b/src/core/javascript_dialog_controller.cpp index c3c133a0d..d789b184f 100644 --- a/src/core/javascript_dialog_controller.cpp +++ b/src/core/javascript_dialog_controller.cpp @@ -47,8 +47,9 @@ void JavaScriptDialogControllerPrivate::dialogFinished(bool accepted, const base::string16 &promptValue) { - // Clear the queue first as this could result in the engine asking us to run another dialog. - JavaScriptDialogManagerQt::GetInstance()->removeDialogForContents(contents); + // Clear the queue first as this could result in the engine asking us to run another dialog, + // but hold a shared pointer so the dialog does not get deleted prematurely when running in-process. + QSharedPointer dialog = JavaScriptDialogManagerQt::GetInstance()->takeDialogForContents(contents); callback.Run(accepted, promptValue); } diff --git a/src/core/javascript_dialog_manager_qt.cpp b/src/core/javascript_dialog_manager_qt.cpp index bd528af95..f886a20d9 100644 --- a/src/core/javascript_dialog_manager_qt.cpp +++ b/src/core/javascript_dialog_manager_qt.cpp @@ -76,7 +76,7 @@ bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *con if (!dialog) return false; dialog->d->dialogFinished(accept, promptOverride ? *promptOverride : base::string16()); - removeDialogForContents(contents); + takeDialogForContents(contents); return true; } @@ -99,10 +99,10 @@ void JavaScriptDialogManagerQt::runDialogForContents(content::WebContents *webCo } - -void JavaScriptDialogManagerQt::removeDialogForContents(content::WebContents *contents) +QSharedPointer JavaScriptDialogManagerQt::takeDialogForContents(content::WebContents *contents) { QSharedPointer dialog = m_activeDialogs.take(contents); if (dialog) Q_EMIT dialog->dialogCloseRequested(); + return dialog; } diff --git a/src/core/javascript_dialog_manager_qt.h b/src/core/javascript_dialog_manager_qt.h index 518ceca53..659b6e95e 100644 --- a/src/core/javascript_dialog_manager_qt.h +++ b/src/core/javascript_dialog_manager_qt.h @@ -68,13 +68,13 @@ public: virtual void RunBeforeUnloadDialog(content::WebContents *, const base::string16 &messageText, bool isReload, const content::JavaScriptDialogManager::DialogClosedCallback &callback) Q_DECL_OVERRIDE { Q_UNUSED(messageText); Q_UNUSED(isReload); Q_UNUSED(callback); } virtual bool HandleJavaScriptDialog(content::WebContents *, bool accept, const base::string16 *promptOverride) Q_DECL_OVERRIDE; - virtual void CancelActiveAndPendingDialogs(content::WebContents *contents) Q_DECL_OVERRIDE { removeDialogForContents(contents); } - virtual void WebContentsDestroyed(content::WebContents *contents) Q_DECL_OVERRIDE { removeDialogForContents(contents); } + virtual void CancelActiveAndPendingDialogs(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); } + virtual void WebContentsDestroyed(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); } void runDialogForContents(content::WebContents *, WebContentsAdapterClient::JavascriptDialogType, const QString &messageText, const QString &defaultPrompt , const QUrl &,const content::JavaScriptDialogManager::DialogClosedCallback &callback, const QString &title = QString()); - void removeDialogForContents(content::WebContents *); + QSharedPointer takeDialogForContents(content::WebContents *); private: QMap > m_activeDialogs; -- cgit v1.2.3