2006-02-10 Eric Seidel <eseidel@apple.com>
authoreseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Feb 2006 08:15:34 +0000 (08:15 +0000)
committereseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Feb 2006 08:15:34 +0000 (08:15 +0000)
        Reviewed by hyatt.

        Adding support for external entity declarations in XSLT.
        http://bugzilla.opendarwin.org/show_bug.cgi?id=7184
        <rdar://problem/4271696> support external DTD references in XSLT

        * dom/xml_tokenizer.cpp:
        (WebCore::OffsetBuffer::OffsetBuffer): new support class
        (WebCore::OffsetBuffer::readOutBytes): read method
        (WebCore::shouldAllowExternalLoad): for preventing common urls
        (WebCore::openFunc): now does a synchronous data load
        (WebCore::readFunc): returns data from the offset buffer
        (WebCore::closeFunc): deletes offset buffer
        (WebCore::setLoaderForLibXMLCallbacks): helper function
        (WebCore::createQStringParser): cleanup
        (WebCore::XMLTokenizer::finish):
        * dom/xml_tokenizer.h:
        * khtml/xsl/xsl_stylesheetimpl.cpp:
        (WebCore::XSLStyleSheetImpl::parseString):
        * khtml/xsl/xsl_stylesheetimpl.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@12750 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/dom/xml_tokenizer.cpp
WebCore/dom/xml_tokenizer.h
WebCore/khtml/xsl/xsl_stylesheetimpl.cpp
WebCore/khtml/xsl/xsl_stylesheetimpl.h

index dea8ef230858df6e4e54db2dcd8005588b6abcc7..0cff1fe46bceaa8b77508dd6a8e5ea437e550f30 100644 (file)
@@ -1,3 +1,26 @@
+2006-02-10  Eric Seidel  <eseidel@apple.com>
+
+        Reviewed by hyatt.
+
+        Adding support for external entity declarations in XSLT.
+        http://bugzilla.opendarwin.org/show_bug.cgi?id=7184
+        <rdar://problem/4271696> support external DTD references in XSLT
+
+        * dom/xml_tokenizer.cpp:
+        (WebCore::OffsetBuffer::OffsetBuffer): new support class
+        (WebCore::OffsetBuffer::readOutBytes): read method
+        (WebCore::shouldAllowExternalLoad): for preventing common urls
+        (WebCore::openFunc): now does a synchronous data load
+        (WebCore::readFunc): returns data from the offset buffer
+        (WebCore::closeFunc): deletes offset buffer
+        (WebCore::setLoaderForLibXMLCallbacks): helper function
+        (WebCore::createQStringParser): cleanup
+        (WebCore::XMLTokenizer::finish): 
+        * dom/xml_tokenizer.h:
+        * khtml/xsl/xsl_stylesheetimpl.cpp:
+        (WebCore::XSLStyleSheetImpl::parseString):
+        * khtml/xsl/xsl_stylesheetimpl.h:
+
 2006-02-10  Beth Dakin  <bdakin@apple.com>
 
         Reviewed by Hyatt
index 0a6971a8220b4d36c99a0cbfc83eddef52122144..96694712992faba3139acad564f2b82eb17b33d6 100644 (file)
@@ -24,7 +24,9 @@
 #include "config.h"
 #include "xml_tokenizer.h"
 
+#include "Cache.h"
 #include "CachedScript.h"
+#include "KWQLoader.h"
 #include "DocLoader.h"
 #include "DocumentFragmentImpl.h"
 #include "DocumentImpl.h"
@@ -43,6 +45,8 @@
 #include <libxml/parserInternals.h>
 #include <kxmlcore/Vector.h>
 
+#include <kio/job.h>
+
 #if SVG_SUPPORT
 #include "SVGNames.h"
 #include "XLinkNames.h"
@@ -152,14 +156,58 @@ static int matchFunc(const char* uri)
     return 1; // Match everything.
 }
 
-static void* openFunc(const char * uri) {
-    return &globalDescriptor;
+static khtml::DocLoader *globalDocLoader = 0;
+
+class OffsetBuffer {
+public:
+    OffsetBuffer(const ByteArray &b) : m_buffer(b), m_currentOffset(0) { }
+    
+    int readOutBytes(char *outputBuffer, unsigned askedToRead) {
+        unsigned bytesLeft = m_buffer.size() - m_currentOffset;
+        unsigned lenToCopy = kMin(askedToRead, bytesLeft);
+        if (lenToCopy) {
+            memcpy(outputBuffer, m_buffer.data() + m_currentOffset, lenToCopy);
+            m_currentOffset += lenToCopy;
+        }
+        return lenToCopy;
+    }
+
+private:
+    ByteArray m_buffer;
+    unsigned m_currentOffset;
+};
+
+static bool shouldAllowExternalLoad(const char* inURI)
+{
+    QString url(inURI);
+    if (url.contains("/etc/catalog")
+        || url.startsWith("http://www.w3.org/Graphics/SVG")
+        || url.startsWith("http://www.w3.org/TR/xhtml"))
+        return false;
+    return true;
+}
+
+static void* openFunc(const char* uri)
+{
+    if (!globalDocLoader || !shouldAllowExternalLoad(uri))
+        return &globalDescriptor;
+
+    KURL finalURL;
+    KIO::TransferJob *job = KIO::get(uri, true, false);
+    QString headers;
+    ByteArray data = KWQServeSynchronousRequest(Cache::loader(), globalDocLoader, job, finalURL, headers);
+    
+    return new OffsetBuffer(data);
 }
 
 static int readFunc(void* context, char* buffer, int len)
 {
-    // Always just do 0-byte reads
-    return 0;
+    // 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* context, const char* buffer, int len)
@@ -168,13 +216,27 @@ static int writeFunc(void* context, const char* buffer, int len)
     return 0;
 }
 
+static int closeFunc(void * context)
+{
+    if (context != &globalDescriptor) {
+        OffsetBuffer *data = static_cast<OffsetBuffer *>(context);
+        delete data;
+    }
+    return 0;
+}
+
+void setLoaderForLibXMLCallbacks(DocLoader *docLoader)
+{
+    globalDocLoader = docLoader;
+}
+
 static xmlParserCtxtPtr createQStringParser(xmlSAXHandlerPtr handlers, void *userData)
 {
     static bool didInit = false;
     if (!didInit) {
         xmlInitParser();
-        xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, 0);
-        xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, 0);
+        xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc);
+        xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc);
         didInit = true;
     }
 
@@ -749,9 +811,9 @@ void XMLTokenizer::finish()
     xmlFreeParserCtxt(m_context);
     m_context = 0;
 
-    if (m_sawError) {
+    if (m_sawError)
         insertErrorMessageBlock();
-    else {
+    else {
         // Parsing was successful. Now locate all html <script> tags in the document and execute them
         // one by one.
         exitText();
index 3eb4adcd4961cd36fa45030c0184a905cbe9dd7d..6c27db7a7cd0f61aaf2c23b672463ff919e1a94c 100644 (file)
@@ -74,6 +74,7 @@ private:
 Tokenizer* newXMLTokenizer(DocumentImpl*, FrameView* = 0);
 #if KHTML_XSLT
 void* xmlDocPtrForString(const QString& source, const QString& URL = QString());
+void setLoaderForLibXMLCallbacks(DocLoader*);
 #endif
 HashMap<DOMString, DOMString> parseAttributes(const DOMString&, bool& attrsOK);
 bool parseXMLDocumentFragment(const DOMString&, DocumentFragmentImpl*, ElementImpl* parent = 0);
index 286031149d8ad14a4927b58cbcfb1bc6a5f8724a..46485c268b7d873a789aa661b1a8d576a23d6718 100644 (file)
@@ -31,6 +31,7 @@
 #include "CachedXSLStyleSheet.h"
 #include "DocLoader.h"
 #include "xsl_stylesheetimpl.h"
+#include "xml_tokenizer.h"
 
 #include <kdebug.h>
 
 #define IS_BLANK_NODE(n)                                                \
     (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))
 
-using namespace khtml;
-using namespace DOM;
-
-namespace DOM {
+namespace WebCore {
     
 XSLStyleSheetImpl::XSLStyleSheetImpl(XSLImportRuleImpl *parentRule, DOMString href)
     : StyleSheetImpl(parentRule, href)
@@ -114,12 +112,14 @@ bool XSLStyleSheetImpl::parseString(const DOMString &string, bool strict)
     // Parse in a single chunk into an xmlDocPtr
     const QChar BOM(0xFEFF);
     const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char *>(&BOM);
+    setLoaderForLibXMLCallbacks(docLoader());
     m_stylesheetDoc = xmlReadMemory(reinterpret_cast<const char *>(string.unicode()),
                                     string.length() * sizeof(QChar),
                                     m_ownerDocument->URL().ascii(),
                                     BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", 
                                     XML_PARSE_NOCDATA|XML_PARSE_DTDATTR|XML_PARSE_NOENT);
     loadChildSheets();
+    setLoaderForLibXMLCallbacks(0);
     return m_stylesheetDoc;
 }
 
index 29db70c768ba5a7ef86e6346a2ed3d3ada65e165..9216432195c760644a338f9c592d96ab4988ab63 100644 (file)
 
 #include <libxslt/transform.h>
 
-namespace khtml {
-    class CachedXSLStyleSheet;
-};
-
-namespace DOM {
+namespace WebCore {
 
 class XSLImportRuleImpl;
+class CachedXSLStyleSheet;
     
 class XSLStyleSheetImpl : public StyleSheetImpl
 {
@@ -60,7 +57,7 @@ public:
 
     xsltStylesheetPtr compileStyleSheet();
 
-    khtml::DocLoader *docLoader();
+    DocLoader *docLoader();
 
     DocumentImpl* ownerDocument() { return m_ownerDocument; }
     void setOwnerDocument(DocumentImpl* doc) { m_ownerDocument = doc; }
@@ -82,7 +79,7 @@ protected:
     bool m_processed;
 };
 
-class XSLImportRuleImpl : public khtml::CachedObjectClient, public StyleBaseImpl
+class XSLImportRuleImpl : public CachedObjectClient, public StyleBaseImpl
 {
 public:
     XSLImportRuleImpl( StyleBaseImpl *parent, const DOM::DOMString &href);
@@ -103,7 +100,7 @@ public:
 protected:
     DOMString m_strHref;
     RefPtr<XSLStyleSheetImpl> m_styleSheet;
-    khtml::CachedXSLStyleSheet* m_cachedSheet;
+    CachedXSLStyleSheet* m_cachedSheet;
     bool m_loading;
 };