diff options
author | Peter Varga <pvarga@inf.u-szeged.hu> | 2016-11-02 18:20:14 +0100 |
---|---|---|
committer | Peter Varga <pvarga@inf.u-szeged.hu> | 2016-11-08 06:38:35 +0000 |
commit | c15c0f5620a15996f4d178e628f5bd401ab34279 (patch) | |
tree | ed98770592da59c7b79f3e01b1a6ff8b2aec87e8 | |
parent | 4abee8c89a47592fecd4c0f9247efa600710a06b (diff) |
Fix crash when trying to execute script on a detached RenderFrame
Task-number: QTBUG-56661
Change-Id: I546222dde64c54955c62d2c30df79d4773b9973c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | src/core/renderer/content_renderer_client_qt.cpp | 12 | ||||
-rw-r--r-- | src/core/renderer/render_frame_observer_qt.cpp | 12 | ||||
-rw-r--r-- | src/core/renderer/render_frame_observer_qt.h | 11 | ||||
-rw-r--r-- | src/core/renderer/web_channel_ipc_transport.cpp | 3 | ||||
-rw-r--r-- | tests/auto/quick/qmltests/BLACKLIST | 3 | ||||
-rw-r--r-- | tests/auto/quick/qmltests/data/tst_loadUrl.qml | 31 |
6 files changed, 54 insertions, 18 deletions
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index a6e35f4be..69f5bfefe 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -135,6 +135,12 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_fr void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame* render_frame) { + // Check whether the render_frame has been created and has not been detached yet. + // Otherwise the WebFrame is not available. + RenderFrameObserverQt *render_frame_observer = RenderFrameObserverQt::Get(render_frame); + if (!render_frame_observer || render_frame_observer->isFrameDetached()) + return; // The frame is invisible to scripts. + if (WebChannelIPCTransport *transport = WebChannelIPCTransport::Get(render_frame->GetRenderView())) transport->RunScriptsAtDocumentStart(render_frame); UserResourceController::instance()->RunScriptsAtDocumentStart(render_frame); @@ -142,6 +148,12 @@ void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame* re void ContentRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) { + // Check whether the render_frame has been created and has not been detached yet. + // Otherwise the WebFrame is not available. + RenderFrameObserverQt *render_frame_observer = RenderFrameObserverQt::Get(render_frame); + if (!render_frame_observer || render_frame_observer->isFrameDetached()) + return; // The frame is invisible to scripts. + UserResourceController::instance()->RunScriptsAtDocumentEnd(render_frame); } diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp index 77bc89f67..53e9407db 100644 --- a/src/core/renderer/render_frame_observer_qt.cpp +++ b/src/core/renderer/render_frame_observer_qt.cpp @@ -55,6 +55,8 @@ namespace QtWebEngineCore { RenderFrameObserverQt::RenderFrameObserverQt(content::RenderFrame* render_frame) : RenderFrameObserver(render_frame) + , RenderFrameObserverTracker<RenderFrameObserverQt>(render_frame) + , m_isFrameDetached(false) { } @@ -72,4 +74,14 @@ void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost* ho } #endif +void RenderFrameObserverQt::FrameDetached() +{ + m_isFrameDetached = true; +} + +bool RenderFrameObserverQt::isFrameDetached() const +{ + return m_isFrameDetached; +} + } // namespace QtWebEngineCore diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h index c59b7babc..b74be5cd1 100644 --- a/src/core/renderer/render_frame_observer_qt.h +++ b/src/core/renderer/render_frame_observer_qt.h @@ -42,6 +42,7 @@ #include "base/compiler_specific.h" #include "content/public/renderer/render_frame_observer.h" +#include "content/public/renderer/render_frame_observer_tracker.h" namespace content { @@ -50,7 +51,10 @@ class RenderFrame; namespace QtWebEngineCore { -class RenderFrameObserverQt : public content::RenderFrameObserver { +class RenderFrameObserverQt + : public content::RenderFrameObserver + , public content::RenderFrameObserverTracker<RenderFrameObserverQt> +{ public: explicit RenderFrameObserverQt(content::RenderFrame* render_frame); ~RenderFrameObserverQt(); @@ -59,9 +63,14 @@ public: void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; #endif void OnDestruct() override { } + void FrameDetached() override; + + bool isFrameDetached() const; private: DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt); + + bool m_isFrameDetached; }; } // namespace QtWebEngineCore diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index 3a44bb182..2ca6640c6 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -164,9 +164,8 @@ void WebChannelIPCTransport::RunScriptsAtDocumentStart(content::RenderFrame *ren { // JavaScript run before this point doesn't stick, and needs to be redone. // ### FIXME: we should try no even installing before - blink::WebLocalFrame *frame = render_frame->GetWebFrame(); if (m_installed && render_frame->IsMainFrame()) - WebChannelTransport::Install(frame, m_installedWorldId); + WebChannelTransport::Install(render_frame->GetWebFrame(), m_installedWorldId); } diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST index a993fcd32..dea9f3ca1 100644 --- a/tests/auto/quick/qmltests/BLACKLIST +++ b/tests/auto/quick/qmltests/BLACKLIST @@ -9,6 +9,3 @@ osx [WebViewGeopermission::test_geoPermissionRequest] osx - -[WebEngineViewLoadUrl::test_loadDataUrl] -windows diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml index 49db85a3e..2a43e1577 100644 --- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml +++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml @@ -189,13 +189,6 @@ TestWebEngineView { var loadRequest = null; // Test load of a data URL - // QTBUG-56661: Loading an URL before the data URL load improves the probability - // of the render process crash after the data URL load. - var url = Qt.resolvedUrl("test1.html"); - webEngineView.url = url; - verify(webEngineView.waitForLoadSucceeded()); - webEngineView.clear(); - var dataUrl = "data:text/html,foo"; webEngineView.url = dataUrl; tryCompare(loadRequestArray, "length", 2); @@ -208,11 +201,6 @@ TestWebEngineView { compare(loadRequest.activeUrl, dataUrl); webEngineView.clear(); - // QTBUG-56661: This load might fail on Windows - webEngineView.url = url; - verify(webEngineView.waitForLoadSucceeded()); - webEngineView.clear(); - // Test loadHtml after a failed load var aboutBlank = "about:blank"; webEngineView.url = aboutBlank; // Reset from previous test @@ -249,6 +237,25 @@ TestWebEngineView { webEngineView.clear(); } + function test_QTBUG_56661() { + var url = Qt.resolvedUrl("test1.html"); + + // Warm up phase + webEngineView.url = url; + verify(webEngineView.waitForLoadSucceeded()); + + // Load data URL + var dataUrl = "data:text/html,foo"; + webEngineView.url = dataUrl; + verify(webEngineView.waitForLoadSucceeded()); + + // WebEngine should not try to execute user scripts in the + // render frame of the warm up phase otherwise the renderer + // crashes. + webEngineView.url = url; + verify(webEngineView.waitForLoadSucceeded()); + } + function test_stopStatus() { var loadRequest = null; |