diff options
Diffstat (limited to 'Source/WebCore/xml/XSLStyleSheetLibxslt.cpp')
-rw-r--r-- | Source/WebCore/xml/XSLStyleSheetLibxslt.cpp | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/Source/WebCore/xml/XSLStyleSheetLibxslt.cpp b/Source/WebCore/xml/XSLStyleSheetLibxslt.cpp index 28a430446..deeaf5a4e 100644 --- a/Source/WebCore/xml/XSLStyleSheetLibxslt.cpp +++ b/Source/WebCore/xml/XSLStyleSheetLibxslt.cpp @@ -27,21 +27,21 @@ #include "Document.h" #include "Frame.h" #include "Page.h" -#include "PageConsole.h" +#include "PageConsoleClient.h" #include "TransformSource.h" #include "XMLDocumentParser.h" #include "XMLDocumentParserScope.h" #include "XSLImportRule.h" #include "XSLTProcessor.h" - #include <libxml/uri.h> #include <libxslt/xsltutils.h> +#include <wtf/CheckedArithmetic.h> -#if PLATFORM(MAC) +#if OS(DARWIN) && !PLATFORM(GTK) #include "SoftLinking.h" #endif -#if PLATFORM(MAC) +#if OS(DARWIN) && !PLATFORM(GTK) SOFT_LINK_LIBRARY(libxslt) SOFT_LINK(libxslt, xsltIsBlank, int, (xmlChar *str), (str)) SOFT_LINK(libxslt, xsltGetNsProp, xmlChar *, (xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace), (node, name, nameSpace)) @@ -52,46 +52,39 @@ SOFT_LINK(libxslt, xsltLoadStylesheetPI, xsltStylesheetPtr, (xmlDocPtr doc), (do namespace WebCore { XSLStyleSheet::XSLStyleSheet(XSLImportRule* parentRule, const String& originalURL, const URL& finalURL) - : m_ownerNode(0) + : m_ownerNode(nullptr) , m_originalURL(originalURL) , m_finalURL(finalURL) - , m_isDisabled(false) , m_embedded(false) , m_processed(false) // Child sheets get marked as processed when the libxslt engine has finally seen them. - , m_stylesheetDoc(0) - , m_stylesheetDocTaken(false) - , m_parentStyleSheet(parentRule ? parentRule->parentStyleSheet() : 0) { + if (parentRule) + m_parentStyleSheet = parentRule->parentStyleSheet(); } XSLStyleSheet::XSLStyleSheet(Node* parentNode, const String& originalURL, const URL& finalURL, bool embedded) : m_ownerNode(parentNode) , m_originalURL(originalURL) , m_finalURL(finalURL) - , m_isDisabled(false) , m_embedded(embedded) , m_processed(true) // The root sheet starts off processed. - , m_stylesheetDoc(0) - , m_stylesheetDocTaken(false) - , m_parentStyleSheet(0) { } XSLStyleSheet::~XSLStyleSheet() { - if (!m_stylesheetDocTaken) - xmlFreeDoc(m_stylesheetDoc); + clearXSLStylesheetDocument(); - for (unsigned i = 0; i < m_children.size(); ++i) { - ASSERT(m_children.at(i)->parentStyleSheet() == this); - m_children.at(i)->setParentStyleSheet(0); + for (auto& import : m_children) { + ASSERT(import->parentStyleSheet() == this); + import->setParentStyleSheet(nullptr); } } bool XSLStyleSheet::isLoading() const { - for (unsigned i = 0; i < m_children.size(); ++i) { - if (m_children.at(i)->isLoading()) + for (auto& import : m_children) { + if (import->isLoading()) return true; } return false; @@ -110,26 +103,36 @@ void XSLStyleSheet::checkLoaded() xmlDocPtr XSLStyleSheet::document() { if (m_embedded && ownerDocument() && ownerDocument()->transformSource()) - return (xmlDocPtr)ownerDocument()->transformSource()->platformSource(); + return ownerDocument()->transformSource()->platformSource(); return m_stylesheetDoc; } void XSLStyleSheet::clearDocuments() { - m_stylesheetDoc = 0; - for (unsigned i = 0; i < m_children.size(); ++i) { - XSLImportRule* import = m_children.at(i).get(); + clearXSLStylesheetDocument(); + + for (auto& import : m_children) { if (import->styleSheet()) import->styleSheet()->clearDocuments(); } } +void XSLStyleSheet::clearXSLStylesheetDocument() +{ + if (!m_stylesheetDocTaken) { + if (m_stylesheetDoc) + xmlFreeDoc(m_stylesheetDoc); + } else + m_stylesheetDocTaken = false; + m_stylesheetDoc = nullptr; +} + CachedResourceLoader* XSLStyleSheet::cachedResourceLoader() { Document* document = ownerDocument(); if (!document) - return 0; - return document->cachedResourceLoader(); + return nullptr; + return &document->cachedResourceLoader(); } bool XSLStyleSheet::parseString(const String& string) @@ -137,25 +140,28 @@ bool XSLStyleSheet::parseString(const String& string) // Parse in a single chunk into an xmlDocPtr const UChar BOM = 0xFEFF; const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM); - if (!m_stylesheetDocTaken) - xmlFreeDoc(m_stylesheetDoc); - m_stylesheetDocTaken = false; + clearXSLStylesheetDocument(); - PageConsole* console = 0; + PageConsoleClient* console = nullptr; Frame* frame = ownerDocument()->frame(); if (frame && frame->page()) console = &frame->page()->console(); XMLDocumentParserScope scope(cachedResourceLoader(), XSLTProcessor::genericErrorFunc, XSLTProcessor::parseErrorFunc, console); - const char* buffer = reinterpret_cast<const char*>(string.deprecatedCharacters()); - int size = string.length() * sizeof(UChar); + auto upconvertedCharacters = StringView(string).upconvertedCharacters(); + const char* buffer = reinterpret_cast<const char*>(upconvertedCharacters.get()); + Checked<unsigned, RecordOverflow> unsignedSize = string.length(); + unsignedSize *= sizeof(UChar); + if (unsignedSize.hasOverflowed() || unsignedSize.unsafeGet() > std::numeric_limits<int>::max()) + return false; + int size = static_cast<int>(unsignedSize.unsafeGet()); xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(buffer, size); if (!ctxt) - return 0; + return false; - if (m_parentStyleSheet) { + if (m_parentStyleSheet && m_parentStyleSheet->m_stylesheetDoc) { // The XSL transform may leave the newly-transformed document // with references to the symbol dictionaries of the style sheet // and any of its children. XML document disposal can corrupt memory @@ -175,7 +181,7 @@ bool XSLStyleSheet::parseString(const String& string) loadChildSheets(); - return m_stylesheetDoc; + return !!m_stylesheetDoc; } void XSLStyleSheet::loadChildSheets() @@ -234,9 +240,8 @@ void XSLStyleSheet::loadChildSheets() void XSLStyleSheet::loadChildSheet(const String& href) { auto childRule = std::make_unique<XSLImportRule>(this, href); - XSLImportRule* c = childRule.get(); m_children.append(childRule.release()); - c->loadSheet(); + m_children.last()->loadSheet(); } xsltStylesheetPtr XSLStyleSheet::compileStyleSheet() @@ -245,12 +250,20 @@ xsltStylesheetPtr XSLStyleSheet::compileStyleSheet() if (m_embedded) return xsltLoadStylesheetPI(document()); + // Certain libxslt versions are corrupting the xmlDoc on compilation + // failures - hence attempting to recompile after a failure is unsafe. + if (m_compilationFailed) + return nullptr; + // xsltParseStylesheetDoc makes the document part of the stylesheet // so we have to release our pointer to it. + ASSERT(m_stylesheetDoc); ASSERT(!m_stylesheetDocTaken); xsltStylesheetPtr result = xsltParseStylesheetDoc(m_stylesheetDoc); if (result) m_stylesheetDocTaken = true; + else + m_compilationFailed = true; return result; } @@ -272,8 +285,7 @@ Document* XSLStyleSheet::ownerDocument() xmlDocPtr XSLStyleSheet::locateStylesheetSubResource(xmlDocPtr parentDoc, const xmlChar* uri) { bool matchedParent = (parentDoc == document()); - for (unsigned i = 0; i < m_children.size(); ++i) { - XSLImportRule* import = m_children.at(i).get(); + for (auto& import : m_children) { XSLStyleSheet* child = import->styleSheet(); if (!child) continue; |