15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2000 Peter Kelly (pmk@post.com)
3c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * Copyright (C) 2005, 2006, 2008, 2014 Apple Inc. All rights reserved.
453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Holger Hans Peter Freyther
853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/parser/XMLDocumentParser.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h"
31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptController.h"
32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptSourceCode.h"
337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "bindings/core/v8/V8Document.h"
345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/FetchInitiatorTypeNames.h"
355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/XMLNSNames.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CDATASection.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Comment.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentFragment.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentType.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ProcessingInstruction.h"
43e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/dom/ScriptLoader.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/TransformSource.h"
45e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h"
46e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ScriptResource.h"
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/UseCounter.h"
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLHtmlElement.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLTemplateElement.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLEntityParser.h"
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/html/parser/TextResourceDecoder.h"
5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoader.h"
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/ImageLoader.h"
55f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "core/svg/graphics/SVGImage.h"
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/xml/parser/SharedBufferReader.h"
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/parser/XMLDocumentParserScope.h"
58591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/xml/parser/XMLParserInput.h"
595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "platform/RuntimeEnabledFeatures.h"
601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/SharedBuffer.h"
61197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/TraceEvent.h"
621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/network/ResourceError.h"
63bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceRequest.h"
64bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceResponse.h"
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SecurityOrigin.h"
66e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/StringExtras.h"
67591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/TemporaryChange.h"
68e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/Threading.h"
69e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/Vector.h"
70e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/unicode/UTF8.h"
7176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include <libxml/catalog.h>
7276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include <libxml/parser.h>
7376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include <libxml/parserInternals.h>
7476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include <libxslt/xslt.h>
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
76c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)using namespace HTMLNames;
7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// FIXME: HTMLConstructionSite has a limit of 512, should these match?
8153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static const unsigned maxXMLTreeDepth = 5000;
8253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static inline String toString(const xmlChar* string, size_t length)
8453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
8553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return String::fromUTF8(reinterpret_cast<const char*>(string), length);
8653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
8753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static inline String toString(const xmlChar* string)
8953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return String::fromUTF8(reinterpret_cast<const char*>(string));
9153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
9253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static inline AtomicString toAtomicString(const xmlChar* string, size_t length)
9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return AtomicString::fromUTF8(reinterpret_cast<const char*>(string), length);
9653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
9753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static inline AtomicString toAtomicString(const xmlChar* string)
9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
10053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return AtomicString::fromUTF8(reinterpret_cast<const char*>(string));
10153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
103df95704c49daea886ddad70775bda23618d6274dBen Murdochstatic inline bool hasNoStyleInformation(Document* document)
104df95704c49daea886ddad70775bda23618d6274dBen Murdoch{
105df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (document->sawElementsInKnownNamespaces() || document->transformSourceDocument())
106df95704c49daea886ddad70775bda23618d6274dBen Murdoch        return false;
107df95704c49daea886ddad70775bda23618d6274dBen Murdoch
108df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (!document->frame() || !document->frame()->page())
109df95704c49daea886ddad70775bda23618d6274dBen Murdoch        return false;
110df95704c49daea886ddad70775bda23618d6274dBen Murdoch
111f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (document->frame()->tree().parent())
112df95704c49daea886ddad70775bda23618d6274dBen Murdoch        return false; // This document is not in a top frame
113df95704c49daea886ddad70775bda23618d6274dBen Murdoch
114f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    if (SVGImage::isInSVGImage(document))
115f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return false;
116f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
117df95704c49daea886ddad70775bda23618d6274dBen Murdoch    return true;
118df95704c49daea886ddad70775bda23618d6274dBen Murdoch}
119df95704c49daea886ddad70775bda23618d6274dBen Murdoch
12053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingStartElementNSCallback FINAL : public XMLDocumentParser::PendingCallback {
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
12253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    PendingStartElementNSCallback(const AtomicString& localName, const AtomicString& prefix, const AtomicString& uri,
12353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        int namespaceCount, const xmlChar** namespaces, int attributeCount, int defaultedCount, const xmlChar** attributes)
12453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        : m_localName(localName)
12553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_prefix(prefix)
12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_uri(uri)
12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_namespaceCount(namespaceCount)
12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_attributeCount(attributeCount)
12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_defaultedCount(defaultedCount)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_namespaces = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * namespaceCount * 2));
13276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        for (int i = 0; i < namespaceCount * 2 ; ++i)
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            m_namespaces[i] = xmlStrdup(namespaces[i]);
13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_attributes = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * attributeCount * 5));
13576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        for (int i = 0; i < attributeCount; ++i) {
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Each attribute has 5 elements in the array:
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // name, prefix, uri, value and an end pointer.
13876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            for (int j = 0; j < 3; ++j)
13953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                m_attributes[i * 5 + j] = xmlStrdup(attributes[i * 5 + j]);
14053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            int length = attributes[i * 5 + 4] - attributes[i * 5 + 3];
14153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            m_attributes[i * 5 + 3] = xmlStrndup(attributes[i * 5 + 3], length);
14253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            m_attributes[i * 5 + 4] = m_attributes[i * 5 + 3] + length;
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual ~PendingStartElementNSCallback()
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
14876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        for (int i = 0; i < m_namespaceCount * 2; ++i)
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            xmlFree(m_namespaces[i]);
15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        xmlFree(m_namespaces);
15176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        for (int i = 0; i < m_attributeCount; ++i)
15276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            for (int j = 0; j < 4; ++j)
15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                xmlFree(m_attributes[i * 5 + j]);
15453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        xmlFree(m_attributes);
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->startElementNs(m_localName, m_prefix, m_uri,
16076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            m_namespaceCount, const_cast<const xmlChar**>(m_namespaces),
16176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            m_attributeCount, m_defaultedCount, const_cast<const xmlChar**>(m_attributes));
16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private:
16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    AtomicString m_localName;
16653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    AtomicString m_prefix;
16753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    AtomicString m_uri;
16853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int m_namespaceCount;
16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    xmlChar** m_namespaces;
17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int m_attributeCount;
17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int m_defaultedCount;
17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    xmlChar** m_attributes;
17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingEndElementNSCallback FINAL : public XMLDocumentParser::PendingCallback {
17653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
17753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
17853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
17953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->endElementNs();
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingCharactersCallback FINAL : public XMLDocumentParser::PendingCallback {
18453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
18553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    PendingCharactersCallback(const xmlChar* chars, int length)
18653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        : m_chars(xmlStrndup(chars, length))
18753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_length(length)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
18953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual ~PendingCharactersCallback()
19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
19353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        xmlFree(m_chars);
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
19853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->characters(m_chars, m_length);
19953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private:
20253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    xmlChar* m_chars;
20353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int m_length;
20453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingProcessingInstructionCallback FINAL : public XMLDocumentParser::PendingCallback {
20753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    PendingProcessingInstructionCallback(const String& target, const String& data)
20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        : m_target(target)
21053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_data(data)
21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
21453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->processingInstruction(m_target, m_data);
21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private:
22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String m_target;
22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String m_data;
22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
22353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
22453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingCDATABlockCallback FINAL : public XMLDocumentParser::PendingCallback {
22553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    explicit PendingCDATABlockCallback(const String& text) : m_text(text) { }
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
23053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->cdataBlock(m_text);
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private:
23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String m_text;
23553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
23653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
23753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingCommentCallback FINAL : public XMLDocumentParser::PendingCallback {
23853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
23953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    explicit PendingCommentCallback(const String& text) : m_text(text) { }
24053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
24153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
24353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->comment(m_text);
24453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private:
24753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String m_text;
24853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingInternalSubsetCallback FINAL : public XMLDocumentParser::PendingCallback {
25153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
25253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    PendingInternalSubsetCallback(const String& name, const String& externalID, const String& systemID)
25353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        : m_name(name)
25453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_externalID(externalID)
25553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_systemID(systemID)
25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
26153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->internalSubset(m_name, m_externalID, m_systemID);
26253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private:
26553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String m_name;
26653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String m_externalID;
26753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String m_systemID;
26853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class PendingErrorCallback FINAL : public XMLDocumentParser::PendingCallback {
27153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
27253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    PendingErrorCallback(XMLErrors::ErrorType type, const xmlChar* message, OrdinalNumber lineNumber, OrdinalNumber columnNumber)
27353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        : m_type(type)
27453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_message(xmlStrdup(message))
27553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_lineNumber(lineNumber)
27653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_columnNumber(columnNumber)
27753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual ~PendingErrorCallback()
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
28253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        xmlFree(m_message);
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void call(XMLDocumentParser* parser) OVERRIDE
28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
28753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        parser->handleError(m_type, reinterpret_cast<char*>(m_message), TextPosition(m_lineNumber, m_columnNumber));
28853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
29153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    XMLErrors::ErrorType m_type;
29253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    xmlChar* m_message;
29353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    OrdinalNumber m_lineNumber;
29453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    OrdinalNumber m_columnNumber;
29553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::pushCurrentNode(ContainerNode* n)
29853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
29953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(n);
30053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_currentNode);
3015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !ENABLE(OILPAN)
30253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (n != document())
30353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        n->ref();
3045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
30553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentNodeStack.append(m_currentNode);
30653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentNode = n;
30753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentNodeStack.size() > maxXMLTreeDepth)
30876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        handleError(XMLErrors::ErrorTypeFatal, "Excessive node nesting.", textPosition());
30953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
31153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::popCurrentNode()
31253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
31353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_currentNode)
31453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
31553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_currentNodeStack.size());
3165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !ENABLE(OILPAN)
31753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentNode != document())
31853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_currentNode->deref();
3195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
32053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentNode = m_currentNodeStack.last();
32153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentNodeStack.removeLast();
32253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::clearCurrentNodeStack()
32553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
3265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !ENABLE(OILPAN)
32753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentNode && m_currentNode != document())
32853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_currentNode->deref();
3295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
330d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_currentNode = nullptr;
331d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_leafTextNode = nullptr;
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentNodeStack.size()) { // Aborted parsing.
3345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !ENABLE(OILPAN)
33553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        for (size_t i = m_currentNodeStack.size() - 1; i != 0; --i)
33653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            m_currentNodeStack[i]->deref();
33753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (m_currentNodeStack[0] && m_currentNodeStack[0] != document())
33853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            m_currentNodeStack[0]->deref();
3395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
34053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_currentNodeStack.clear();
34153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
34253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
34453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::insert(const SegmentedString&)
34553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
34653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_NOT_REACHED();
34753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
34953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
35053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
35153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    SegmentedString source(inputSource);
35253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_sawXSLTransform || !m_sawFirstElement)
35353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_originalSourceForTransform.append(source);
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (isStopped() || m_sawXSLTransform)
35653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parserPaused) {
35953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pendingSrc.append(source);
36053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
36153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3639bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // JavaScript can detach the parser. Make sure this is not released
3649bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // before the end of this method.
365d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
3669bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
36753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    doWrite(source.toString());
36853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::handleError(XMLErrors::ErrorType type, const char* formattedMessage, TextPosition position)
37153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
37253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_xmlErrors.handleError(type, formattedMessage, position);
37376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (type != XMLErrors::ErrorTypeWarning)
37453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_sawError = true;
37576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (type == XMLErrors::ErrorTypeFatal)
37653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        stopParsing();
37753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::enterText()
38053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
38153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_bufferedText.size() == 0);
38253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(!m_leafTextNode);
38353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_leafTextNode = Text::create(m_currentNode->document(), "");
3848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_currentNode->parserAppendChild(m_leafTextNode.get());
38553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::exitText()
38853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
38953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (isStopped())
39053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
39253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_leafTextNode)
39353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_leafTextNode->appendData(toString(m_bufferedText.data(), m_bufferedText.size()));
396c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    m_bufferedText.clear();
397d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_leafTextNode = nullptr;
39853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
39953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
40053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::detach()
40153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
40253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    clearCurrentNodeStack();
40353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ScriptableDocumentParser::detach();
40453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
40653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::end()
40753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
408197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    TRACE_EVENT0("blink", "XMLDocumentParser::end");
40953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // XMLDocumentParserLibxml2 will do bad things to the document if doEnd() is called.
41053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // I don't believe XMLDocumentParserQt needs doEnd called in the fragment case.
41153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(!m_parsingFragment);
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    doEnd();
41453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
41553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // doEnd() call above can detach the parser and null out its document.
41653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // In that case, we just bail out.
41753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (isDetached())
41853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
41953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
42053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // doEnd() could process a script tag, thus pausing parsing.
42153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parserPaused)
42253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
42353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
42476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (m_sawError) {
42553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        insertErrorMessageBlock();
42676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    } else {
42753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        exitText();
428d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        document()->styleResolverChanged();
42953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
43053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
43153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (isParsing())
43253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        prepareToStopParsing();
43353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    document()->setReadyState(Document::Interactive);
43453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    clearCurrentNodeStack();
43553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    document()->finishedParsing();
43653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
43753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
43853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::finish()
43953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
44053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
44153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // makes sense to call any methods on DocumentParser once it's been stopped.
44253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // However, FrameLoader::stop calls DocumentParser::finish unconditionally.
44353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4449e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    // flush may ending up executing arbitrary script, and possibly detach the parser.
4459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
4469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    flush();
4479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (isDetached())
4489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return;
4499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
45053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parserPaused)
45153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_finishCalled = true;
45253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    else
45353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        end();
45453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
45553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
45653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::insertErrorMessageBlock()
45753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
45853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_xmlErrors.insertErrorMessageBlock();
45953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
46053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
461fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid XMLDocumentParser::notifyFinished(Resource* unusedResource)
46253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
46353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_UNUSED(unusedResource, unusedResource == m_pendingScript);
46453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
46553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ScriptSourceCode sourceCode(m_pendingScript.get());
46653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool errorOccurred = m_pendingScript->errorOccurred();
46753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool wasCanceled = m_pendingScript->wasCanceled();
46853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
46953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_pendingScript->removeClient(this);
47053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_pendingScript = 0;
47153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
472d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<Element> e = m_scriptElement;
473d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_scriptElement = nullptr;
47453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
475e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ScriptLoader* scriptLoader = toScriptLoaderIfPossible(e.get());
476e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ASSERT(scriptLoader);
47753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
47876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // JavaScript can detach this parser, make sure it's kept alive even if
47976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // detached.
480d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
48193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
48276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (errorOccurred) {
483e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        scriptLoader->dispatchErrorEvent();
48476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    } else if (!wasCanceled) {
48509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        scriptLoader->executeScript(sourceCode);
48609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        scriptLoader->dispatchLoadEvent();
48753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
48853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
489d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_scriptElement = nullptr;
49053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
49153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!isDetached() && !m_requestingScript)
49253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        resumeParsing();
49353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
49453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
49553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool XMLDocumentParser::isWaitingForScripts() const
49653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
49753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return m_pendingScript;
49853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
49953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
50053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::pauseParsing()
50153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
50276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (!m_parsingFragment)
50376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        m_parserPaused = true;
50453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
50553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
50653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
50753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
50853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!chunk.length())
50953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return true;
51053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
51153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // FIXME: We need to implement the HTML5 XML Fragment parsing algorithm:
51253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#xml-fragment-parsing-algorithm
51353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // For now we have a hack for script/style innerHTML support:
514c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (contextElement && (contextElement->hasLocalName(scriptTag.localName()) || contextElement->hasLocalName(styleTag.localName()))) {
5158abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        fragment->parserAppendChild(fragment->document().createTextNode(chunk));
51653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return true;
51753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
51853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
519d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
52053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool wellFormed = parser->appendFragmentSource(chunk);
52176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)
52276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // Do not call finish(). Current finish() and doEnd() implementations touch
52376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // the main Document/loader and can cause crashes in the fragment case.
52476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)
52576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // Allows ~DocumentParser to assert it was detached before destruction.
52676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    parser->detach();
52776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // appendFragmentSource()'s wellFormed is more permissive than wellFormed().
52876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    return wellFormed;
52953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int globalDescriptor = 0;
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static ThreadIdentifier libxmlLoaderThread = 0;
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int matchFunc(const char*)
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
53676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // Only match loads initiated due to uses of libxml2 from within
53776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // XMLDocumentParser to avoid interfering with client applications that also
53876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // use libxml2. http://bugs.webkit.org/show_bug.cgi?id=17353
5393464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    return XMLDocumentParserScope::currentFetcher && currentThread() == libxmlLoaderThread;
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
542926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline void setAttributes(Element* element, Vector<Attribute>& attributeVector, ParserContentPolicy parserContentPolicy)
543926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
544926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!scriptingContentIsAllowed(parserContentPolicy))
54553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        element->stripScriptingAttributes(attributeVector);
546926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    element->parserSetAttributes(attributeVector);
547926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
548926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
549591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic void switchEncoding(xmlParserCtxtPtr ctxt, bool is8Bit)
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Hack around libxml2's lack of encoding overide support by manually
55276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // resetting the encoding to UTF-16 before every chunk. Otherwise libxml
55376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // will detect <?xml version="1.0" encoding="<encoding name>"?> blocks and
55476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // switch encodings, causing the parse to fail.
555591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (is8Bit) {
556591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
557591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return;
558591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
559591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const UChar BOM = 0xFEFF;
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSwitchEncoding(ctxt, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic void parseChunk(xmlParserCtxtPtr ctxt, const String& chunk)
566591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{
567591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    bool is8Bit = chunk.is8Bit();
568591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    switchEncoding(ctxt, is8Bit);
569591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (is8Bit)
570591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        xmlParseChunk(ctxt, reinterpret_cast<const char*>(chunk.characters8()), sizeof(LChar) * chunk.length(), 0);
571591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    else
572591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        xmlParseChunk(ctxt, reinterpret_cast<const char*>(chunk.characters16()), sizeof(UChar) * chunk.length(), 0);
573591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}
574591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
575591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic void finishParsing(xmlParserCtxtPtr ctxt)
576591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{
577591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    xmlParseChunk(ctxt, 0, 0, 1);
578591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}
579591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
580591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#define xmlParseChunk #error "Use parseChunk instead to select the correct encoding."
581591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
582c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)static bool isLibxmlDefaultCatalogFile(const String& urlString)
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // On non-Windows platforms libxml asks for this URL, the
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // "XML_XML_DEFAULT_CATALOG", on initialization.
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (urlString == "file:///etc/xml/catalog")
587c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return true;
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // On Windows, libxml computes a URL relative to where its DLL resides.
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (urlString.startsWith("file:///", false) && urlString.endsWith("/etc/catalog", false))
591c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return true;
592c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    return false;
593c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
594c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
595c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)static bool shouldAllowExternalLoad(const KURL& url)
596c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
597c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    String urlString = url.string();
598c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
599c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // This isn't really necessary now that initializeLibXMLIfNecessary
600c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // disables catalog support in libxml, but keeping it for defense in depth.
601c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (isLibxmlDefaultCatalogFile(url))
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
60476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // The most common DTD. There isn't much point in hammering www.w3c.org by
60576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // requesting this URL for every XHTML document.
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (urlString.startsWith("http://www.w3.org/TR/xhtml", false))
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Similarly, there isn't much point in requesting the SVG DTD.
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (urlString.startsWith("http://www.w3.org/Graphics/SVG", false))
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
61376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // The libxml doesn't give us a lot of context for deciding whether to allow
61476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // this request. In the worst case, this load could be for an external
61576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // entity and the resulting document could simply read the retrieved
61676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // content. If we had more context, we could potentially allow the parser to
61776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // load a DTD. As things stand, we take the conservative route and allow
61876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // same-origin requests only.
6193464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    if (!XMLDocumentParserScope::currentFetcher->document()->securityOrigin()->canRequest(url)) {
6203464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch        XMLDocumentParserScope::currentFetcher->printAccessDeniedMessage(url);
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void* openFunc(const char* uri)
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6293464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    ASSERT(XMLDocumentParserScope::currentFetcher);
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(currentThread() == libxmlLoaderThread);
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    KURL url(KURL(), uri);
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!shouldAllowExternalLoad(url))
6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return &globalDescriptor;
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
63706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    KURL finalURL;
638d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<SharedBuffer> data;
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
6413464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch        ResourceFetcher* fetcher = XMLDocumentParserScope::currentFetcher;
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        XMLDocumentParserScope scope(0);
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: We should restore the original global error handler as well.
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (fetcher->frame()) {
64606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            FetchRequest request(ResourceRequest(url), FetchInitiatorTypeNames::xml, ResourceFetcher::defaultResourceOptions());
64706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            ResourcePtr<Resource> resource = fetcher->fetchSynchronously(request);
64806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (resource && !resource->errorOccurred()) {
649d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                data = resource->resourceBuffer();
65006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                finalURL = resource->response().url();
65106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
65206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        }
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We have to check the URL again after the load to catch redirects.
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See <https://bugs.webkit.org/show_bug.cgi?id=21963>.
65706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!shouldAllowExternalLoad(finalURL))
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return &globalDescriptor;
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    UseCounter::count(XMLDocumentParserScope::currentFetcher->document(), UseCounter::XMLExternalResourceLoad);
6617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
662d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return new SharedBufferReader(data);
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int readFunc(void* context, char* buffer, int len)
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Do 0-byte reads in case of a null descriptor
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (context == &globalDescriptor)
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
671d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SharedBufferReader* data = static_cast<SharedBufferReader*>(context);
672d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return data->readData(buffer, len);
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int writeFunc(void*, const char*, int)
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Always just do 0-byte writes
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int closeFunc(void* context)
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (context != &globalDescriptor) {
684d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        SharedBufferReader* data = static_cast<SharedBufferReader*>(context);
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        delete data;
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void errorFunc(void*, const char*, ...)
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: It would be nice to display error messages somewhere.
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
695c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)static void initializeLibXMLIfNecessary()
696c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
697c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    static bool didInit = false;
698c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (didInit)
699c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return;
700c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
701c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // We don't want libxml to try and load catalogs.
702c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // FIXME: It's not nice to set global settings in libxml, embedders of Blink
703c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    // could be trying to use libxml themselves.
704c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE);
705c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    xmlInitParser();
706c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc);
707c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc);
708c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    libxmlLoaderThread = currentThread();
709c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    didInit = true;
710c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
711c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<XMLParserContext> XMLParserContext::createStringParser(xmlSAXHandlerPtr handlers, void* userData)
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
715c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    initializeLibXMLIfNecessary();
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParserCtxtPtr parser = xmlCreatePushParserCtxt(handlers, 0, 0, 0, 0);
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->_private = userData;
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->replaceEntities = true;
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return adoptRef(new XMLParserContext(parser));
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Chunk should be encoded in UTF-8
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<XMLParserContext> XMLParserContext::createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const CString& chunk)
7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
725c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    initializeLibXMLIfNecessary();
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // appendFragmentSource() checks that the length doesn't overflow an int.
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParserCtxtPtr parser = xmlCreateMemoryParserCtxt(chunk.data(), chunk.length());
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!parser)
731d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Copy the sax handler
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    memcpy(parser->sax, handlers, sizeof(xmlSAXHandler));
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Set parser options.
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // XML_PARSE_NODICT: default dictionary option.
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // XML_PARSE_NOENT: force entities substitutions.
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlCtxtUseOptions(parser, XML_PARSE_NODICT | XML_PARSE_NOENT);
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Internal initialization
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->sax2 = 1;
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->instate = XML_PARSER_CONTENT; // We are parsing a CONTENT
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->depth = 0;
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->str_xml = xmlDictLookup(parser->dict, BAD_CAST "xml", 3);
7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->str_xmlns = xmlDictLookup(parser->dict, BAD_CAST "xmlns", 5);
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->str_xml_ns = xmlDictLookup(parser->dict, XML_XML_NAMESPACE, 36);
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parser->_private = userData;
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return adoptRef(new XMLParserContext(parser));
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// --------------------------------
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool XMLDocumentParser::supportsXMLVersion(const String& version)
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return version == "1.0";
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
760d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)XMLDocumentParser::XMLDocumentParser(Document& document, FrameView* frameView)
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : ScriptableDocumentParser(document)
762d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    , m_hasView(frameView)
763d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_context(nullptr)
764d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    , m_currentNode(&document)
765591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    , m_isCurrentlyParsing8BitChunk(false)
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawError(false)
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawCSS(false)
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawXSLTransform(false)
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawFirstElement(false)
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_isXHTMLDocument(false)
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_parserPaused(false)
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_requestingScript(false)
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_finishCalled(false)
774d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    , m_xmlErrors(&document)
7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_pendingScript(0)
7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_scriptStartPosition(TextPosition::belowRangePosition())
7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_parsingFragment(false)
7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
77993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // This is XML being used as a document resource.
780d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (frameView && document.isXMLDocument())
781d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        UseCounter::count(document, UseCounter::XMLDocument);
7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
784926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, ParserContentPolicy parserContentPolicy)
785d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
786d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    , m_hasView(false)
787d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_context(nullptr)
7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_currentNode(fragment)
789591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    , m_isCurrentlyParsing8BitChunk(false)
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawError(false)
7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawCSS(false)
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawXSLTransform(false)
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_sawFirstElement(false)
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_isXHTMLDocument(false)
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_parserPaused(false)
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_requestingScript(false)
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_finishCalled(false)
7988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    , m_xmlErrors(&fragment->document())
7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_pendingScript(0)
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_scriptStartPosition(TextPosition::belowRangePosition())
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_parsingFragment(true)
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !ENABLE(OILPAN)
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fragment->ref();
8055d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Add namespaces based on the parent node
8085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<Element> > elemStack;
8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (parentElement) {
8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        elemStack.append(parentElement);
8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8129e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        Element* grandParentElement = parentElement->parentElement();
8139e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (!grandParentElement)
8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
8159e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        parentElement = grandParentElement;
8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (elemStack.isEmpty())
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (; !elemStack.isEmpty(); elemStack.removeLast()) {
8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Element* element = elemStack.last();
823c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        AttributeCollection attributes = element->attributes();
824e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        AttributeCollection::iterator end = attributes.end();
825e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
826c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (it->localName() == xmlnsAtom)
827c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                m_defaultNamespaceURI = it->value();
828c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            else if (it->prefix() == xmlnsAtom)
829c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                m_prefixToNamespaceMap.set(it->localName(), it->value());
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the parent element is not in document tree, there may be no xmlns attribute; just default to the parent's namespace.
8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_defaultNamespaceURI.isNull() && !parentElement->inDocument())
8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_defaultNamespaceURI = parentElement->namespaceURI();
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)XMLParserContext::~XMLParserContext()
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_context->myDoc)
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        xmlFreeDoc(m_context->myDoc);
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlFreeParserCtxt(m_context);
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)XMLDocumentParser::~XMLDocumentParser()
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
847d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if !ENABLE(OILPAN)
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The XMLDocumentParser will always be detached before being destroyed.
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_currentNodeStack.isEmpty());
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_currentNode);
851d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif
8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: m_pendingScript handling should be moved into XMLDocumentParser.cpp!
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_pendingScript)
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_pendingScript->removeClient(this);
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
858d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void XMLDocumentParser::trace(Visitor* visitor)
859d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
860d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_currentNode);
861d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if ENABLE(OILPAN)
862d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_currentNodeStack);
863d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif
864d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_leafTextNode);
865d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_xmlErrors);
866d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_scriptElement);
867d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ScriptableDocumentParser::trace(visitor);
868d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
869d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::doWrite(const String& parseString)
8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
872197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    TRACE_EVENT0("blink", "XMLDocumentParser::doWrite");
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!isDetached());
8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_context)
8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        initializeParserContext();
8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Protect the libxml context from deletion during a callback
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<XMLParserContext> context = m_context;
8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
88076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // libXML throws an error if you try to switch the encoding for an empty
88176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // string.
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (parseString.length()) {
883591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        // JavaScript may cause the parser to detach during parseChunk
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // keep this alive until this function is done.
885d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8873464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch        XMLDocumentParserScope scope(document()->fetcher());
888591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        TemporaryChange<bool> encodingScope(m_isCurrentlyParsing8BitChunk, parseString.is8Bit());
889591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        parseChunk(context->context(), parseString);
8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
891591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        // JavaScript (which may be run under the parseChunk callstack) may
8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // cause the parser to be stopped or detached.
8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isStopped())
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
89776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // FIXME: Why is this here? And why is it after we process the passed
89876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // source?
89951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (document()->sawDecodingError()) {
9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If the decoder saw an error, report it as fatal (stops parsing)
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TextPosition position(OrdinalNumber::fromOneBasedInt(context->context()->input->line), OrdinalNumber::fromOneBasedInt(context->context()->input->col));
90276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        handleError(XMLErrors::ErrorTypeFatal, "Encoding error", position);
9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
90676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)struct xmlSAX2Namespace {
9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const xmlChar* prefix;
9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const xmlChar* uri;
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
91151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline void handleNamespaceAttributes(Vector<Attribute>& prefixedAttributes, const xmlChar** libxmlNamespaces, int nbNamespaces, ExceptionState& exceptionState)
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAX2Namespace* namespaces = reinterpret_cast<xmlSAX2Namespace*>(libxmlNamespaces);
91476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    for (int i = 0; i < nbNamespaces; ++i) {
9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AtomicString namespaceQName = xmlnsAtom;
9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AtomicString namespaceURI = toAtomicString(namespaces[i].uri);
9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (namespaces[i].prefix)
9187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            namespaceQName = WTF::xmlnsWithColon + namespaces[i].prefix;
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        QualifiedName parsedName = anyName;
92151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!Element::parseAttributeName(parsedName, XMLNSNames::xmlnsNamespaceURI, namespaceQName, exceptionState))
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
92353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        prefixedAttributes.append(Attribute(parsedName, namespaceURI));
9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
92876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)struct xmlSAX2Attributes {
9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const xmlChar* localname;
9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const xmlChar* prefix;
9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const xmlChar* uri;
9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const xmlChar* value;
9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const xmlChar* end;
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
93651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline void handleElementAttributes(Vector<Attribute>& prefixedAttributes, const xmlChar** libxmlAttributes, int nbAttributes, ExceptionState& exceptionState)
9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);
93976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    for (int i = 0; i < nbAttributes; ++i) {
9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int valueLength = static_cast<int>(attributes[i].end - attributes[i].value);
9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AtomicString attrValue = toAtomicString(attributes[i].value, valueLength);
9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String attrPrefix = toString(attributes[i].prefix);
9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AtomicString attrURI = attrPrefix.isEmpty() ? AtomicString() : toAtomicString(attributes[i].uri);
9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AtomicString attrQName = attrPrefix.isEmpty() ? toAtomicString(attributes[i].localname) : attrPrefix + ":" + toString(attributes[i].localname);
9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        QualifiedName parsedName = anyName;
94751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!Element::parseAttributeName(parsedName, attrURI, attrQName, exceptionState))
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        prefixedAttributes.append(Attribute(parsedName, attrValue));
9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
954df95704c49daea886ddad70775bda23618d6274dBen Murdochvoid XMLDocumentParser::startElementNs(const AtomicString& localName, const AtomicString& prefix, const AtomicString& uri, int nbNamespaces,
955df95704c49daea886ddad70775bda23618d6274dBen Murdoch    const xmlChar** libxmlNamespaces, int nbAttributes, int nbDefaulted, const xmlChar** libxmlAttributes)
9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parserPaused) {
961df95704c49daea886ddad70775bda23618d6274dBen Murdoch        m_pendingCallbacks.append(adoptPtr(new PendingStartElementNSCallback(localName, prefix, uri, nbNamespaces, libxmlNamespaces,
962df95704c49daea886ddad70775bda23618d6274dBen Murdoch            nbAttributes, nbDefaulted, libxmlAttributes)));
9635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    exitText();
9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
96853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    AtomicString adjustedURI = uri;
96953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parsingFragment && adjustedURI.isNull()) {
9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!prefix.isNull())
97153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            adjustedURI = m_prefixToNamespaceMap.get(prefix);
9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
97353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            adjustedURI = m_defaultNamespaceURI;
9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isFirstElement = !m_sawFirstElement;
9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_sawFirstElement = true;
9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
97953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    QualifiedName qName(prefix, localName, adjustedURI);
980d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<Element> newElement = m_currentNode->document().createElement(qName, true);
9815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!newElement) {
9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        stopParsing();
9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
986926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Vector<Attribute> prefixedAttributes;
98751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TrackExceptionState exceptionState;
98851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    handleNamespaceAttributes(prefixedAttributes, libxmlNamespaces, nbNamespaces, exceptionState);
98951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException()) {
990926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        stopParsing();
9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
99551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    handleElementAttributes(prefixedAttributes, libxmlAttributes, nbAttributes, exceptionState);
996926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
99751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException()) {
9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        stopParsing();
9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newElement->beginParsingChildren();
10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1004e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ScriptLoader* scriptLoader = toScriptLoaderIfPossible(newElement.get());
1005e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (scriptLoader)
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_scriptStartPosition = textPosition();
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_currentNode->parserAppendChild(newElement.get());
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Event handlers may synchronously trigger removal of the
10117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // document and cancellation of this parser.
10127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (isStopped()) {
10137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        stopParsing();
10147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
10157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
10167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1017d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (isHTMLTemplateElement(*newElement))
1018d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        pushCurrentNode(toHTMLTemplateElement(*newElement).content());
1019926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else
1020926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        pushCurrentNode(newElement.get());
1021926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1022d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (isHTMLHtmlElement(*newElement))
1023d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        toHTMLHtmlElement(*newElement).insertedByParser();
10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parsingFragment && isFirstElement && document()->frame())
1026f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        document()->frame()->loader().dispatchDocumentElementAvailable();
10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::endElementNs()
10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parserPaused) {
103553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pendingCallbacks.append(adoptPtr(new PendingEndElementNSCallback()));
10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
103976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // JavaScript can detach the parser. Make sure this is not released before
104076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // the end of this method.
1041d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    exitText();
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<ContainerNode> n = m_currentNode;
104609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_currentNode->isElementNode())
104709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        toElement(n.get())->finishParsingChildren();
10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1049f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode() && toScriptLoaderIfPossible(toElement(n))) {
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        popCurrentNode();
10511fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        n->remove(IGNORE_EXCEPTION);
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1055d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!n->isElementNode() || !m_hasView) {
10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        popCurrentNode();
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1060f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    Element* element = toElement(n);
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The element's parent may have already been removed from document.
10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Parsing continues in this case, but scripts aren't executed.
10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element->inDocument()) {
10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        popCurrentNode();
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1069e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element);
1070e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (!scriptLoader) {
10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        popCurrentNode();
10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Don't load external scripts for standalone documents (for now).
10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_pendingScript);
10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_requestingScript = true;
10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1079d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (scriptLoader->prepareScript(m_scriptStartPosition, ScriptLoader::AllowLegacyTypeInTypeAttribute)) {
10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Script execution should be shared between
10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the libxml2 and Qt XMLDocumentParser implementations.
10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1083e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        if (scriptLoader->readyToBeParserExecuted()) {
1084e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            scriptLoader->executeScript(ScriptSourceCode(scriptLoader->scriptContent(), document()->url(), m_scriptStartPosition));
1085e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        } else if (scriptLoader->willBeParserExecuted()) {
1086d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            m_pendingScript = scriptLoader->resource();
10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_scriptElement = element;
10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_pendingScript->addClient(this);
10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
109076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            // m_pendingScript will be 0 if script was already loaded and
109176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)            // addClient() executed it.
10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_pendingScript)
10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                pauseParsing();
1094e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        } else {
1095d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_scriptElement = nullptr;
1096e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        }
10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // JavaScript may have detached the parser
10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isDetached())
11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_requestingScript = false;
11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    popCurrentNode();
11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
110653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::characters(const xmlChar* chars, int length)
11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parserPaused) {
111253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pendingCallbacks.append(adoptPtr(new PendingCharactersCallback(chars, length)));
11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_leafTextNode)
11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        enterText();
111853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_bufferedText.append(chars, length);
11195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::error(XMLErrors::ErrorType type, const char* message, va_list args)
11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
112653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    char formattedMessage[1024];
112753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    vsnprintf(formattedMessage, sizeof(formattedMessage) - 1, message, args);
11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
112953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parserPaused) {
113053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pendingCallbacks.append(adoptPtr(new PendingErrorCallback(type, reinterpret_cast<const xmlChar*>(formattedMessage), lineNumber(), columnNumber())));
113153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
113253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
113353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
113453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    handleError(type, formattedMessage, textPosition());
11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
113753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::processingInstruction(const String& target, const String& data)
11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parserPaused) {
114376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        m_pendingCallbacks.append(adoptPtr(new PendingProcessingInstructionCallback(target, data)));
11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    exitText();
11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // ### handle exceptions
115051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TrackExceptionState exceptionState;
1151d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<ProcessingInstruction> pi = m_currentNode->document().createProcessingInstruction(target, data, exceptionState);
115251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    pi->setCreatedByParser(true);
11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11578abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_currentNode->parserAppendChild(pi.get());
11585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
115909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    pi->setCreatedByParser(false);
11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (pi->isCSS())
11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_sawCSS = true;
11631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
11641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!RuntimeEnabledFeatures::xsltEnabled())
11651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
11661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_sawXSLTransform = !m_sawFirstElement && pi->isXSL();
1168bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (m_sawXSLTransform && !document()->transformSourceDocument()) {
116976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // This behavior is very tricky. We call stopParsing() here because we
117076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // want to stop processing the document until we're ready to apply the
117176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // transform, but we actually still want to be fed decoded string pieces
117276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // to accumulate in m_originalSourceForTransform. So, we call
117376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // stopParsing() here and check isStopped() in element callbacks.
1174bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // FIXME: This contradicts the contract of DocumentParser.
11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        stopParsing();
1176bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
11775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
117953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::cdataBlock(const String& text)
11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parserPaused) {
118553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pendingCallbacks.append(adoptPtr(new PendingCDATABlockCallback(text)));
11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    exitText();
11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1191d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_currentNode->parserAppendChild(CDATASection::create(m_currentNode->document(), text));
11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
119453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::comment(const String& text)
11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parserPaused) {
120053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pendingCallbacks.append(adoptPtr(new PendingCommentCallback(text)));
12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    exitText();
12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1206d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_currentNode->parserAppendChild(Comment::create(m_currentNode->document(), text));
12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum StandaloneInfo {
12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StandaloneUnspecified = -2,
12115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NoXMlDeclaration,
12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StandaloneNo,
12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StandaloneYes
12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
121653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::startDocument(const String& version, const String& encoding, int standalone)
12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
121876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    StandaloneInfo standaloneInfo = static_cast<StandaloneInfo>(standalone);
12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (standaloneInfo == NoXMlDeclaration) {
12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        document()->setHasXMLDeclaration(false);
12215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
122453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!version.isNull())
12251fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        document()->setXMLVersion(version, ASSERT_NO_EXCEPTION);
12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (standalone != StandaloneUnspecified)
12271fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        document()->setXMLStandalone(standaloneInfo == StandaloneYes, ASSERT_NO_EXCEPTION);
122853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!encoding.isNull())
122953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        document()->setXMLEncoding(encoding);
12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    document()->setHasXMLDeclaration(true);
12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::endDocument()
12345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    exitText();
12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
123853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void XMLDocumentParser::internalSubset(const String& name, const String& externalID, const String& systemID)
12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStopped())
12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parserPaused) {
124453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pendingCallbacks.append(adoptPtr(new PendingInternalSubsetCallback(name, externalID, systemID)));
12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (document())
12498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        document()->parserAppendChild(DocumentType::create(document(), name, externalID, systemID));
12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline XMLDocumentParser* getParser(void* closure)
12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParserCtxtPtr ctxt = static_cast<xmlParserCtxtPtr>(closure);
12555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return static_cast<XMLDocumentParser*>(ctxt->_private);
12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1258df95704c49daea886ddad70775bda23618d6274dBen Murdochstatic void startElementNsHandler(void* closure, const xmlChar* localName, const xmlChar* prefix, const xmlChar* uri, int nbNamespaces, const xmlChar** namespaces, int nbAttributes, int nbDefaulted, const xmlChar** libxmlAttributes)
12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1260df95704c49daea886ddad70775bda23618d6274dBen Murdoch    getParser(closure)->startElementNs(toAtomicString(localName), toAtomicString(prefix), toAtomicString(uri), nbNamespaces, namespaces, nbAttributes, nbDefaulted, libxmlAttributes);
12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void endElementNsHandler(void* closure, const xmlChar*, const xmlChar*, const xmlChar*)
12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    getParser(closure)->endElementNs();
12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
126853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static void charactersHandler(void* closure, const xmlChar* chars, int length)
12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
127053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    getParser(closure)->characters(chars, length);
12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void processingInstructionHandler(void* closure, const xmlChar* target, const xmlChar* data)
12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
127553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    getParser(closure)->processingInstruction(toString(target), toString(data));
12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
127853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static void cdataBlockHandler(void* closure, const xmlChar* text, int length)
12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
128053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    getParser(closure)->cdataBlock(toString(text, length));
12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
128353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static void commentHandler(void* closure, const xmlChar* text)
12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
128553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    getParser(closure)->comment(toString(text));
12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WTF_ATTRIBUTE_PRINTF(2, 3)
12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void warningHandler(void* closure, const char* message, ...)
12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_list args;
12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_start(args, message);
129376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    getParser(closure)->error(XMLErrors::ErrorTypeWarning, message, args);
12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_end(args);
12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WTF_ATTRIBUTE_PRINTF(2, 3)
12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void fatalErrorHandler(void* closure, const char* message, ...)
12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_list args;
13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_start(args, message);
130276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    getParser(closure)->error(XMLErrors::ErrorTypeFatal, message, args);
13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_end(args);
13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WTF_ATTRIBUTE_PRINTF(2, 3)
13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void normalErrorHandler(void* closure, const char* message, ...)
13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_list args;
13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_start(args, message);
131176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    getParser(closure)->error(XMLErrors::ErrorTypeNonFatal, message, args);
13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    va_end(args);
13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
131576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)// Using a static entity and marking it XML_INTERNAL_PREDEFINED_ENTITY is a hack
131676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)// to avoid malloc/free. Using a global variable like this could cause trouble
13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// if libxml implementation details were to change
1318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static xmlChar sharedXHTMLEntityResult[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static xmlEntityPtr sharedXHTMLEntity()
13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static xmlEntity entity;
13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!entity.type) {
13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        entity.type = XML_ENTITY_DECL;
13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        entity.orig = sharedXHTMLEntityResult;
13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        entity.content = sharedXHTMLEntityResult;
13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        entity.etype = XML_INTERNAL_PREDEFINED_ENTITY;
13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return &entity;
13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1332926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static size_t convertUTF16EntityToUTF8(const UChar* utf16Entity, size_t numberOfCodeUnits, char* target, size_t targetSize)
1333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1334926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const char* originalTarget = target;
1335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    WTF::Unicode::ConversionResult conversionResult = WTF::Unicode::convertUTF16ToUTF8(&utf16Entity,
1336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        utf16Entity + numberOfCodeUnits, &target, target + targetSize);
1337926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (conversionResult != WTF::Unicode::conversionOK)
1338926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return 0;
1339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Even though we must pass the length, libxml expects the entity string to be null terminated.
1341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(target > originalTarget + 1);
1342926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    *target = '\0';
1343926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return target - originalTarget;
1344926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1345926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static xmlEntityPtr getXHTMLEntity(const xmlChar* name)
13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1348926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    UChar utf16DecodedEntity[4];
1349926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    size_t numberOfCodeUnits = decodeNamedEntityToUCharArray(reinterpret_cast<const char*>(name), utf16DecodedEntity);
1350926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!numberOfCodeUnits)
1351926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return 0;
1352926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1353926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(numberOfCodeUnits <= 4);
1354926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    size_t entityLengthInUTF8 = convertUTF16EntityToUTF8(utf16DecodedEntity, numberOfCodeUnits,
1355926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        reinterpret_cast<char*>(sharedXHTMLEntityResult), WTF_ARRAY_LENGTH(sharedXHTMLEntityResult));
1356926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!entityLengthInUTF8)
13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlEntityPtr entity = sharedXHTMLEntity();
1360926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    entity->length = entityLengthInUTF8;
13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    entity->name = name;
13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return entity;
13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static xmlEntityPtr getEntityHandler(void* closure, const xmlChar* name)
13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParserCtxtPtr ctxt = static_cast<xmlParserCtxtPtr>(closure);
13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlEntityPtr ent = xmlGetPredefinedEntity(name);
13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ent) {
13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ent->etype = XML_INTERNAL_PREDEFINED_ENTITY;
13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return ent;
13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ent = xmlGetDocEntity(ctxt->myDoc, name);
137553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!ent && getParser(closure)->isXHTMLDocument()) {
13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ent = getXHTMLEntity(name);
13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ent)
13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ent->etype = XML_INTERNAL_GENERAL_ENTITY;
13795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ent;
13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void startDocumentHandler(void* closure)
13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParserCtxt* ctxt = static_cast<xmlParserCtxt*>(closure);
1387591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    XMLDocumentParser* parser = getParser(closure);
1388591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    switchEncoding(ctxt, parser->isCurrentlyParsing8BitChunk());
1389591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    parser->startDocument(toString(ctxt->version), toString(ctxt->encoding), ctxt->standalone);
13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAX2StartDocument(closure);
13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void endDocumentHandler(void* closure)
13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    getParser(closure)->endDocument();
13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAX2EndDocument(closure);
13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void internalSubsetHandler(void* closure, const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID)
14005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
140153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    getParser(closure)->internalSubset(toString(name), toString(externalID), toString(systemID));
14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAX2InternalSubset(closure, name, externalID, systemID);
14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void externalSubsetHandler(void* closure, const xmlChar*, const xmlChar* externalId, const xmlChar*)
14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String extId = toString(externalId);
140876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (extId == "-//W3C//DTD XHTML 1.0 Transitional//EN"
140976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//W3C//DTD XHTML 1.1//EN"
141076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//W3C//DTD XHTML 1.0 Strict//EN"
141176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//W3C//DTD XHTML 1.0 Frameset//EN"
141276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//W3C//DTD XHTML Basic 1.0//EN"
141376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"
141476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
141576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
141676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//WAPFORUM//DTD XHTML Mobile 1.1//EN"
141776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        || extId == "-//WAPFORUM//DTD XHTML Mobile 1.2//EN") {
141876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // Controls if we replace entities or not.
141976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        getParser(closure)->setIsXHTMLDocument(true);
142076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    }
14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void ignorableWhitespaceHandler(void*, const xmlChar*, int)
14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
142576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // Nothing to do, but we need this to work around a crasher.
14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // http://bugzilla.gnome.org/show_bug.cgi?id=172255
14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // http://bugs.webkit.org/show_bug.cgi?id=5792
14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::initializeParserContext(const CString& chunk)
14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAXHandler sax;
14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    memset(&sax, 0, sizeof(sax));
14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.error = normalErrorHandler;
14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.fatalError = fatalErrorHandler;
14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.characters = charactersHandler;
14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.processingInstruction = processingInstructionHandler;
14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.cdataBlock = cdataBlockHandler;
14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.comment = commentHandler;
14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.warning = warningHandler;
14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.startElementNs = startElementNsHandler;
14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.endElementNs = endElementNsHandler;
14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.getEntity = getEntityHandler;
14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.startDocument = startDocumentHandler;
14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.endDocument = endDocumentHandler;
14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.internalSubset = internalSubsetHandler;
14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.externalSubset = externalSubsetHandler;
14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.ignorableWhitespace = ignorableWhitespaceHandler;
145053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    sax.entityDecl = xmlSAX2EntityDecl;
14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.initialized = XML_SAX2_MAGIC;
14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_sawError = false;
14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_sawCSS = false;
14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_sawXSLTransform = false;
14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_sawFirstElement = false;
14565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14573464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    XMLDocumentParserScope scope(document()->fetcher());
145876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (m_parsingFragment) {
14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_context = XMLParserContext::createMemoryParser(&sax, this, chunk);
146076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    } else {
14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!chunk.data());
14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_context = XMLParserContext::createStringParser(&sax, this);
14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::doEnd()
14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isStopped()) {
14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_context) {
14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Tell libxml we're done.
14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            {
14723464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch                XMLDocumentParserScope scope(document()->fetcher());
1473591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch                finishParsing(context());
14745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
14755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1476d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_context = nullptr;
14775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
14785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1480df95704c49daea886ddad70775bda23618d6274dBen Murdoch    bool xmlViewerMode = !m_sawError && !m_sawCSS && !m_sawXSLTransform && hasNoStyleInformation(document());
14817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if (xmlViewerMode) {
14827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        const char noStyleMessage[] = "This XML file does not appear to have any style information associated with it. The document tree is shown below.";
14837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        document()->setIsViewSource(true);
14847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        V8Document::PrivateScript::transformDocumentToTreeViewMethod(document()->frame(), document(), noStyleMessage);
14857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    } else if (m_sawXSLTransform) {
14863464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch        xmlDocPtr doc = xmlDocPtrForString(document()->fetcher(), m_originalSourceForTransform.toString(), document()->url().string());
14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        document()->setTransformSource(adoptPtr(new TransformSource(doc)));
148876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // Make the document think it's done, so it will apply XSL stylesheets.
148976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        document()->setParsing(false);
1490d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        document()->styleResolverChanged();
14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
149276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // styleResolverChanged() call can detach the parser and null out its
149376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // document. In that case, we just bail out.
1494926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (isDetached())
1495926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return;
1496926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1497926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        document()->setParsing(true);
14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DocumentParser::stopParsing();
14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15023464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben MurdochxmlDocPtr xmlDocPtrForString(ResourceFetcher* fetcher, const String& source, const String& url)
15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (source.isEmpty())
15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Parse in a single chunk into an xmlDocPtr
150776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // FIXME: Hook up error handlers so that a failure to parse the main
150876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // document results in good error messages.
15093464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch    XMLDocumentParserScope scope(fetcher, errorFunc, 0);
1510591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    XMLParserInput input(source);
1511591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return xmlReadMemory(input.data(), input.size(), url.latin1().data(), input.encoding(), XSLT_PARSE_OPTIONS);
15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)OrdinalNumber XMLDocumentParser::lineNumber() const
15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return OrdinalNumber::fromOneBasedInt(context() ? context()->input->line : 1);
15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)OrdinalNumber XMLDocumentParser::columnNumber() const
15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return OrdinalNumber::fromOneBasedInt(context() ? context()->input->col : 1);
15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TextPosition XMLDocumentParser::textPosition() const
15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParserCtxtPtr context = this->context();
15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!context)
15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return TextPosition::minimumPosition();
152976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    return TextPosition(OrdinalNumber::fromOneBasedInt(context->input->line), OrdinalNumber::fromOneBasedInt(context->input->col));
15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::stopParsing()
15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentParser::stopParsing();
15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (context())
15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        xmlStopParser(context());
15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLDocumentParser::resumeParsing()
15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!isDetached());
15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_parserPaused);
15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_parserPaused = false;
15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // First, execute any pending callbacks
154753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    while (!m_pendingCallbacks.isEmpty()) {
154853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        OwnPtr<PendingCallback> callback = m_pendingCallbacks.takeFirst();
154953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        callback->call(this);
15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A callback paused the parser
15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_parserPaused)
15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Then, write any pending data
15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SegmentedString rest = m_pendingSrc;
15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_pendingSrc.clear();
1559926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // There is normally only one string left, so toString() shouldn't copy.
1560926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // In any case, the XML parser runs on the main thread and it's OK if
1561926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // the passed string has more than one reference.
1562926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    append(rest.toString().impl());
15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Finally, if finish() has been called and write() didn't result
15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // in any further callbacks being queued, call end()
156653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_finishCalled && m_pendingCallbacks.isEmpty())
15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        end();
15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool XMLDocumentParser::appendFragmentSource(const String& chunk)
15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_context);
15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_parsingFragment);
15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CString chunkAsUtf8 = chunk.utf8();
157653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
157776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // libxml2 takes an int for a length, and therefore can't handle XML chunks
157876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // larger than 2 GiB.
15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (chunkAsUtf8.length() > INT_MAX)
15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1582197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    TRACE_EVENT0("blink", "XMLDocumentParser::appendFragmentSource");
15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    initializeParserContext(chunkAsUtf8);
15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParseContent(context());
15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    endDocument(); // Close any open text nodes.
15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
158776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // FIXME: If this code is actually needed, it should probably move to
158876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // finish()
158976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // XMLDocumentParserQt has a similar check (m_stream.error() ==
159076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // QXmlStreamReader::PrematureEndOfDocumentError) in doEnd(). Check if all
159176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // the chunk has been processed.
15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    long bytesProcessed = xmlByteConsumed(context());
159376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (bytesProcessed == -1 || static_cast<unsigned long>(bytesProcessed) != chunkAsUtf8.length()) {
159476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // FIXME: I don't believe we can hit this case without also having seen
159576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // an error or a null byte. If we hit this ASSERT, we've found a test
159676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // case which demonstrates the need for this code.
15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_sawError || (bytesProcessed >= 0 && !chunkAsUtf8.data()[bytesProcessed]));
15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // No error if the chunk is well formed or it is not but we have no error.
16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return context()->wellFormed || !xmlCtxtGetLastError(context());
16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// --------------------------------
16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct AttributeParseState {
16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashMap<String, String> attributes;
16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool gotAttributes;
16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void attributesStartElementNsHandler(void* closure, const xmlChar* xmlLocalName, const xmlChar* /*xmlPrefix*/,
1613df95704c49daea886ddad70775bda23618d6274dBen Murdoch    const xmlChar* /*xmlURI*/, int /*nbNamespaces*/, const xmlChar** /*namespaces*/,
1614df95704c49daea886ddad70775bda23618d6274dBen Murdoch    int nbAttributes, int /*nbDefaulted*/, const xmlChar** libxmlAttributes)
16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (strcmp(reinterpret_cast<const char*>(xmlLocalName), "attrs") != 0)
16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlParserCtxtPtr ctxt = static_cast<xmlParserCtxtPtr>(closure);
16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AttributeParseState* state = static_cast<AttributeParseState*>(ctxt->_private);
16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    state->gotAttributes = true;
16235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);
162576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    for (int i = 0; i < nbAttributes; ++i) {
16265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String attrLocalName = toString(attributes[i].localname);
16275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int valueLength = (int) (attributes[i].end - attributes[i].value);
16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String attrValue = toString(attributes[i].value, valueLength);
16295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String attrPrefix = toString(attributes[i].prefix);
16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String attrQName = attrPrefix.isEmpty() ? attrLocalName : attrPrefix + ":" + attrLocalName;
16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        state->attributes.set(attrQName, attrValue);
16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HashMap<String, String> parseAttributes(const String& string, bool& attrsOK)
16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AttributeParseState state;
16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    state.gotAttributes = false;
16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xmlSAXHandler sax;
16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    memset(&sax, 0, sizeof(sax));
16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.startElementNs = attributesStartElementNsHandler;
16445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sax.initialized = XML_SAX2_MAGIC;
16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax, &state);
16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />";
1647591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    parseChunk(parser->context(), parseString);
1648591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    finishParsing(parser->context());
16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    attrsOK = state.gotAttributes;
16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return state.attributes;
16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1653c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
1654