summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/DocumentWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader/DocumentWriter.cpp')
-rw-r--r--Source/WebCore/loader/DocumentWriter.cpp68
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)