AX: [ATK] Crash getting text under element in CSS table
authorjdiggs@igalia.com <jdiggs@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Apr 2016 16:36:01 +0000 (16:36 +0000)
committerjdiggs@igalia.com <jdiggs@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Apr 2016 16:36:01 +0000 (16:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156328

Reviewed by Chris Fleizach.

Source/WebCore:

AccessibilityRenderObject::textUnderElement() assumes (and asserts) that
the first and last child of an anonymous block will each have nodes with
which to define positions. This is not the case for CSS Tables and their
anonymous descendants. AccessibilityNodeObject:textUnderElement() is our
fallback for the instances where a text range cannot be created based on
positions, so let it handle anonymous RenderTable parts.

Test: accessibility/generated-content-with-display-table-crash.html

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::textUnderElement):
(WebCore::AccessibilityRenderObject::shouldGetTextFromNode):
* accessibility/AccessibilityRenderObject.h:

LayoutTests:

While this crash is currently seen only for ATK, there is nothing to
prevent another port from attempting to get all the text under a CSS
RenderTable. Hence the shared test.

* accessibility/generated-content-with-display-table-crash.html: Added.
* platform/gtk/accessibility/generated-content-with-display-table-crash-expected.txt: Added.
* platform/mac/accessibility/generated-content-with-display-table-crash-expected.txt: Added.

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

LayoutTests/ChangeLog
LayoutTests/accessibility/generated-content-with-display-table-crash.html [new file with mode: 0644]
LayoutTests/platform/gtk/accessibility/generated-content-with-display-table-crash-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/accessibility/generated-content-with-display-table-crash-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/accessibility/AccessibilityRenderObject.h

index dc2691b..d3f793b 100644 (file)
@@ -1,3 +1,18 @@
+2016-04-08  Joanmarie Diggs  <jdiggs@igalia.com>
+
+        AX: [ATK] Crash getting text under element in CSS table
+        https://bugs.webkit.org/show_bug.cgi?id=156328
+
+        Reviewed by Chris Fleizach.
+
+        While this crash is currently seen only for ATK, there is nothing to
+        prevent another port from attempting to get all the text under a CSS
+        RenderTable. Hence the shared test.
+
+        * accessibility/generated-content-with-display-table-crash.html: Added.
+        * platform/gtk/accessibility/generated-content-with-display-table-crash-expected.txt: Added.
+        * platform/mac/accessibility/generated-content-with-display-table-crash-expected.txt: Added.
+
 2016-04-08  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: Quick Open fails to match pattern "bB" in file "abBc"
diff --git a/LayoutTests/accessibility/generated-content-with-display-table-crash.html b/LayoutTests/accessibility/generated-content-with-display-table-crash.html
new file mode 100644 (file)
index 0000000..eea8661
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+<script src="../resources/accessibility-helper.js"></script>
+<style>
+[class*="foo"]:after { content: "!"; }
+[class*="bar"]:after { content: "!"; display: table; }
+[class*="baz"]:after { display: table; }
+</style>
+</head>
+<body id="body">
+<div id="div1" class="foo">foo</div>
+<div id="div2" class="bar">bar</div>
+<div id="div3" class="baz">baz</div>
+<div id="stopElement">End of test</div>
+
+<pre id="tree"></pre>
+
+<p id="description"></p>
+<div id="console"></div>
+<script>
+    description("This verifies that getting content of an element with generated content in CSS table doesn't cause a crash.");
+    if (window.accessibilityController) {
+        document.body.focus();
+        var stopElement = accessibilityController.accessibleElementById("stopElement");
+        dumpAccessibilityTree(accessibilityController.focusedElement, stopElement, 0);
+    }
+</script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/gtk/accessibility/generated-content-with-display-table-crash-expected.txt b/LayoutTests/platform/gtk/accessibility/generated-content-with-display-table-crash-expected.txt
new file mode 100644 (file)
index 0000000..ef937d7
--- /dev/null
@@ -0,0 +1,18 @@
+foo
+bar
+baz
+End of test
+AXRole: AXWebArea 
+    AXRole: AXSection AXValue: foo !
+    AXRole: AXSection AXValue: bar !
+    AXRole: AXSection AXValue: baz
+    AXRole: AXSection AXValue: End of test
+This verifies that getting content of an element with generated content in CSS table doesn't cause a crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/accessibility/generated-content-with-display-table-crash-expected.txt b/LayoutTests/platform/mac/accessibility/generated-content-with-display-table-crash-expected.txt
new file mode 100644 (file)
index 0000000..d79d7b0
--- /dev/null
@@ -0,0 +1,23 @@
+foo
+bar
+baz
+End of test
+AXRole: AXWebArea AXValue: 
+    AXRole: AXGroup AXValue: 
+        AXRole: AXStaticText AXValue: foo
+        AXRole: AXStaticText AXValue: !
+    AXRole: AXGroup AXValue: 
+        AXRole: AXStaticText AXValue: bar
+    AXRole: AXStaticText AXValue: !
+    AXRole: AXGroup AXValue: 
+        AXRole: AXStaticText AXValue: baz
+    AXRole: AXGroup AXValue: 
+This verifies that getting content of an element with generated content in CSS table doesn't cause a crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index be9169c..03f4828 100644 (file)
@@ -1,3 +1,24 @@
+2016-04-08  Joanmarie Diggs  <jdiggs@igalia.com>
+
+        AX: [ATK] Crash getting text under element in CSS table
+        https://bugs.webkit.org/show_bug.cgi?id=156328
+
+        Reviewed by Chris Fleizach.
+
+        AccessibilityRenderObject::textUnderElement() assumes (and asserts) that
+        the first and last child of an anonymous block will each have nodes with
+        which to define positions. This is not the case for CSS Tables and their
+        anonymous descendants. AccessibilityNodeObject:textUnderElement() is our
+        fallback for the instances where a text range cannot be created based on
+        positions, so let it handle anonymous RenderTable parts.
+
+        Test: accessibility/generated-content-with-display-table-crash.html
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::textUnderElement):
+        (WebCore::AccessibilityRenderObject::shouldGetTextFromNode):
+        * accessibility/AccessibilityRenderObject.h:
+
 2016-04-08  Darin Adler  <darin@apple.com>
 
         Remove unneeded UsePointersEvenForNonNullableObjectArguments from event classes
index e179b17..e51578d 100644 (file)
@@ -644,8 +644,7 @@ String AccessibilityRenderObject::textUnderElement(AccessibilityTextUnderElement
         return downcast<RenderMathMLOperator>(*m_renderer).element().textContent();
 #endif
 
-    // rangeOfContents does not include CSS-generated content.
-    if (m_renderer->isBeforeOrAfterContent())
+    if (shouldGetTextFromNode(mode))
         return AccessibilityNodeObject::textUnderElement(mode);
 
     // We use a text iterator for text objects AND for those cases where we are
@@ -657,12 +656,6 @@ String AccessibilityRenderObject::textUnderElement(AccessibilityTextUnderElement
         Document* nodeDocument = nullptr;
         RefPtr<Range> textRange;
         if (Node* node = m_renderer->node()) {
-            // rangeOfContents does not include CSS-generated content.
-            Node* firstChild = node->pseudoAwareFirstChild();
-            Node* lastChild = node->pseudoAwareLastChild();
-            if ((firstChild && firstChild->isPseudoElement()) || (lastChild && lastChild->isPseudoElement()))
-                return AccessibilityNodeObject::textUnderElement(mode);
-
             nodeDocument = &node->document();
             textRange = rangeOfContents(*node);
         } else {
@@ -720,6 +713,31 @@ String AccessibilityRenderObject::textUnderElement(AccessibilityTextUnderElement
     return AccessibilityNodeObject::textUnderElement(mode);
 }
 
+bool AccessibilityRenderObject::shouldGetTextFromNode(AccessibilityTextUnderElementMode mode) const
+{
+    if (!m_renderer)
+        return false;
+
+    // AccessibilityRenderObject::textUnderElement() gets the text of anonymous blocks by using
+    // the child nodes to define positions. CSS tables and their anonymous descendants lack
+    // children with nodes.
+    if (m_renderer->isAnonymous() && m_renderer->isTablePart())
+        return mode.childrenInclusion == AccessibilityTextUnderElementMode::TextUnderElementModeIncludeAllChildren;
+
+    // AccessibilityRenderObject::textUnderElement() calls rangeOfContents() to create the text
+    // range. rangeOfContents() does not include CSS-generated content.
+    if (m_renderer->isBeforeOrAfterContent())
+        return true;
+    if (Node* node = m_renderer->node()) {
+        Node* firstChild = node->pseudoAwareFirstChild();
+        Node* lastChild = node->pseudoAwareLastChild();
+        if ((firstChild && firstChild->isPseudoElement()) || (lastChild && lastChild->isPseudoElement()))
+            return true;
+    }
+
+    return false;
+}
+
 Node* AccessibilityRenderObject::node() const
 {
     if (!m_renderer)
index fd4d492..406198a 100644 (file)
@@ -279,6 +279,8 @@ private:
 
     bool inheritsPresentationalRole() const override;
 
+    bool shouldGetTextFromNode(AccessibilityTextUnderElementMode) const;
+
 #if ENABLE(MATHML)
     // All math elements return true for isMathElement().
     bool isMathElement() const override;