From ea21c1ecb284c6b3b954fcc5af99a9fbc1e91b4b Mon Sep 17 00:00:00 2001 From: "achristensen@apple.com" Date: Sat, 25 Jul 2020 03:10:18 +0000 Subject: [PATCH] Null check frame in Document::dispatchDisabledAdaptationsDidChangeForMainFrame and a few other places https://bugs.webkit.org/show_bug.cgi?id=214715 Reviewed by Geoffrey Garen. Source/WebCore: Test: security/mutation-observer-frame-detach.html * dom/Document.cpp: (WebCore::Document::didBecomeCurrentDocumentInFrame): (WebCore::Document::initContentSecurityPolicy): * loader/DocumentLoader.cpp: (WebCore::DocumentLoader::commitData): Add some null checks and early returns if the frame detaches. * loader/SubframeLoader.cpp: (WebCore::FrameLoader::SubframeLoader::loadSubframe): Balance the call to incrementLoadEventDelayCount in the early return case or this test never finishes loading. LayoutTests: * security/mutation-observer-frame-detach-expected.txt: Added. * security/mutation-observer-frame-detach.html: Added. git-svn-id: https://svn.webkit.org/repository/webkit/trunk@264880 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 11 +++++++ ...utation-observer-frame-detach-expected.txt | 2 ++ .../mutation-observer-frame-detach.html | 29 +++++++++++++++++++ Source/WebCore/ChangeLog | 20 +++++++++++++ Source/WebCore/dom/Document.cpp | 18 ++++++++++-- Source/WebCore/loader/DocumentLoader.cpp | 5 +++- 6 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 LayoutTests/security/mutation-observer-frame-detach-expected.txt create mode 100644 LayoutTests/security/mutation-observer-frame-detach.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 6aa38abc0b43..e3fd183b87c7 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,14 @@ +2020-07-24 Alex Christensen + + Null check frame in Document::dispatchDisabledAdaptationsDidChangeForMainFrame and a few other places + https://bugs.webkit.org/show_bug.cgi?id=214715 + + + Reviewed by Geoffrey Garen. + + * security/mutation-observer-frame-detach-expected.txt: Added. + * security/mutation-observer-frame-detach.html: Added. + 2020-07-24 Alex Christensen Fix assertion when highlighting in detached frames and make loads complete diff --git a/LayoutTests/security/mutation-observer-frame-detach-expected.txt b/LayoutTests/security/mutation-observer-frame-detach-expected.txt new file mode 100644 index 000000000000..aec03005a1ea --- /dev/null +++ b/LayoutTests/security/mutation-observer-frame-detach-expected.txt @@ -0,0 +1,2 @@ +ALERT: test passed because nothing crashed + diff --git a/LayoutTests/security/mutation-observer-frame-detach.html b/LayoutTests/security/mutation-observer-frame-detach.html new file mode 100644 index 000000000000..a5f63518c8a7 --- /dev/null +++ b/LayoutTests/security/mutation-observer-frame-detach.html @@ -0,0 +1,29 @@ + + +

+

+ +

+

+ diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 307ae6f58562..49a267eab05c 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,23 @@ +2020-07-24 Alex Christensen + + Null check frame in Document::dispatchDisabledAdaptationsDidChangeForMainFrame and a few other places + https://bugs.webkit.org/show_bug.cgi?id=214715 + + + Reviewed by Geoffrey Garen. + + Test: security/mutation-observer-frame-detach.html + + * dom/Document.cpp: + (WebCore::Document::didBecomeCurrentDocumentInFrame): + (WebCore::Document::initContentSecurityPolicy): + * loader/DocumentLoader.cpp: + (WebCore::DocumentLoader::commitData): + Add some null checks and early returns if the frame detaches. + * loader/SubframeLoader.cpp: + (WebCore::FrameLoader::SubframeLoader::loadSubframe): + Balance the call to incrementLoadEventDelayCount in the early return case or this test never finishes loading. + 2020-07-24 Alex Christensen Fix assertion when highlighting in detached frames and make loads complete diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 48927c36efaa..3d742e719d85 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -2386,16 +2386,24 @@ void Document::createRenderTree() void Document::didBecomeCurrentDocumentInFrame() { - // FIXME: Are there cases where the document can be dislodged from the frame during the event handling below? - // If so, then m_frame could become 0, and we need to do something about that. - m_frame->script().updateDocument(); + // Many of these functions have event handlers which can detach the frame synchronously, so we must check repeatedly in this function. + if (!m_frame) + return; + if (!hasLivingRenderTree()) createRenderTree(); + if (!m_frame) + return; dispatchDisabledAdaptationsDidChangeForMainFrame(); + if (!m_frame) + return; + updateViewportArguments(); + if (!m_frame) + return; // FIXME: Doing this only for the main frame is insufficient. // Changing a subframe can also change the wheel event handler count. @@ -2406,6 +2414,8 @@ void Document::didBecomeCurrentDocumentInFrame() // unless the documents they are replacing had wheel event handlers. if (page() && m_frame->isMainFrame()) wheelEventHandlersChanged(); + if (!m_frame) + return; // Ensure that the scheduled task state of the document matches the DOM suspension state of the frame. It can // be out of sync if the DOM suspension state changed while the document was not in the frame (possibly in the @@ -6098,6 +6108,8 @@ void Document::initSecurityContext() void Document::initContentSecurityPolicy() { + if (!m_frame) + return; auto* parentFrame = m_frame->tree().parent(); if (parentFrame) contentSecurityPolicy()->copyUpgradeInsecureRequestStateFrom(*parentFrame->document()->contentSecurityPolicy()); diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp index 2fc21498c0b1..408a13e374be 100644 --- a/Source/WebCore/loader/DocumentLoader.cpp +++ b/Source/WebCore/loader/DocumentLoader.cpp @@ -1087,7 +1087,10 @@ void DocumentLoader::commitData(const char* bytes, size_t length) bool hasBegun = m_writer.begin(documentURL(), false); m_writer.setDocumentWasLoadedAsPartOfNavigation(); - auto& document = *m_frame->document(); + auto* documentOrNull = m_frame ? m_frame->document() : nullptr; + if (!documentOrNull) + return; + auto& document = *documentOrNull; if (SecurityPolicy::allowSubstituteDataAccessToLocal() && m_originalSubstituteDataWasValid) { // If this document was loaded with substituteData, then the document can -- 2.36.0