From 6fb392ee9e4c185861e9b0d7010b174364f86673 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Mon, 20 Jan 2014 18:26:37 +0100 Subject: Clear callbacks with an empty value on page destruction The current implementation offers no way to cancel async requests. This means that normal applications could easily allow callbacks to dereference a destroyed object unless they use a smart pointer within the callback function object. This patch will empty the pending callback list by calling each of them with an empty value. This will at least allow applications to cover the cases where the page is expected to have a shorter or equal lifetime than objects referenced in the callback. Change-Id: Ia9fc556b03f5d83f904a0ff4b05dc9e440ea488c Reviewed-by: Pierre Rossi --- src/webenginewidgets/api/qwebenginepage.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 1a3cf5dde..d05a43d0d 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -58,6 +58,15 @@ QWebEnginePagePrivate::QWebEnginePagePrivate() QWebEnginePagePrivate::~QWebEnginePagePrivate() { + // "Cancel" pending callbacks by calling them with an invalid value. + // This guarantees that each callback is called exactly once. + Q_FOREACH (QExplicitlySharedDataPointer callback, m_variantCallbacks) + (*callback)(QVariant()); + m_variantCallbacks.clear(); + Q_FOREACH (QExplicitlySharedDataPointer callback, m_stringCallbacks) + (*callback)(QString()); + m_stringCallbacks.clear(); + delete history; } @@ -148,17 +157,20 @@ void QWebEnginePagePrivate::close() void QWebEnginePagePrivate::didRunJavaScript(const QVariant& result, quint64 requestId) { - (*m_variantCallbacks.take(requestId))(result); + if (QExplicitlySharedDataPointer callback = m_variantCallbacks.take(requestId)) + (*callback)(result); } void QWebEnginePagePrivate::didFetchDocumentMarkup(const QString& result, quint64 requestId) { - (*m_stringCallbacks.take(requestId))(result); + if (QExplicitlySharedDataPointer callback = m_stringCallbacks.take(requestId)) + (*callback)(result); } void QWebEnginePagePrivate::didFetchDocumentInnerText(const QString& result, quint64 requestId) { - (*m_stringCallbacks.take(requestId))(result); + if (QExplicitlySharedDataPointer callback = m_stringCallbacks.take(requestId)) + (*callback)(result); } void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const -- cgit v1.2.3