Title: [280464] trunk/Source/WebCore
Revision
280464
Author
[email protected]
Date
2021-07-29 19:05:05 -0700 (Thu, 29 Jul 2021)

Log Message

Crash at WebCore: -[WebAccessibilityObjectWrapper _accessibilityTableAncestor].
https://bugs.webkit.org/show_bug.cgi?id=228600
rdar://79910135

Reviewed by Chris Fleizach.

The cause of the crash was that [WebAccessibilityObjectWrapper
_accessibilityTableAncestor] was dereferencing self.axBackingObject
which can be null.
The same problem was present in a number of methods that are retrieving
an ancestor of a given role. This patch solves this problem by calling
_prepareAccessibilityCall before trying to dereference the backing core
object.
Avoided code repetition by adding the helper function ancestorWithRole.

* accessibility/AccessibilityObjectInterface.h:
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(ancestorWithRole):
(-[WebAccessibilityObjectWrapper _accessibilityTreeAncestor]):
(-[WebAccessibilityObjectWrapper _accessibilityDescriptionListAncestor]):
(-[WebAccessibilityObjectWrapper _accessibilityListAncestor]):
(-[WebAccessibilityObjectWrapper _accessibilityArticleAncestor]):
(-[WebAccessibilityObjectWrapper _accessibilityLandmarkAncestor]):
(-[WebAccessibilityObjectWrapper _accessibilityTableAncestor]):
(-[WebAccessibilityObjectWrapper _accessibilityIsInTableCell]):
(-[WebAccessibilityObjectWrapper _accessibilityFieldsetAncestor]):
(-[WebAccessibilityObjectWrapper _accessibilityFrameAncestor]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (280463 => 280464)


--- trunk/Source/WebCore/ChangeLog	2021-07-30 02:00:36 UTC (rev 280463)
+++ trunk/Source/WebCore/ChangeLog	2021-07-30 02:05:05 UTC (rev 280464)
@@ -1,3 +1,33 @@
+2021-07-29  Andres Gonzalez  <[email protected]>
+
+        Crash at WebCore: -[WebAccessibilityObjectWrapper _accessibilityTableAncestor].
+        https://bugs.webkit.org/show_bug.cgi?id=228600
+        rdar://79910135
+
+        Reviewed by Chris Fleizach.
+
+        The cause of the crash was that [WebAccessibilityObjectWrapper
+        _accessibilityTableAncestor] was dereferencing self.axBackingObject
+        which can be null.
+        The same problem was present in a number of methods that are retrieving
+        an ancestor of a given role. This patch solves this problem by calling
+        _prepareAccessibilityCall before trying to dereference the backing core
+        object.
+        Avoided code repetition by adding the helper function ancestorWithRole.
+
+        * accessibility/AccessibilityObjectInterface.h:
+        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+        (ancestorWithRole):
+        (-[WebAccessibilityObjectWrapper _accessibilityTreeAncestor]):
+        (-[WebAccessibilityObjectWrapper _accessibilityDescriptionListAncestor]):
+        (-[WebAccessibilityObjectWrapper _accessibilityListAncestor]):
+        (-[WebAccessibilityObjectWrapper _accessibilityArticleAncestor]):
+        (-[WebAccessibilityObjectWrapper _accessibilityLandmarkAncestor]):
+        (-[WebAccessibilityObjectWrapper _accessibilityTableAncestor]):
+        (-[WebAccessibilityObjectWrapper _accessibilityIsInTableCell]):
+        (-[WebAccessibilityObjectWrapper _accessibilityFieldsetAncestor]):
+        (-[WebAccessibilityObjectWrapper _accessibilityFrameAncestor]):
+
 2021-07-29  Jer Noble  <[email protected]>
 
         [Cocoa|WK1] -[NSAttributeString loadFromHTML...] methods will disable bluetooth route switching

Modified: trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h (280463 => 280464)


--- trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2021-07-30 02:00:36 UTC (rev 280463)
+++ trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2021-07-30 02:05:05 UTC (rev 280464)
@@ -33,6 +33,7 @@
 #include "TextIterator.h"
 #include "VisibleSelection.h"
 #include "Widget.h"
+#include <wtf/HashSet.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Variant.h>
 
@@ -239,6 +240,8 @@
     Window,
 };
 
+using AccessibilityRoleSet = WTF::HashSet<AccessibilityRole, WTF::IntHash<AccessibilityRole>, WTF::StrongEnumHashTraits<AccessibilityRole>>;
+
 ALWAYS_INLINE String accessibilityRoleToString(AccessibilityRole role)
 {
     switch (role) {

Modified: trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (280463 => 280464)


--- trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm	2021-07-30 02:00:36 UTC (rev 280463)
+++ trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm	2021-07-30 02:05:05 UTC (rev 280464)
@@ -587,99 +587,92 @@
     }    
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityTreeAncestor
+static AccessibilityObjectWrapper *ancestorWithRole(const AXCoreObject& descendant, const AccessibilityRoleSet& roles)
 {
-    auto matchFunc = [] (const AXCoreObject& object) {
-        AccessibilityRole role = object.roleValue();
-        return role == AccessibilityRole::Tree;
-    };
+    auto* ancestor = Accessibility::findAncestor(descendant, false, [&roles] (const auto& object) {
+        return roles.contains(object.roleValue());
+    });
+    return ancestor ? ancestor->wrapper() : nil;
+}
 
-    if (const AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, WTFMove(matchFunc)))
-        return parent->wrapper();
-    return nil;
+- (AccessibilityObjectWrapper *)_accessibilityTreeAncestor
+{
+    if (![self _prepareAccessibilityCall])
+        return nil;
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::Tree });
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityDescriptionListAncestor
+- (AccessibilityObjectWrapper *)_accessibilityDescriptionListAncestor
 {
-    auto matchFunc = [] (const AXCoreObject& object) {
-        return object.roleValue() == AccessibilityRole::DescriptionList;
-    };
-    
-    if (const AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, WTFMove(matchFunc)))
-        return parent->wrapper();
-    return nil;
+    if (![self _prepareAccessibilityCall])
+        return nil;
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::DescriptionList });
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityListAncestor
+- (AccessibilityObjectWrapper *)_accessibilityListAncestor
 {
-    auto matchFunc = [] (const AXCoreObject& object) {
-        AccessibilityRole role = object.roleValue();
-        return role == AccessibilityRole::List || role == AccessibilityRole::ListBox;
-    };
-    
-    if (const AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, WTFMove(matchFunc)))
-        return parent->wrapper();
-    return nil;
+    if (![self _prepareAccessibilityCall])
+        return nil;
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::List, AccessibilityRole::ListBox });
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityArticleAncestor
+- (AccessibilityObjectWrapper *)_accessibilityArticleAncestor
 {
-    if (const AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, [] (const AXCoreObject& object) {
-        return object.roleValue() == AccessibilityRole::DocumentArticle;
-    }))
-        return parent->wrapper();
-    return nil;
+    if (![self _prepareAccessibilityCall])
+        return nil;
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::DocumentArticle });
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityLandmarkAncestor
+- (AccessibilityObjectWrapper *)_accessibilityLandmarkAncestor
 {
-    if (const AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, [self] (const AXCoreObject& object) {
-        return [self _accessibilityIsLandmarkRole:object.roleValue()];
-    }))
-        return parent->wrapper();
-    return nil;
+    if (![self _prepareAccessibilityCall])
+        return nil;
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::Document,
+        AccessibilityRole::DocumentArticle,
+        AccessibilityRole::DocumentNote,
+        AccessibilityRole::LandmarkBanner,
+        AccessibilityRole::LandmarkComplementary,
+        AccessibilityRole::LandmarkContentInfo,
+        AccessibilityRole::LandmarkDocRegion,
+        AccessibilityRole::LandmarkMain,
+        AccessibilityRole::LandmarkNavigation,
+        AccessibilityRole::LandmarkRegion,
+        AccessibilityRole::LandmarkSearch });
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityTableAncestor
+- (AccessibilityObjectWrapper *)_accessibilityTableAncestor
 {
-    if (const AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, [] (const AXCoreObject& object) {
-        switch (object.roleValue()) {
-        case AccessibilityRole::Table:
-        case AccessibilityRole::TreeGrid:
-        case AccessibilityRole::Grid:
-            return true;
-        default:
-            return false;
-        }
-    }))
-        return parent->wrapper();
-    return nil;
+    if (![self _prepareAccessibilityCall])
+        return nil;
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::Table,
+        AccessibilityRole::TreeGrid,
+        AccessibilityRole::Grid });
 }
 
 - (BOOL)_accessibilityIsInTableCell
 {
-    return Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, [] (const AXCoreObject& object) {
-        return object.roleValue() == AccessibilityRole::Cell;
-    }) != nullptr;
+    if (![self _prepareAccessibilityCall])
+        return NO;
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::Cell }) != nullptr;
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityFieldsetAncestor
+- (AccessibilityObjectWrapper *)_accessibilityFieldsetAncestor
 {
-    if (const AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, [] (const AXCoreObject& object) {
+    if (![self _prepareAccessibilityCall])
+        return nil;
+
+    auto* ancestor = Accessibility::findAncestor(*self.axBackingObject, false, [] (const auto& object) {
         return object.isFieldset();
-    }))
-        return parent->wrapper();
-    return nil;
+    });
+    return ancestor ? ancestor->wrapper() : nil;
 }
 
-- (AccessibilityObjectWrapper*)_accessibilityFrameAncestor
+- (AccessibilityObjectWrapper *)_accessibilityFrameAncestor
 {
-    auto* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, false, [] (const AXCoreObject& object) {
-        return object.isWebArea();
-    });
-    if (!parent)
+    if (![self _prepareAccessibilityCall])
         return nil;
-    return parent->wrapper();
+
+    return ancestorWithRole(*self.axBackingObject, { AccessibilityRole::WebArea });
 }
 
 - (uint64_t)_accessibilityTraitsFromAncestors
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to