diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/DocumentWriter.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/loader/DocumentWriter.cpp')
-rw-r--r-- | Source/WebCore/loader/DocumentWriter.cpp | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/Source/WebCore/loader/DocumentWriter.cpp b/Source/WebCore/loader/DocumentWriter.cpp index 742eb9907..24b214cd3 100644 --- a/Source/WebCore/loader/DocumentWriter.cpp +++ b/Source/WebCore/loader/DocumentWriter.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2010. Adam Barth. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -29,6 +30,7 @@ #include "config.h" #include "DocumentWriter.h" +#include "ContentSecurityPolicy.h" #include "DOMImplementation.h" #include "DOMWindow.h" #include "Frame.h" @@ -36,26 +38,25 @@ #include "FrameLoaderClient.h" #include "FrameLoaderStateMachine.h" #include "FrameView.h" +#include "MIMETypeRegistry.h" +#include "MainFrame.h" #include "PluginDocument.h" #include "RawDataDocumentParser.h" #include "ScriptController.h" #include "ScriptableDocumentParser.h" #include "SecurityOrigin.h" +#include "SecurityOriginPolicy.h" #include "SegmentedString.h" #include "Settings.h" #include "SinkDocument.h" #include "TextResourceDecoder.h" #include <wtf/Ref.h> -#if PLATFORM(IOS) -#include "PDFDocument.h" -#endif - namespace WebCore { static inline bool canReferToParentFrameEncoding(const Frame* frame, const Frame* parentFrame) { - return parentFrame && parentFrame->document()->securityOrigin()->canAccess(frame->document()->securityOrigin()); + return parentFrame && parentFrame->document()->securityOrigin().canAccess(frame->document()->securityOrigin()); } DocumentWriter::DocumentWriter(Frame* frame) @@ -72,12 +73,23 @@ DocumentWriter::DocumentWriter(Frame* frame) void DocumentWriter::replaceDocument(const String& source, Document* ownerDocument) { m_frame->loader().stopAllLoaders(); + + // If we are in the midst of changing the frame's document, don't execute script + // that modifies the document further: + if (m_frame->documentIsBeingReplaced()) + return; + begin(m_frame->document()->url(), true, ownerDocument); + // begin() might fire an unload event, which will result in a situation where no new document has been attached, + // and the old document has been detached. Therefore, bail out if no document is attached. + if (!m_frame->document()) + return; + if (!source.isNull()) { if (!m_hasReceivedSomeData) { m_hasReceivedSomeData = true; - m_frame->document()->setCompatibilityMode(Document::NoQuirksMode); + m_frame->document()->setCompatibilityMode(DocumentCompatibilityMode::NoQuirksMode); } // FIXME: This should call DocumentParser::appendBytes instead of append @@ -91,7 +103,7 @@ void DocumentWriter::replaceDocument(const String& source, Document* ownerDocume void DocumentWriter::clear() { - m_decoder = 0; + m_decoder = nullptr; m_hasReceivedSomeData = false; if (!m_encodingWasChosenByUser) m_encoding = String(); @@ -102,17 +114,17 @@ void DocumentWriter::begin() begin(URL()); } -PassRefPtr<Document> DocumentWriter::createDocument(const URL& url) +Ref<Document> DocumentWriter::createDocument(const URL& url) { - if (!m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->loader().client().shouldAlwaysUsePluginDocument(m_mimeType)) + if (!m_frame->loader().stateMachine().isDisplayingInitialEmptyDocument() && m_frame->loader().client().shouldAlwaysUsePluginDocument(m_mimeType)) return PluginDocument::create(m_frame, url); #if PLATFORM(IOS) - if (equalIgnoringCase(m_mimeType, "application/pdf")) - return PDFDocument::create(m_frame, url); + if (MIMETypeRegistry::isPDFMIMEType(m_mimeType) && (m_frame->isMainFrame() || !m_frame->settings().useImageDocumentForSubframePDF())) + return SinkDocument::create(m_frame, url); #endif if (!m_frame->loader().client().hasHTMLView()) return Document::createNonRenderedPlaceholder(m_frame, url); - return DOMImplementation::createDocument(m_mimeType, m_frame, url, m_frame->inViewSourceMode()); + return DOMImplementation::createDocument(m_mimeType, m_frame, url); } void DocumentWriter::begin(const URL& urlReference, bool dispatch, Document* ownerDocument) @@ -124,7 +136,7 @@ void DocumentWriter::begin(const URL& urlReference, bool dispatch, Document* own // Create a new document before clearing the frame, because it may need to // inherit an aliased security context. - RefPtr<Document> document = createDocument(url); + Ref<Document> document = createDocument(url); // If the new document is for a Plugin but we're supposed to be sandboxed from Plugins, // then replace the document with one whose parser will ignore the incoming data (bug 39323) @@ -133,26 +145,42 @@ void DocumentWriter::begin(const URL& urlReference, bool dispatch, Document* own // FIXME: Do we need to consult the content security policy here about blocked plug-ins? - bool shouldReuseDefaultView = m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->document()->isSecureTransitionTo(url); + bool shouldReuseDefaultView = m_frame->loader().stateMachine().isDisplayingInitialEmptyDocument() && m_frame->document()->isSecureTransitionTo(url); if (shouldReuseDefaultView) document->takeDOMWindowFrom(m_frame->document()); else document->createDOMWindow(); - m_frame->loader().clear(document.get(), !shouldReuseDefaultView, !shouldReuseDefaultView); + // Per <http://www.w3.org/TR/upgrade-insecure-requests/>, we need to retain an ongoing set of upgraded + // requests in new navigation contexts. Although this information is present when we construct the + // Document object, it is discard in the subsequent 'clear' statements below. So, we must capture it + // so we can restore it. + HashSet<RefPtr<SecurityOrigin>> insecureNavigationRequestsToUpgrade; + if (auto* existingDocument = m_frame->document()) + insecureNavigationRequestsToUpgrade = existingDocument->contentSecurityPolicy()->takeNavigationRequestsToUpgrade(); + + m_frame->loader().clear(document.ptr(), !shouldReuseDefaultView, !shouldReuseDefaultView); clear(); + // m_frame->loader().clear() might fire unload event which could remove the view of the document. + // Bail out if document has no view. + if (!document->view()) + return; + if (!shouldReuseDefaultView) m_frame->script().updatePlatformScriptObjects(); m_frame->loader().setOutgoingReferrer(url); - m_frame->setDocument(document); + m_frame->setDocument(document.copyRef()); + + document->contentSecurityPolicy()->setInsecureNavigationRequestsToUpgrade(WTFMove(insecureNavigationRequestsToUpgrade)); if (m_decoder) document->setDecoder(m_decoder.get()); if (ownerDocument) { document->setCookieURL(ownerDocument->cookieURL()); - document->setSecurityOrigin(ownerDocument->securityOrigin()); + document->setSecurityOriginPolicy(ownerDocument->securityOriginPolicy()); + document->setStrictMixedContentMode(ownerDocument->isStrictMixedContentMode()); } m_frame->loader().didBeginDocument(dispatch); @@ -190,7 +218,7 @@ TextResourceDecoder* DocumentWriter::createDecoderIfNeeded() m_decoder->setHintEncoding(parentFrame->document()->decoder()); if (m_encoding.isEmpty()) { if (canReferToParentFrameEncoding(m_frame, parentFrame)) - m_decoder->setEncoding(parentFrame->document()->inputEncoding(), TextResourceDecoder::EncodingFromParentFrame); + m_decoder->setEncoding(parentFrame->document()->textEncoding(), TextResourceDecoder::EncodingFromParentFrame); } else { m_decoder->setEncoding(m_encoding, m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader); @@ -246,7 +274,7 @@ void DocumentWriter::end() if (!m_parser) return; m_parser->finish(); - m_parser = 0; + m_parser = nullptr; } void DocumentWriter::setEncoding(const String& name, bool userChosen) |