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/xml/parser/XMLDocumentParser.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/xml/parser/XMLDocumentParser.cpp')
-rw-r--r-- | Source/WebCore/xml/parser/XMLDocumentParser.cpp | 109 |
1 files changed, 50 insertions, 59 deletions
diff --git a/Source/WebCore/xml/parser/XMLDocumentParser.cpp b/Source/WebCore/xml/parser/XMLDocumentParser.cpp index 547ffcb05..4cbccd970 100644 --- a/Source/WebCore/xml/parser/XMLDocumentParser.cpp +++ b/Source/WebCore/xml/parser/XMLDocumentParser.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2000 Peter Kelly (pmk@post.com) - * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005-2017 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) @@ -27,9 +27,7 @@ #include "XMLDocumentParser.h" #include "CDATASection.h" -#include "CachedScript.h" #include "Comment.h" -#include "CachedResourceLoader.h" #include "Document.h" #include "DocumentFragment.h" #include "DocumentType.h" @@ -40,12 +38,16 @@ #include "HTMLNames.h" #include "HTMLStyleElement.h" #include "ImageLoader.h" +#include "PendingScript.h" #include "ProcessingInstruction.h" #include "ResourceError.h" #include "ResourceRequest.h" #include "ResourceResponse.h" +#include "SVGNames.h" +#include "SVGStyleElement.h" #include "ScriptElement.h" #include "ScriptSourceCode.h" +#include "StyleScope.h" #include "TextResourceDecoder.h" #include "TreeDepthLimit.h" #include <wtf/Ref.h> @@ -53,11 +55,6 @@ #include <wtf/Threading.h> #include <wtf/Vector.h> -#if ENABLE(SVG) -#include "SVGNames.h" -#include "SVGStyleElement.h" -#endif - namespace WebCore { using namespace HTMLNames; @@ -91,8 +88,8 @@ void XMLDocumentParser::clearCurrentNodeStack() { if (m_currentNode && m_currentNode != document()) m_currentNode->deref(); - m_currentNode = 0; - m_leafTextNode = 0; + m_currentNode = nullptr; + m_leafTextNode = nullptr; if (m_currentNodeStack.size()) { // Aborted parsing. for (size_t i = m_currentNodeStack.size() - 1; i != 0; --i) @@ -103,14 +100,15 @@ void XMLDocumentParser::clearCurrentNodeStack() } } -void XMLDocumentParser::insert(const SegmentedString&) +void XMLDocumentParser::insert(SegmentedString&&) { ASSERT_NOT_REACHED(); } -void XMLDocumentParser::append(PassRefPtr<StringImpl> inputSource) +void XMLDocumentParser::append(RefPtr<StringImpl>&& inputSource) { - SegmentedString source(inputSource); + String source { WTFMove(inputSource) }; + if (m_sawXSLTransform || !m_sawFirstElement) m_originalSourceForTransform.append(source); @@ -122,16 +120,16 @@ void XMLDocumentParser::append(PassRefPtr<StringImpl> inputSource) return; } - doWrite(source.toString()); + doWrite(source); - // After parsing, go ahead and dispatch image beforeload events. + // After parsing, dispatch image beforeload events. ImageLoader::dispatchPendingBeforeLoadEvents(); } void XMLDocumentParser::handleError(XMLErrors::ErrorType type, const char* m, TextPosition position) { if (!m_xmlErrors) - m_xmlErrors = std::make_unique<XMLErrors>(document()); + m_xmlErrors = std::make_unique<XMLErrors>(*document()); m_xmlErrors->handleError(type, m, position); if (type != XMLErrors::warning) m_sawError = true; @@ -139,12 +137,15 @@ void XMLDocumentParser::handleError(XMLErrors::ErrorType type, const char* m, Te stopParsing(); } -void XMLDocumentParser::enterText() +void XMLDocumentParser::createLeafTextNode() { + if (m_leafTextNode) + return; + ASSERT(m_bufferedText.size() == 0); ASSERT(!m_leafTextNode); m_leafTextNode = Text::create(m_currentNode->document(), ""); - m_currentNode->parserAppendChild(m_leafTextNode.get()); + m_currentNode->parserAppendChild(*m_leafTextNode); } static inline String toString(const xmlChar* string, size_t size) @@ -152,20 +153,23 @@ static inline String toString(const xmlChar* string, size_t size) return String::fromUTF8(reinterpret_cast<const char*>(string), size); } - -void XMLDocumentParser::exitText() +bool XMLDocumentParser::updateLeafTextNode() { if (isStopped()) - return; + return false; if (!m_leafTextNode) - return; + return true; + + // This operation might fire mutation event, see below. + m_leafTextNode->appendData(toString(m_bufferedText.data(), m_bufferedText.size())); + m_bufferedText = { }; - m_leafTextNode->appendData(toString(m_bufferedText.data(), m_bufferedText.size()), IGNORE_EXCEPTION); - Vector<xmlChar> empty; - m_bufferedText.swap(empty); + m_leafTextNode = nullptr; - m_leafTextNode = 0; + // Hence, we need to check again whether the parser is stopped, since mutation + // event handlers executed by appendData might have detached this parser. + return !isStopped(); } void XMLDocumentParser::detach() @@ -191,11 +195,13 @@ void XMLDocumentParser::end() if (m_parserPaused) return; - if (m_sawError) + if (m_sawError) { insertErrorMessageBlock(); - else { - exitText(); - document()->styleResolverChanged(RecalcStyleImmediately); + if (isDetached()) // Inserting an error message may have ran arbitrary scripts. + return; + } else { + updateLeafTextNode(); + document()->styleScope().didChangeStyleSheetEnvironment(); } if (isParsing()) @@ -211,6 +217,8 @@ void XMLDocumentParser::finish() // makes sense to call any methods on DocumentParser once it's been stopped. // However, FrameLoader::stop calls DocumentParser::finish unconditionally. + Ref<XMLDocumentParser> protectedThis(*this); + if (m_parserPaused) m_finishCalled = true; else @@ -223,35 +231,17 @@ void XMLDocumentParser::insertErrorMessageBlock() m_xmlErrors->insertErrorMessageBlock(); } -void XMLDocumentParser::notifyFinished(CachedResource* unusedResource) +void XMLDocumentParser::notifyFinished(PendingScript& pendingScript) { - ASSERT_UNUSED(unusedResource, unusedResource == m_pendingScript); - ASSERT(m_pendingScript->accessCount() > 0); - - ScriptSourceCode sourceCode(m_pendingScript.get()); - bool errorOccurred = m_pendingScript->errorOccurred(); - bool wasCanceled = m_pendingScript->wasCanceled(); - - m_pendingScript->removeClient(this); - m_pendingScript = 0; - - RefPtr<Element> e = m_scriptElement; - m_scriptElement = 0; - - ScriptElement* scriptElement = toScriptElementIfPossible(e.get()); - ASSERT(scriptElement); + ASSERT(&pendingScript == m_pendingScript.get()); // JavaScript can detach this parser, make sure it's kept alive even if detached. - Ref<XMLDocumentParser> protect(*this); - - if (errorOccurred) - scriptElement->dispatchErrorEvent(); - else if (!wasCanceled) { - scriptElement->executeScript(sourceCode); - scriptElement->dispatchLoadEvent(); - } + Ref<XMLDocumentParser> protectedThis(*this); - m_scriptElement = 0; + m_pendingScript = nullptr; + pendingScript.clearClient(); + + pendingScript.element().executePendingScript(pendingScript); if (!isDetached() && !m_requestingScript) resumeParsing(); @@ -264,6 +254,8 @@ bool XMLDocumentParser::isWaitingForScripts() const void XMLDocumentParser::pauseParsing() { + ASSERT(!m_parserPaused); + if (m_parsingFragment) return; @@ -278,17 +270,16 @@ bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragm // FIXME: We need to implement the HTML5 XML Fragment parsing algorithm: // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#xml-fragment-parsing-algorithm // For now we have a hack for script/style innerHTML support: - if (contextElement && (contextElement->hasLocalName(HTMLNames::scriptTag) || contextElement->hasLocalName(HTMLNames::styleTag))) { + if (contextElement && (contextElement->hasLocalName(HTMLNames::scriptTag.localName()) || contextElement->hasLocalName(HTMLNames::styleTag.localName()))) { fragment.parserAppendChild(fragment.document().createTextNode(chunk)); return true; } RefPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, parserContentPolicy); bool wellFormed = parser->appendFragmentSource(chunk); - // Do not call finish(). Current finish() and doEnd() implementations touch the main Document/loader - // and can cause crashes in the fragment case. + // Do not call finish(). The finish() and doEnd() implementations touch the main document and loader and can cause crashes in the fragment case. parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction. - return wellFormed; // appendFragmentSource()'s wellFormed is more permissive than wellFormed(). + return wellFormed; // appendFragmentSource()'s wellFormed is more permissive than Document::wellFormed(). } } // namespace WebCore |