diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/loader/DocumentWriter.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/loader/DocumentWriter.cpp')
-rw-r--r-- | Source/WebCore/loader/DocumentWriter.cpp | 113 |
1 files changed, 61 insertions, 52 deletions
diff --git a/Source/WebCore/loader/DocumentWriter.cpp b/Source/WebCore/loader/DocumentWriter.cpp index 749caa497..442e3bf57 100644 --- a/Source/WebCore/loader/DocumentWriter.cpp +++ b/Source/WebCore/loader/DocumentWriter.cpp @@ -10,7 +10,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. * @@ -36,16 +36,19 @@ #include "FrameLoaderClient.h" #include "FrameLoaderStateMachine.h" #include "FrameView.h" -#include "PlaceholderDocument.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> namespace WebCore { @@ -67,23 +70,24 @@ DocumentWriter::DocumentWriter(Frame* frame) // This is the <iframe src="javascript:'html'"> case. void DocumentWriter::replaceDocument(const String& source, Document* ownerDocument) { - m_frame->loader()->stopAllLoaders(); + m_frame->loader().stopAllLoaders(); 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 // to support RawDataDocumentParsers. - if (DocumentParser* parser = m_frame->document()->parser()) { - parser->pinToMainThread(); - // Because we're pinned to the main thread we don't need to worry about - // passing ownership of the source string. + if (DocumentParser* parser = m_frame->document()->parser()) parser->append(source.impl()); - } } end(); @@ -91,7 +95,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(); @@ -99,28 +103,32 @@ void DocumentWriter::clear() void DocumentWriter::begin() { - begin(KURL()); + begin(URL()); } -PassRefPtr<Document> DocumentWriter::createDocument(const KURL& 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 (!m_frame->loader()->client()->hasHTMLView()) - return PlaceholderDocument::create(m_frame, url); - return DOMImplementation::createDocument(m_mimeType, m_frame, url, m_frame->inViewSourceMode()); +#if PLATFORM(IOS) + 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); } -void DocumentWriter::begin(const KURL& urlReference, bool dispatch, Document* ownerDocument) +void DocumentWriter::begin(const URL& urlReference, bool dispatch, Document* ownerDocument) { // We grab a local copy of the URL because it's easy for callers to supply // a URL that will be deallocated during the execution of this function. // For example, see <https://bugs.webkit.org/show_bug.cgi?id=66360>. - KURL url = urlReference; + URL url = urlReference; // 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) @@ -129,29 +137,34 @@ void DocumentWriter::begin(const KURL& urlReference, bool dispatch, Document* ow // 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); + 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->script().updatePlatformScriptObjects(); - m_frame->loader()->setOutgoingReferrer(url); - m_frame->setDocument(document); + m_frame->loader().setOutgoingReferrer(url); + m_frame->setDocument(document.copyRef()); if (m_decoder) document->setDecoder(m_decoder.get()); if (ownerDocument) { document->setCookieURL(ownerDocument->cookieURL()); - document->setSecurityOrigin(ownerDocument->securityOrigin()); + document->setSecurityOriginPolicy(ownerDocument->securityOriginPolicy()); } - m_frame->loader()->didBeginDocument(dispatch); + m_frame->loader().didBeginDocument(dispatch); document->implicitOpen(); @@ -160,7 +173,7 @@ void DocumentWriter::begin(const KURL& urlReference, bool dispatch, Document* ow // document.open). m_parser = document->parser(); - if (m_frame->view() && m_frame->loader()->client()->hasHTMLView()) + if (m_frame->view() && m_frame->loader().client().hasHTMLView()) m_frame->view()->setContentsSize(IntSize()); m_state = StartedWritingState; @@ -169,28 +182,24 @@ void DocumentWriter::begin(const KURL& urlReference, bool dispatch, Document* ow TextResourceDecoder* DocumentWriter::createDecoderIfNeeded() { if (!m_decoder) { - if (Settings* settings = m_frame->settings()) { - m_decoder = TextResourceDecoder::create(m_mimeType, - settings->defaultTextEncodingName(), - settings->usesEncodingDetector()); - Frame* parentFrame = m_frame->tree()->parent(); - // Set the hint encoding to the parent frame encoding only if - // the parent and the current frames share the security origin. - // We impose this condition because somebody can make a child frame - // containing a carefully crafted html/javascript in one encoding - // that can be mistaken for hintEncoding (or related encoding) by - // an auto detector. When interpreted in the latter, it could be - // an attack vector. - // FIXME: This might be too cautious for non-7bit-encodings and - // we may consider relaxing this later after testing. - if (canReferToParentFrameEncoding(m_frame, parentFrame)) - m_decoder->setHintEncoding(parentFrame->document()->decoder()); - } else - m_decoder = TextResourceDecoder::create(m_mimeType, String()); - Frame* parentFrame = m_frame->tree()->parent(); + m_decoder = TextResourceDecoder::create(m_mimeType, + m_frame->settings().defaultTextEncodingName(), + m_frame->settings().usesEncodingDetector()); + Frame* parentFrame = m_frame->tree().parent(); + // Set the hint encoding to the parent frame encoding only if + // the parent and the current frames share the security origin. + // We impose this condition because somebody can make a child frame + // containing a carefully crafted html/javascript in one encoding + // that can be mistaken for hintEncoding (or related encoding) by + // an auto detector. When interpreted in the latter, it could be + // an attack vector. + // FIXME: This might be too cautious for non-7bit-encodings and + // we may consider relaxing this later after testing. + if (canReferToParentFrameEncoding(m_frame, parentFrame)) + 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); @@ -208,7 +217,7 @@ void DocumentWriter::reportDataReceived() m_hasReceivedSomeData = true; if (m_decoder->encoding().usesVisualOrdering()) m_frame->document()->setVisuallyOrdered(); - m_frame->document()->recalcStyle(Node::Force); + m_frame->document()->recalcStyle(Style::Force); } void DocumentWriter::addData(const char* bytes, size_t length) @@ -222,7 +231,7 @@ void DocumentWriter::addData(const char* bytes, size_t length) CRASH(); ASSERT(m_parser); - m_parser->appendBytes(this, bytes, length); + m_parser->appendBytes(*this, bytes, length); } void DocumentWriter::end() @@ -237,16 +246,16 @@ void DocumentWriter::end() // http://bugs.webkit.org/show_bug.cgi?id=10854 // The frame's last ref may be removed and it can be deleted by checkCompleted(), // so we'll add a protective refcount - RefPtr<Frame> protector(m_frame); + Ref<Frame> protect(*m_frame); if (!m_parser) return; // FIXME: m_parser->finish() should imply m_parser->flush(). - m_parser->flush(this); + m_parser->flush(*this); if (!m_parser) return; m_parser->finish(); - m_parser = 0; + m_parser = nullptr; } void DocumentWriter::setEncoding(const String& name, bool userChosen) |