Title: [99740] trunk
Revision
99740
Author
[email protected]
Date
2011-11-09 11:08:03 -0800 (Wed, 09 Nov 2011)

Log Message

AX: crash when accessing selectedTab in a tab list
https://bugs.webkit.org/show_bug.cgi?id=70938

Reviewed by Beth Dakin.

Source/WebCore: 

There were a few methods accessing m_children directly without first validating that those elements
needed to be updated (because the layout changed). Changing those to call children() ensures
that they will have the correct children.

Test: platform/mac/accessibility/selected-tab-crash.html

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::isChecked):
(WebCore::AccessibilityRenderObject::selectedRadioButton):
(WebCore::AccessibilityRenderObject::selectedTabItem):
(WebCore::AccessibilityRenderObject::ariaListboxVisibleChildren):
(WebCore::AccessibilityRenderObject::tabChildren):

Tools: 

Add the ability to retrieve an element through an arbitrary attribute.

* DumpRenderTree/AccessibilityUIElement.cpp:
(uiElementAttributeValueCallback):
(AccessibilityUIElement::uiElementAttributeValue):
(AccessibilityUIElement::getJSClass):
* DumpRenderTree/AccessibilityUIElement.h:
* DumpRenderTree/mac/AccessibilityUIElementMac.mm:
(AccessibilityUIElement::uiElementAttributeValue):

LayoutTests: 

* platform/mac/accessibility/selected-tab-crash-expected.txt: Added.
* platform/mac/accessibility/selected-tab-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (99739 => 99740)


--- trunk/LayoutTests/ChangeLog	2011-11-09 19:03:20 UTC (rev 99739)
+++ trunk/LayoutTests/ChangeLog	2011-11-09 19:08:03 UTC (rev 99740)
@@ -1,3 +1,13 @@
+2011-11-09 Chris Fleizach  <[email protected]>
+
+        AX: crash when accessing selectedTab in a tab list
+        https://bugs.webkit.org/show_bug.cgi?id=70938
+
+        Reviewed by Beth Dakin.
+
+        * platform/mac/accessibility/selected-tab-crash-expected.txt: Added.
+        * platform/mac/accessibility/selected-tab-crash.html: Added.
+
 2011-11-09  Ojan Vafai  <[email protected]>
 
         Remove failures fixed with r99630.

Added: trunk/LayoutTests/platform/mac/accessibility/selected-tab-crash-expected.txt (0 => 99740)


--- trunk/LayoutTests/platform/mac/accessibility/selected-tab-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/accessibility/selected-tab-crash-expected.txt	2011-11-09 19:08:03 UTC (rev 99740)
@@ -0,0 +1,11 @@
+tab 2
+tab 3
+This tests that if a tablists children are updated, we will not crash accessing an old object.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/platform/mac/accessibility/selected-tab-crash.html (0 => 99740)


--- trunk/LayoutTests/platform/mac/accessibility/selected-tab-crash.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/accessibility/selected-tab-crash.html	2011-11-09 19:08:03 UTC (rev 99740)
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script>
+var successfullyParsed = false;
+</script>
+<script src=""
+</head>
+<body id="body">
+
+<div role="tablist" tabindex="0" id="tablist">
+<div role="tab" aria-checked="true" id="selectedtab">tab 1</div>
+<div role="tab">tab 2</div>
+<div role="tab">tab 3</div>
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that if a tablists children are updated, we will not crash accessing an old object.");
+
+    if (window.accessibilityController) {
+
+        document.getElementById("tablist").focus();
+        var tablist = accessibilityController.focusedElement;
+
+        // Iterate all the children so we have a cache of them.
+        tablist.attributesOfChildren();
+
+        // Retrieve and verify we have the right selected child.
+        var selectedTab = tablist.uiElementAttributeValue("AXValue");
+
+        // Delete the selected child.
+        document.getElementById("tablist").removeChild(document.getElementById("selectedtab"));
+
+        // Retrieve the tab. We should not crash here!
+        var selectedTab = tablist.uiElementAttributeValue("AXValue");
+    }
+
+    successfullyParsed = true;
+</script>
+
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (99739 => 99740)


--- trunk/Source/WebCore/ChangeLog	2011-11-09 19:03:20 UTC (rev 99739)
+++ trunk/Source/WebCore/ChangeLog	2011-11-09 19:08:03 UTC (rev 99740)
@@ -1,3 +1,23 @@
+2011-11-09  Chris Fleizach  <[email protected]>
+
+        AX: crash when accessing selectedTab in a tab list
+        https://bugs.webkit.org/show_bug.cgi?id=70938
+
+        Reviewed by Beth Dakin.
+
+        There were a few methods accessing m_children directly without first validating that those elements
+        needed to be updated (because the layout changed). Changing those to call children() ensures
+        that they will have the correct children.
+
+        Test: platform/mac/accessibility/selected-tab-crash.html
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::isChecked):
+        (WebCore::AccessibilityRenderObject::selectedRadioButton):
+        (WebCore::AccessibilityRenderObject::selectedTabItem):
+        (WebCore::AccessibilityRenderObject::ariaListboxVisibleChildren):
+        (WebCore::AccessibilityRenderObject::tabChildren):
+
 2011-11-09  Andreas Kling  <[email protected]>
 
         Shrink HTMLCollection.

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (99739 => 99740)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2011-11-09 19:03:20 UTC (rev 99739)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2011-11-09 19:08:03 UTC (rev 99740)
@@ -628,11 +628,13 @@
 bool AccessibilityRenderObject::isChecked() const
 {
     ASSERT(m_renderer);
-    if (!m_renderer->node())
+    
+    Node* node = this->node();
+    if (!node)
         return false;
 
     // First test for native checkedness semantics
-    HTMLInputElement* inputElement = m_renderer->node()->toInputElement();
+    HTMLInputElement* inputElement = node->toInputElement();
     if (inputElement)
         return inputElement->shouldAppearChecked();
 
@@ -775,10 +777,12 @@
     if (!isRadioGroup())
         return 0;
     
+    AccessibilityObject::AccessibilityChildrenVector children = this->children();
+
     // Find the child radio button that is selected (ie. the intValue == 1).
-    int count = m_children.size();
-    for (int i = 0; i < count; ++i) {
-        AccessibilityObject* object = m_children[i].get();
+    size_t size = children.size();
+    for (size_t i = 0; i < size; ++i) {
+        AccessibilityObject* object = children[i].get();
         if (object->roleValue() == RadioButtonRole && object->checkboxOrRadioValue() == ButtonStateOn)
             return object;
     }
@@ -794,9 +798,11 @@
     AccessibilityObject::AccessibilityChildrenVector tabs;
     tabChildren(tabs);
     
-    int count = tabs.size();
-    for (int i = 0; i < count; ++i) {
-        AccessibilityObject* object = m_children[i].get();
+    AccessibilityObject::AccessibilityChildrenVector children = this->children();
+    
+    size_t size = tabs.size();
+    for (size_t i = 0; i < size; ++i) {
+        AccessibilityObject* object = children[i].get();
         if (object->isTabItem() && object->isChecked())
             return object;
     }
@@ -3661,10 +3667,11 @@
     if (!hasChildren())
         addChildren();
     
-    unsigned length = m_children.size();
-    for (unsigned i = 0; i < length; i++) {
-        if (!m_children[i]->isOffScreen())
-            result.append(m_children[i]);
+    AccessibilityObject::AccessibilityChildrenVector children = this->children();
+    size_t size = children.size();
+    for (size_t i = 0; i < size; i++) {
+        if (!children[i]->isOffScreen())
+            result.append(children[i]);
     }
 }
 
@@ -3684,10 +3691,11 @@
 {
     ASSERT(roleValue() == TabListRole);
     
-    unsigned length = m_children.size();
-    for (unsigned i = 0; i < length; ++i) {
-        if (m_children[i]->isTabItem())
-            result.append(m_children[i]);
+    AccessibilityObject::AccessibilityChildrenVector children = this->children();
+    size_t size = children.size();
+    for (size_t i = 0; i < size; ++i) {
+        if (children[i]->isTabItem())
+            result.append(children[i]);
     }
 }
     

Modified: trunk/Tools/ChangeLog (99739 => 99740)


--- trunk/Tools/ChangeLog	2011-11-09 19:03:20 UTC (rev 99739)
+++ trunk/Tools/ChangeLog	2011-11-09 19:08:03 UTC (rev 99740)
@@ -1,3 +1,20 @@
+2011-11-09  Chris Fleizach  <[email protected]>
+
+        AX: crash when accessing selectedTab in a tab list
+        https://bugs.webkit.org/show_bug.cgi?id=70938
+
+        Reviewed by Beth Dakin.
+
+        Add the ability to retrieve an element through an arbitrary attribute.
+
+        * DumpRenderTree/AccessibilityUIElement.cpp:
+        (uiElementAttributeValueCallback):
+        (AccessibilityUIElement::uiElementAttributeValue):
+        (AccessibilityUIElement::getJSClass):
+        * DumpRenderTree/AccessibilityUIElement.h:
+        * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+        (AccessibilityUIElement::uiElementAttributeValue):
+
 2011-11-09  Andy Wingo  <[email protected]>
 
         Add webkitdirs.pm:getArchitecture implementation for GTK

Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp (99739 => 99740)


--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp	2011-11-09 19:03:20 UTC (rev 99739)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp	2011-11-09 19:08:03 UTC (rev 99740)
@@ -374,6 +374,15 @@
     return result;
 }
 
+static JSValueRef uiElementAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    JSStringRef attribute = 0;
+    if (argumentCount == 1)
+        attribute = JSValueToStringCopy(context, arguments[0], exception);
+    
+    return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->uiElementAttributeValue(attribute));
+}
+
 static JSValueRef numberAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     JSStringRef attribute = 0;
@@ -859,6 +868,7 @@
 void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement*) const { }
 unsigned AccessibilityUIElement::selectedChildrenCount() const { return 0; }
 AccessibilityUIElement AccessibilityUIElement::selectedChildAtIndex(unsigned) const { return 0; }
+AccessibilityUIElement AccessibilityUIElement::uiElementAttributeValue(JSStringRef) const { return 0; }
 #endif
 
 #if !PLATFORM(WIN)
@@ -933,6 +943,9 @@
 
 JSObjectRef AccessibilityUIElement::makeJSAccessibilityUIElement(JSContextRef context, const AccessibilityUIElement& element)
 {
+    if (!element)
+        return 0;
+    
     return JSObjectMake(context, AccessibilityUIElement::getJSClass(), new AccessibilityUIElement(element));
 }
 
@@ -1020,6 +1033,7 @@
         { "titleUIElement", titleUIElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setSelectedTextRange", setSelectedTextRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "stringAttributeValue", stringAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "uiElementAttributeValue", uiElementAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "numberAttributeValue", numberAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "boolAttributeValue", boolAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isAttributeSupported", isAttributeSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },

Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.h (99739 => 99740)


--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.h	2011-11-09 19:03:20 UTC (rev 99739)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.h	2011-11-09 19:08:03 UTC (rev 99740)
@@ -105,6 +105,7 @@
     // Attributes - platform-independent implementations
     JSStringRef stringAttributeValue(JSStringRef attribute);
     double numberAttributeValue(JSStringRef attribute);
+    AccessibilityUIElement uiElementAttributeValue(JSStringRef attribute);    
     bool boolAttributeValue(JSStringRef attribute);
     bool isAttributeSupported(JSStringRef attribute);
     bool isAttributeSettable(JSStringRef attribute);

Modified: trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm (99739 => 99740)


--- trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm	2011-11-09 19:03:20 UTC (rev 99739)
+++ trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm	2011-11-09 19:08:03 UTC (rev 99740)
@@ -480,6 +480,17 @@
     return 0;
 }
 
+AccessibilityUIElement AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute)
+{
+    BEGIN_AX_OBJC_EXCEPTIONS
+    id uiElement = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
+    return AccessibilityUIElement(uiElement);
+    END_AX_OBJC_EXCEPTIONS
+    
+    return 0;
+}
+
+
 double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
 {
     BEGIN_AX_OBJC_EXCEPTIONS
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to