Avoid reparsing an XSLT stylesheet after the first failure.

Certain libxslt versions appear to leave the doc in an invalid state when parsing fails. We should cache this result and avoid re-parsing.

(The test cannot be converted to text-only due to its invalid stylesheet).

R=inferno@chromium.org,abarth@chromium.org,pdr@chromium.org
BUG=271939

Review URL: https://chromiumcodereview.appspot.com/23103007

git-svn-id: svn://svn.chromium.org/blink/trunk@156248 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations
index 80c149f..7b087ff 100644
--- a/LayoutTests/TestExpectations
+++ b/LayoutTests/TestExpectations
@@ -250,6 +250,8 @@
 crbug.com/266213 [ Debug ] svg/custom/bug86392.html [ Crash ]
 crbug.com/266213 [ Debug ] svg/custom/unicode-in-tspan-multi-svg-crash.html [ Crash ]
 
+Bug(fmalita) svg/custom/invalid-xslt-crash.svg [ NeedsRebaseline ]
+
 # -----------------------------------------------------------------
 # End SVG TESTS
 # -----------------------------------------------------------------
diff --git a/LayoutTests/svg/custom/invalid-xslt-crash.svg b/LayoutTests/svg/custom/invalid-xslt-crash.svg
new file mode 100644
index 0000000..e212f2b
--- /dev/null
+++ b/LayoutTests/svg/custom/invalid-xslt-crash.svg
@@ -0,0 +1,7 @@
+<?xml-stylesheet type="application/xml" href=""?>
+<svg xmlns="http://www.w3.org/2000/svg"
+		xmlns:xslt="http://www.w3.org/1999/XSL/Transform"
+		xslt:version="1.0">
+  <!-- The test passes if it doesn't crash -->
+  <xslt:attribute nnnnnnnnnnname="fill">lime</xslt:attribute>
+</svg>
diff --git a/Source/core/xml/XSLStyleSheet.h b/Source/core/xml/XSLStyleSheet.h
index 3ca331a..6b21a11 100644
--- a/Source/core/xml/XSLStyleSheet.h
+++ b/Source/core/xml/XSLStyleSheet.h
@@ -111,6 +111,7 @@
 
     xmlDocPtr m_stylesheetDoc;
     bool m_stylesheetDocTaken;
+    bool m_compilationFailed;
 
     XSLStyleSheet* m_parentStyleSheet;
 };
diff --git a/Source/core/xml/XSLStyleSheetLibxslt.cpp b/Source/core/xml/XSLStyleSheetLibxslt.cpp
index 35ea279..bce87ad 100644
--- a/Source/core/xml/XSLStyleSheetLibxslt.cpp
+++ b/Source/core/xml/XSLStyleSheetLibxslt.cpp
@@ -47,6 +47,7 @@
     , m_processed(false) // Child sheets get marked as processed when the libxslt engine has finally seen them.
     , m_stylesheetDoc(0)
     , m_stylesheetDocTaken(false)
+    , m_compilationFailed(false)
     , m_parentStyleSheet(parentRule ? parentRule->parentStyleSheet() : 0)
 {
 }
@@ -60,6 +61,7 @@
     , m_processed(true) // The root sheet starts off processed.
     , m_stylesheetDoc(0)
     , m_stylesheetDocTaken(false)
+    , m_compilationFailed(false)
     , m_parentStyleSheet(0)
 {
 }
@@ -226,12 +228,19 @@
     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 0;
+
     // xsltParseStylesheetDoc makes the document part of the stylesheet
     // so we have to release our pointer to it.
     ASSERT(!m_stylesheetDocTaken);
     xsltStylesheetPtr result = xsltParseStylesheetDoc(m_stylesheetDoc);
     if (result)
         m_stylesheetDocTaken = true;
+    else
+        m_compilationFailed = true;
     return result;
 }