Source/WebCore: Invalid cast in WebCore::toRenderMathMLBlock
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Oct 2013 17:40:52 +0000 (17:40 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Oct 2013 17:40:52 +0000 (17:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=121728
rdar://problem/15046151

Reviewed by Dean Jackson.

Tested by: mathml/arbitrary-markup.html

* dom/Element.h: Expose childShouldCreateRenderer for
MathML as well as SVG builds.
* dom/Node.h:
(WebCore::Node::isMathMLElement): Added.
* mathml/MathMLElement.cpp:
(WebCore::MathMLElement::create): Create as MathML Element.
(WebCore::MathMLElement::childShouldCreateRenderer):
Only allow the child to emit a renderer if it is a
MathML element.
* mathml/MathMLElement.h:

LayoutTests: [MathML] invalid cast in WebCore::toRenderMathMLBlock
https://bugs.webkit.org/show_bug.cgi?id=121728

Reviewed by Dean Jackson.

* mathml/arbitrary-markup-expected.txt: Added.
* mathml/arbitrary-markup.html: Added.
* mathml/mfenced-root-layer.html: Modified to avoid invalid
use of arbitrary markup inside mfenced element.
* mathml/mfenced-root-layer-expected.txt: Rebaselined.

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

13 files changed:
LayoutTests/ChangeLog
LayoutTests/mathml/arbitrary-markup-expected.txt [new file with mode: 0644]
LayoutTests/mathml/arbitrary-markup.html [new file with mode: 0644]
LayoutTests/mathml/mfenced-root-layer-expected.txt
LayoutTests/mathml/mfenced-root-layer.html
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.h
Source/WebCore/mathml/MathMLElement.cpp
Source/WebCore/mathml/MathMLElement.h
Source/WebCore/mathml/MathMLTextElement.cpp
Source/WebCore/mathml/MathMLTextElement.h
Source/WebCore/rendering/mathml/RenderMathMLScripts.cpp

index 42614db..2b87960 100644 (file)
@@ -1,3 +1,16 @@
+2013-10-25  Brent Fulgham  <bfulgham@apple.com>
+
+        [MathML] invalid cast in WebCore::toRenderMathMLBlock
+        https://bugs.webkit.org/show_bug.cgi?id=121728
+
+        Reviewed by Dean Jackson.
+
+        * mathml/arbitrary-markup-expected.txt: Added.
+        * mathml/arbitrary-markup.html: Added.
+        * mathml/mfenced-root-layer.html: Modified to avoid invalid
+        use of arbitrary markup inside mfenced element.
+        * mathml/mfenced-root-layer-expected.txt: Rebaselined.
+
 2013-10-29  Chris Fleizach  <cfleizach@apple.com>
 
         AX: elements with explicit tabindex should expose AXFocused as writable, since mouse clicks can focus it
diff --git a/LayoutTests/mathml/arbitrary-markup-expected.txt b/LayoutTests/mathml/arbitrary-markup-expected.txt
new file mode 100644 (file)
index 0000000..711d47e
--- /dev/null
@@ -0,0 +1,2 @@
+b
+
diff --git a/LayoutTests/mathml/arbitrary-markup.html b/LayoutTests/mathml/arbitrary-markup.html
new file mode 100644 (file)
index 0000000..bf3ac7d
--- /dev/null
@@ -0,0 +1,38 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+    <title>MathML: inserting arbitrary markup</title>
+    <script>
+        if (window.testRunner)
+        testRunner.dumpAsText();
+    </script>
+</head>
+<body>
+<table>
+    <tr>
+        <td><math id="math"></math></td>
+    </tr>
+    <tr>
+        <td>
+            <math xmlns="http://www.w3.org/1998/Math/MathML">
+                <msub>
+                    <mi id="mi1">a</mi>
+                    <mi id="mi2">b</mi>
+                </msub>
+            </math>
+        </td>
+    </tr>
+</table>
+<script>
+var elem = document.getElementById("mi2"); 
+var parent = elem.parentNode;
+var new_elem = document.createElement("wbr");
+parent.insertBefore(new_elem, elem);
+node = document.getElementById("math").appendChild(document.createElement("object")).lastElementChild;
+elem = document.getElementById("mi1"); 
+parent = elem.parentNode;
+new_elem = document.createElement("strong");
+parent.insertBefore(new_elem, elem);
+parent.removeChild(elem);
+</script>
+</body>
+</html>
index f4be9c3..93e038f 100644 (file)
@@ -1,2 +1 @@
-Bug 100764: Heap-use-after-free in WebCore::RenderLayer::paintList [MathML]
-This test passes if it does not crash.
+Bug 100764: Heap-use-after-free in WebCore::RenderLayer::paintList [MathML]. This test passes if it does not crash.
index 44b269d..8ceaabd 100644 (file)
@@ -3,14 +3,13 @@
     if (window.testRunner)
         testRunner.dumpAsText();
 
-    var mfenced = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mfenced");
+    var mtext = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mtext");
 
     var docElt = document.documentElement;
     docElt.parentNode.removeChild(docElt);
 
-    document.appendChild(mfenced);
+    var textNode = document.createTextNode("Bug 100764: Heap-use-after-free in WebCore::RenderLayer::paintList [MathML]. This test passes if it does not crash.");
+    mtext.appendChild(textNode);
 
-    var e = document.createElement("div");
-    e.innerHTML = "<a href='https://bugs.webkit.org/show_bug.cgi?id=100764'>Bug 100764</a>: Heap-use-after-free in WebCore::RenderLayer::paintList [MathML]<br>This test passes if it does not crash.";
-    mfenced.appendChild(e);
+    document.appendChild(mtext);
 </script>
index 43cd426..a2efb51 100644 (file)
@@ -1,3 +1,24 @@
+2013-10-24  Brent Fulgham  <bfulgham@apple.com>
+
+        Invalid cast in WebCore::toRenderMathMLBlock
+        https://bugs.webkit.org/show_bug.cgi?id=121728
+        rdar://problem/15046151
+
+        Reviewed by Dean Jackson.
+
+        Tested by: mathml/arbitrary-markup.html
+
+        * dom/Element.h: Expose childShouldCreateRenderer for
+        MathML as well as SVG builds.
+        * dom/Node.h: 
+        (WebCore::Node::isMathMLElement): Added.
+        * mathml/MathMLElement.cpp:
+        (WebCore::MathMLElement::create): Create as MathML Element.
+        (WebCore::MathMLElement::childShouldCreateRenderer):
+        Only allow the child to emit a renderer if it is a
+        MathML element.
+        * mathml/MathMLElement.h:
+
 2013-10-29  Andreas Kling  <akling@apple.com>
 
         SVG: applyStrokeStyleToContext should take a RenderElement&.
index 6e2d969..ef4cd41 100644 (file)
@@ -452,12 +452,6 @@ public:
 
     DOMStringMap* dataset();
 
-#if ENABLE(MATHML)
-    virtual bool isMathMLElement() const { return false; }
-#else
-    static bool isMathMLElement() { return false; }
-#endif
-
 #if ENABLE(VIDEO)
     virtual bool isMediaElement() const { return false; }
 #endif
@@ -486,8 +480,10 @@ public:
     virtual bool isDisabledFormControl() const { return false; }
 
 
-#if ENABLE(SVG)
+#if ENABLE(SVG) || ENABLE(MATHML)
     virtual bool childShouldCreateRenderer(const Node*) const OVERRIDE;
+#endif
+#if ENABLE(SVG)
     bool hasPendingResources() const;
     void setHasPendingResources();
     void clearHasPendingResources();
index 603468d..319c562 100644 (file)
@@ -224,6 +224,7 @@ public:
     bool isTextNode() const { return getFlag(IsTextFlag); }
     bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
     bool isSVGElement() const { return getFlag(IsSVGFlag); }
+    bool isMathMLElement() const { return getFlag(IsMathMLFlag); }
 
     bool isPseudoElement() const { return pseudoId() != NOPSEUDO; }
     bool isBeforePseudoElement() const { return pseudoId() == BEFORE; }
@@ -596,6 +597,7 @@ private:
         HasEventTargetDataFlag = 1 << 21,
         NeedsNodeRenderingTraversalSlowPathFlag = 1 << 22,
         IsInShadowTreeFlag = 1 << 23,
+        IsMathMLFlag = 1 << 24,
 
         DefaultNodeFlags = IsParsingChildrenFinishedFlag
     };
@@ -622,6 +624,7 @@ protected:
         CreateDocument = CreateContainer | InDocumentFlag,
         CreateInsertionPoint = CreateHTMLElement | NeedsNodeRenderingTraversalSlowPathFlag,
         CreateEditingText = CreateText | IsEditingTextFlag,
+        CreateMathMLElement = CreateStyledElement | IsMathMLFlag,
     };
     Node(Document*, ConstructionType);
 
index 06eea48..433a7c2 100644 (file)
@@ -39,7 +39,7 @@ namespace WebCore {
 using namespace MathMLNames;
     
 MathMLElement::MathMLElement(const QualifiedName& tagName, Document& document)
-    : StyledElement(tagName, document, CreateStyledElement)
+    : StyledElement(tagName, document, CreateMathMLElement)
 {
 }
     
@@ -113,6 +113,12 @@ void MathMLElement::collectStyleForPresentationAttribute(const QualifiedName& na
     }
 }
 
+bool MathMLElement::childShouldCreateRenderer(const Node* child) const
+{
+    // Only create renderers for MathML elements or text. MathML prohibits non-MathML markup inside a <math> element.
+    return child->isTextNode() || child->isMathMLElement();
+}
+
 }
 
 #endif // ENABLE(MATHML)
index 4396ddf..84085e8 100644 (file)
@@ -41,14 +41,14 @@ public:
     int colSpan() const;
     int rowSpan() const;
 
+    virtual bool childShouldCreateRenderer(const Node*) const OVERRIDE;
+
 protected:
     MathMLElement(const QualifiedName& tagName, Document&);
 
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
 
 private:    
-    virtual bool isMathMLElement() const { return true; }
-
     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
 };
index dcef222..9e3f7ee 100644 (file)
@@ -73,6 +73,11 @@ RenderElement* MathMLTextElement::createRenderer(PassRef<RenderStyle> style)
     return MathMLElement::createRenderer(std::move(style));
 }
 
+bool MathMLTextElement::childShouldCreateRenderer(const Node* child) const
+{
+    return child->isTextNode();
+}
+
 }
 
 #endif // ENABLE(MATHML)
index a7933d2..c8327ea 100644 (file)
@@ -37,6 +37,8 @@ public:
     static PassRefPtr<MathMLTextElement> create(const QualifiedName& tagName, Document&);
     virtual void didAttachRenderers() OVERRIDE;
 
+    virtual bool childShouldCreateRenderer(const Node*) const OVERRIDE;
+
 private:
     MathMLTextElement(const QualifiedName& tagName, Document&);
 
index 65b2e27..9f3bb8e 100644 (file)
@@ -153,9 +153,12 @@ void RenderMathMLScripts::addChildInternal(bool doNotRestructure, RenderObject*
         // beforeChild may be a grandchild, so we call the addChild function of the corresponding wrapper instead.
         RenderObject* parent = beforeChild->parent();
         if (parent != this) {
-            RenderMathMLScriptsWrapper* wrapper = toRenderMathMLScriptsWrapper(parent);
-            wrapper->addChildInternal(false, child, beforeChild);
-            return;
+            RenderMathMLBlock* parentBlock = toRenderMathMLBlock(parent);
+            if (parentBlock->isRenderMathMLScriptsWrapper()) {
+                RenderMathMLScriptsWrapper* wrapper = toRenderMathMLScriptsWrapper(parentBlock);
+                wrapper->addChildInternal(false, child, beforeChild);
+                return;
+            }
         }
     }