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