⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmltokenizerlibxml2.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2000 Peter Kelly (pmk@post.com) * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2008 Holger Hans Peter Freyther * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#include "XMLTokenizer.h"#include "CDATASection.h"#include "CString.h"#include "CachedScript.h"#include "Comment.h"#include "DocLoader.h"#include "Document.h"#include "DocumentFragment.h"#include "DocumentType.h"#include "Frame.h"#include "FrameLoader.h"#include "FrameView.h"#include "HTMLLinkElement.h"#include "HTMLStyleElement.h"#include "HTMLTokenizer.h" // for decodeNamedEntity#include "ProcessingInstruction.h"#include "ResourceError.h"#include "ResourceHandle.h"#include "ResourceRequest.h"#include "ResourceResponse.h"#include "ScriptController.h"#include "ScriptElement.h"#include "ScriptSourceCode.h"#include "ScriptValue.h"#include "TextResourceDecoder.h"#include <libxml/parser.h>#include <libxml/parserInternals.h>#include <wtf/Platform.h>#include <wtf/StringExtras.h>#include <wtf/Threading.h>#include <wtf/UnusedParam.h>#include <wtf/Vector.h>#if ENABLE(XSLT)#include <libxslt/xslt.h>#endifusing namespace std;namespace WebCore {class PendingCallbacks : Noncopyable {public:    ~PendingCallbacks()    {        deleteAllValues(m_callbacks);    }        void appendStartElementNSCallback(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int nb_namespaces,                                      const xmlChar** namespaces, int nb_attributes, int nb_defaulted, const xmlChar** attributes)    {        PendingStartElementNSCallback* callback = new PendingStartElementNSCallback;                callback->xmlLocalName = xmlStrdup(xmlLocalName);        callback->xmlPrefix = xmlStrdup(xmlPrefix);        callback->xmlURI = xmlStrdup(xmlURI);        callback->nb_namespaces = nb_namespaces;        callback->namespaces = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * nb_namespaces * 2));        for (int i = 0; i < nb_namespaces * 2 ; i++)            callback->namespaces[i] = xmlStrdup(namespaces[i]);        callback->nb_attributes = nb_attributes;        callback->nb_defaulted = nb_defaulted;        callback->attributes = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * nb_attributes * 5));        for (int i = 0; i < nb_attributes; i++) {            // Each attribute has 5 elements in the array:            // name, prefix, uri, value and an end pointer.                        for (int j = 0; j < 3; j++)                callback->attributes[i * 5 + j] = xmlStrdup(attributes[i * 5 + j]);                        int len = attributes[i * 5 + 4] - attributes[i * 5 + 3];            callback->attributes[i * 5 + 3] = xmlStrndup(attributes[i * 5 + 3], len);            callback->attributes[i * 5 + 4] = callback->attributes[i * 5 + 3] + len;        }                m_callbacks.append(callback);    }    void appendEndElementNSCallback()    {        PendingEndElementNSCallback* callback = new PendingEndElementNSCallback;                m_callbacks.append(callback);    }        void appendCharactersCallback(const xmlChar* s, int len)    {        PendingCharactersCallback* callback = new PendingCharactersCallback;                callback->s = xmlStrndup(s, len);        callback->len = len;                m_callbacks.append(callback);    }        void appendProcessingInstructionCallback(const xmlChar* target, const xmlChar* data)    {        PendingProcessingInstructionCallback* callback = new PendingProcessingInstructionCallback;                callback->target = xmlStrdup(target);        callback->data = xmlStrdup(data);                m_callbacks.append(callback);    }        void appendCDATABlockCallback(const xmlChar* s, int len)    {        PendingCDATABlockCallback* callback = new PendingCDATABlockCallback;                callback->s = xmlStrndup(s, len);        callback->len = len;                m_callbacks.append(callback);            }    void appendCommentCallback(const xmlChar* s)    {        PendingCommentCallback* callback = new PendingCommentCallback;                callback->s = xmlStrdup(s);                m_callbacks.append(callback);            }    void appendInternalSubsetCallback(const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID)    {        PendingInternalSubsetCallback* callback = new PendingInternalSubsetCallback;                callback->name = xmlStrdup(name);        callback->externalID = xmlStrdup(externalID);        callback->systemID = xmlStrdup(systemID);                m_callbacks.append(callback);            }        void appendErrorCallback(XMLTokenizer::ErrorType type, const char* message, int lineNumber, int columnNumber)    {        PendingErrorCallback* callback = new PendingErrorCallback;                callback->message = strdup(message);        callback->type = type;        callback->lineNumber = lineNumber;        callback->columnNumber = columnNumber;                m_callbacks.append(callback);    }    void callAndRemoveFirstCallback(XMLTokenizer* tokenizer)    {        OwnPtr<PendingCallback> callback(m_callbacks.first());        m_callbacks.removeFirst();        callback->call(tokenizer);    }        bool isEmpty() const { return m_callbacks.isEmpty(); }    private:        struct PendingCallback {          virtual ~PendingCallback() { }        virtual void call(XMLTokenizer* tokenizer) = 0;    };          struct PendingStartElementNSCallback : public PendingCallback {        virtual ~PendingStartElementNSCallback() {            xmlFree(xmlLocalName);            xmlFree(xmlPrefix);            xmlFree(xmlURI);            for (int i = 0; i < nb_namespaces * 2; i++)                xmlFree(namespaces[i]);            xmlFree(namespaces);            for (int i = 0; i < nb_attributes; i++)                for (int j = 0; j < 4; j++)                     xmlFree(attributes[i * 5 + j]);            xmlFree(attributes);        }                virtual void call(XMLTokenizer* tokenizer) {            tokenizer->startElementNs(xmlLocalName, xmlPrefix, xmlURI,                                       nb_namespaces, const_cast<const xmlChar**>(namespaces),                                      nb_attributes, nb_defaulted, const_cast<const xmlChar**>(attributes));        }        xmlChar* xmlLocalName;        xmlChar* xmlPrefix;        xmlChar* xmlURI;        int nb_namespaces;        xmlChar** namespaces;        int nb_attributes;        int nb_defaulted;        xmlChar** attributes;    };        struct PendingEndElementNSCallback : public PendingCallback {        virtual void call(XMLTokenizer* tokenizer)         {            tokenizer->endElementNs();        }    };        struct PendingCharactersCallback : public PendingCallback {        virtual ~PendingCharactersCallback()         {            xmlFree(s);        }            virtual void call(XMLTokenizer* tokenizer)         {            tokenizer->characters(s, len);        }                xmlChar* s;        int len;    };    struct PendingProcessingInstructionCallback : public PendingCallback {        virtual ~PendingProcessingInstructionCallback()         {            xmlFree(target);            xmlFree(data);        }                virtual void call(XMLTokenizer* tokenizer)         {            tokenizer->processingInstruction(target, data);        }                xmlChar* target;        xmlChar* data;    };        struct PendingCDATABlockCallback : public PendingCallback {        virtual ~PendingCDATABlockCallback()         {            xmlFree(s);        }                virtual void call(XMLTokenizer* tokenizer)         {            tokenizer->cdataBlock(s, len);        }                xmlChar* s;        int len;    };    struct PendingCommentCallback : public PendingCallback {        virtual ~PendingCommentCallback()         {            xmlFree(s);        }                virtual void call(XMLTokenizer* tokenizer)         {            tokenizer->comment(s);        }        xmlChar* s;    };        struct PendingInternalSubsetCallback : public PendingCallback {        virtual ~PendingInternalSubsetCallback()         {            xmlFree(name);            xmlFree(externalID);            xmlFree(systemID);        }                virtual void call(XMLTokenizer* tokenizer)        {            tokenizer->internalSubset(name, externalID, systemID);        }                xmlChar* name;        xmlChar* externalID;        xmlChar* systemID;            };        struct PendingErrorCallback: public PendingCallback {        virtual ~PendingErrorCallback()         {            free (message);        }                virtual void call(XMLTokenizer* tokenizer)         {            tokenizer->handleError(type, message, lineNumber, columnNumber);        }                XMLTokenizer::ErrorType type;        char* message;        int lineNumber;        int columnNumber;    };        Deque<PendingCallback*> m_callbacks;};// --------------------------------static int globalDescriptor = 0;static DocLoader* globalDocLoader = 0;static ThreadIdentifier libxmlLoaderThread = 0;static int matchFunc(const char*){    // Only match loads initiated due to uses of libxml2 from within XMLTokenizer to avoid    // interfering with client applications that also use libxml2.  http://bugs.webkit.org/show_bug.cgi?id=17353    return globalDocLoader && currentThread() == libxmlLoaderThread;}class OffsetBuffer {public:    OffsetBuffer(const Vector<char>& b) : m_buffer(b), m_currentOffset(0) { }        int readOutBytes(char* outputBuffer, unsigned askedToRead) {        unsigned bytesLeft = m_buffer.size() - m_currentOffset;        unsigned lenToCopy = min(askedToRead, bytesLeft);        if (lenToCopy) {            memcpy(outputBuffer, m_buffer.data() + m_currentOffset, lenToCopy);            m_currentOffset += lenToCopy;        }        return lenToCopy;    }private:    Vector<char> m_buffer;    unsigned m_currentOffset;};static bool shouldAllowExternalLoad(const KURL& url){    String urlString = url.string();    // On non-Windows platforms libxml asks for this URL, the    // "XML_XML_DEFAULT_CATALOG", on initialization.    if (urlString == "file:///etc/xml/catalog")        return false;    // On Windows, libxml computes a URL relative to where its DLL resides.    if (urlString.startsWith("file:///", false) && urlString.endsWith("/etc/catalog", false))        return false;    // The most common DTD.  There isn't much point in hammering www.w3c.org    // by requesting this URL for every XHTML document.    if (urlString.startsWith("http://www.w3.org/TR/xhtml", false))        return false;    // Similarly, there isn't much point in requesting the SVG DTD.    if (urlString.startsWith("http://www.w3.org/Graphics/SVG", false))        return false;    // The libxml doesn't give us a lot of context for deciding whether to    // allow this request.  In the worst case, this load could be for an    // external entity and the resulting document could simply read the    // retrieved content.  If we had more context, we could potentially allow    // the parser to load a DTD.  As things stand, we take the conservative    // route and allow same-origin requests only.    if (!globalDocLoader->doc()->securityOrigin()->canRequest(url)) {        globalDocLoader->printAccessDeniedMessage(url);        return false;    }    return true;}static void* openFunc(const char* uri){    ASSERT(globalDocLoader);    ASSERT(currentThread() == libxmlLoaderThread);    KURL url(KURL(), uri);    if (!shouldAllowExternalLoad(url))        return &globalDescriptor;    ResourceError error;    ResourceResponse response;    Vector<char> data;        DocLoader* docLoader = globalDocLoader;    globalDocLoader = 0;    // FIXME: We should restore the original global error handler as well.    if (docLoader->frame())         docLoader->frame()->loader()->loadResourceSynchronously(url, error, response, data);    globalDocLoader = docLoader;    // We have to check the URL again after the load to catch redirects.    // See <https://bugs.webkit.org/show_bug.cgi?id=21963>.    if (!shouldAllowExternalLoad(response.url()))        return &globalDescriptor;    return new OffsetBuffer(data);}static int readFunc(void* context, char* buffer, int len){    // Do 0-byte reads in case of a null descriptor    if (context == &globalDescriptor)        return 0;            OffsetBuffer* data = static_cast<OffsetBuffer*>(context);    return data->readOutBytes(buffer, len);}static int writeFunc(void*, const char*, int){    // Always just do 0-byte writes    return 0;}static int closeFunc(void* context){    if (context != &globalDescriptor) {        OffsetBuffer* data = static_cast<OffsetBuffer*>(context);        delete data;    }    return 0;}#if ENABLE(XSLT)static void errorFunc(void*, const char*, ...){    // FIXME: It would be nice to display error messages somewhere.}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -