diff options
4 files changed, 73 insertions, 15 deletions
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc index b7e06c2c288..34f7fb2b64b 100644 --- a/chromium/content/renderer/render_frame_impl.cc +++ b/chromium/content/renderer/render_frame_impl.cc @@ -3617,8 +3617,17 @@ blink::BlameContext* RenderFrameImpl::GetFrameBlameContext() { std::unique_ptr<blink::WebServiceWorkerProvider> RenderFrameImpl::CreateServiceWorkerProvider() { + // Bail-out if we are about to be navigated away. + // We check that DocumentLoader is attached since: + // - This serves as the signal since the DocumentLoader is detached in + // FrameLoader::PrepareForCommit(). + // - Creating ServiceWorkerProvider in + // RenderFrameImpl::CreateServiceWorkerProvider() assumes that there is a + // DocumentLoader attached to the frame. + if (!frame_->GetDocumentLoader()) + return nullptr; + // At this point we should have non-null data source. - DCHECK(frame_->GetDocumentLoader()); if (!ChildThreadImpl::current()) return nullptr; // May be null in some tests. ServiceWorkerNetworkProvider* provider = diff --git a/chromium/third_party/WebKit/Source/core/frame/History.cpp b/chromium/third_party/WebKit/Source/core/frame/History.cpp index 8b1156ce437..cdb9bc62d4b 100644 --- a/chromium/third_party/WebKit/Source/core/frame/History.cpp +++ b/chromium/third_party/WebKit/Source/core/frame/History.cpp @@ -86,21 +86,30 @@ SerializedScriptValue* History::state(ExceptionState& exception_state) { } SerializedScriptValue* History::StateInternal() const { - if (!GetFrame()) + LocalFrame* frame = GetFrame(); + if (!frame) return nullptr; - if (HistoryItem* history_item = - GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem()) { - return history_item->StateObject(); - } + // TODO(kouhei, dcheng): The DocumentLoader null check should be unnecessary. + // Investigate and see if it can be removed. + DocumentLoader* document_loader = frame->Loader().GetDocumentLoader(); + if (!document_loader) + return nullptr; + + HistoryItem* history_item = document_loader->GetHistoryItem(); + if (!history_item) + return nullptr; - return nullptr; + return history_item->StateObject(); } void History::setScrollRestoration(const String& value, ExceptionState& exception_state) { DCHECK(value == "manual" || value == "auto"); - if (!GetFrame() || !GetFrame()->Client()) { + // TODO(kouhei, dcheng): The DocumentLoader null check should be unnecessary. + // Investigate and see if it can be removed. + if (!GetFrame() || !GetFrame()->Client() || + !GetFrame()->Loader().GetDocumentLoader()) { exception_state.ThrowSecurityError( "May not use a History object associated with a Document that is not " "fully active"); @@ -131,11 +140,23 @@ String History::scrollRestoration(ExceptionState& exception_state) { } HistoryScrollRestorationType History::ScrollRestorationInternal() const { - HistoryItem* history_item = - GetFrame() ? GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem() - : nullptr; - return history_item ? history_item->ScrollRestorationType() - : kScrollRestorationAuto; + constexpr HistoryScrollRestorationType default_type = kScrollRestorationAuto; + + LocalFrame* frame = GetFrame(); + if (!frame) + return default_type; + + // TODO(kouhei, dcheng): The DocumentLoader null check should be unnecessary. + // Investigate and see if it can be removed. + DocumentLoader* document_loader = frame->Loader().GetDocumentLoader(); + if (!document_loader) + return default_type; + + HistoryItem* history_item = document_loader->GetHistoryItem(); + if (!history_item) + return default_type; + + return history_item->ScrollRestorationType(); } // TODO(crbug.com/394296): This is not the long-term fix to IPC flooding that we diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp index f0b1f6e9d63..7d63d6594e1 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp @@ -80,7 +80,9 @@ #include "platform/InstanceCounters.h" #include "platform/WebFrameScheduler.h" #include "platform/bindings/DOMWrapperWorld.h" +#include "platform/bindings/Microtask.h" #include "platform/bindings/ScriptForbiddenScope.h" +#include "platform/bindings/V8PerIsolateData.h" #include "platform/instrumentation/tracing/TraceEvent.h" #include "platform/loader/fetch/ResourceFetcher.h" #include "platform/loader/fetch/ResourceRequest.h" @@ -1079,6 +1081,14 @@ bool FrameLoader::PrepareForCommit() { if (!frame_->Client()) return false; DCHECK_EQ(provisional_document_loader_, pdl); + + // Flush microtask queue so that they all run on pre-navigation context. + Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate()); + + // Ensure that the frame_ hasn't detached from running the microtasks. + if (!frame_->Client()) + return false; + // No more events will be dispatched so detach the Document. // TODO(yoav): Should we also be nullifying domWindow's document (or // domWindow) since the doc is now detached? diff --git a/chromium/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp b/chromium/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp index b2eff50e339..637665bb459 100644 --- a/chromium/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp +++ b/chromium/third_party/WebKit/Source/modules/serviceworkers/NavigatorServiceWorker.cpp @@ -18,9 +18,27 @@ namespace blink { NavigatorServiceWorker::NavigatorServiceWorker(Navigator& navigator) {} NavigatorServiceWorker* NavigatorServiceWorker::From(Document& document) { - if (!document.GetFrame() || !document.GetFrame()->DomWindow()) + LocalFrame* frame = document.GetFrame(); + if (!frame) return nullptr; - Navigator& navigator = *document.GetFrame()->DomWindow()->navigator(); + + // TODO(kouhei): Remove below after M72, since the check is now done in + // RenderFrameImpl::CreateServiceWorkerProvider instead. + // + // Bail-out if we are about to be navigated away. + // We check that DocumentLoader is attached since: + // - This serves as the signal since the DocumentLoader is detached in + // FrameLoader::PrepareForCommit(). + // - Creating ServiceWorkerProvider in + // RenderFrameImpl::CreateServiceWorkerProvider() assumes that there is a + // DocumentLoader attached to the frame. + if (!frame->Loader().GetDocumentLoader()) + return nullptr; + + LocalDOMWindow* dom_window = frame->DomWindow(); + if (!dom_window) + return nullptr; + Navigator& navigator = *dom_window->navigator(); return &From(navigator); } |