/* * Copyright (C) 2000 Peter Kelly (pmk@post.com) * Copyright (C) 2005-2016 Apple Inc. All rights reserved. * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #pragma once #include "FragmentScriptingPermission.h" #include "PendingScriptClient.h" #include "ScriptableDocumentParser.h" #include "SegmentedString.h" #include "XMLErrors.h" #include #include #include #include #include namespace WebCore { class ContainerNode; class CachedResourceLoader; class DocumentFragment; class Element; class FrameView; class PendingCallbacks; class Text; class XMLParserContext : public RefCounted { public: static RefPtr createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString& chunk); static Ref createStringParser(xmlSAXHandlerPtr, void* userData); ~XMLParserContext(); xmlParserCtxtPtr context() const { return m_context; } private: XMLParserContext(xmlParserCtxtPtr context) : m_context(context) { } xmlParserCtxtPtr m_context; }; class XMLDocumentParser final : public ScriptableDocumentParser, public PendingScriptClient { WTF_MAKE_FAST_ALLOCATED; public: static Ref create(Document& document, FrameView* view) { return adoptRef(*new XMLDocumentParser(document, view)); } static Ref create(DocumentFragment& fragment, Element* element, ParserContentPolicy parserContentPolicy) { return adoptRef(*new XMLDocumentParser(fragment, element, parserContentPolicy)); } ~XMLDocumentParser(); // Exposed for callbacks: void handleError(XMLErrors::ErrorType, const char* message, TextPosition); void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; } bool isXHTMLDocument() const { return m_isXHTMLDocument; } static bool parseDocumentFragment(const String&, DocumentFragment&, Element* parent = nullptr, ParserContentPolicy = AllowScriptingContent); // Used by XMLHttpRequest to check if the responseXML was well formed. bool wellFormed() const final { return !m_sawError; } static bool supportsXMLVersion(const String&); private: explicit XMLDocumentParser(Document&, FrameView* = nullptr); XMLDocumentParser(DocumentFragment&, Element*, ParserContentPolicy); void insert(SegmentedString&&) final; void append(RefPtr&&) final; void finish() final; bool isWaitingForScripts() const final; void stopParsing() final; void detach() final; TextPosition textPosition() const final; bool shouldAssociateConsoleMessagesWithTextPosition() const final; void notifyFinished(PendingScript&) final; void end(); void pauseParsing(); void resumeParsing(); bool appendFragmentSource(const String&); public: // Callbacks from parser SAX, and other functions needed inside // the parser implementation, but outside this class. void error(XMLErrors::ErrorType, const char* message, va_list args) WTF_ATTRIBUTE_PRINTF(3, 0); void startElementNs(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int numNamespaces, const xmlChar** namespaces, int numAttributes, int numDefaulted, const xmlChar** libxmlAttributes); void endElementNs(); void characters(const xmlChar*, int length); void processingInstruction(const xmlChar* target, const xmlChar* data); void cdataBlock(const xmlChar*, int length); void comment(const xmlChar*); void startDocument(const xmlChar* version, const xmlChar* encoding, int standalone); void internalSubset(const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID); void endDocument(); bool isParsingEntityDeclaration() const { return m_isParsingEntityDeclaration; } void setIsParsingEntityDeclaration(bool value) { m_isParsingEntityDeclaration = value; } int depthTriggeringEntityExpansion() const { return m_depthTriggeringEntityExpansion; } void setDepthTriggeringEntityExpansion(int depth) { m_depthTriggeringEntityExpansion = depth; } private: void initializeParserContext(const CString& chunk = CString()); void pushCurrentNode(ContainerNode*); void popCurrentNode(); void clearCurrentNodeStack(); void insertErrorMessageBlock(); void createLeafTextNode(); bool updateLeafTextNode(); void doWrite(const String&); void doEnd(); xmlParserCtxtPtr context() const { return m_context ? m_context->context() : nullptr; }; FrameView* m_view { nullptr }; SegmentedString m_originalSourceForTransform; RefPtr m_context; std::unique_ptr m_pendingCallbacks; Vector m_bufferedText; int m_depthTriggeringEntityExpansion { -1 }; bool m_isParsingEntityDeclaration { false }; ContainerNode* m_currentNode { nullptr }; Vector m_currentNodeStack; RefPtr m_leafTextNode; bool m_sawError { false }; bool m_sawCSS { false }; bool m_sawXSLTransform { false }; bool m_sawFirstElement { false }; bool m_isXHTMLDocument { false }; bool m_parserPaused { false }; bool m_requestingScript { false }; bool m_finishCalled { false }; std::unique_ptr m_xmlErrors; RefPtr m_pendingScript; TextPosition m_scriptStartPosition; bool m_parsingFragment { false }; AtomicString m_defaultNamespaceURI; HashMap m_prefixToNamespaceMap; SegmentedString m_pendingSrc; }; #if ENABLE(XSLT) xmlDocPtr xmlDocPtrForString(CachedResourceLoader&, const String& source, const String& url); #endif HashMap parseAttributes(const String&, bool& attrsOK); } // namespace WebCore