[webkit-changes] [WebKit/WebKit] 0af03d: AX: Web content can become inaccessible when revea...
Tyler Wilcock
noreply at github.com
Fri Jul 26 21:17:10 PDT 2024
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 0af03dfdd5d39c45999aba3e13cd86a2f2f69051
https://github.com/WebKit/WebKit/commit/0af03dfdd5d39c45999aba3e13cd86a2f2f69051
Author: Tyler Wilcock <tyler_w at apple.com>
Date: 2024-07-26 (Fri, 26 Jul 2024)
Changed paths:
A LayoutTests/accessibility/animated-dropdown-expected.txt
A LayoutTests/accessibility/animated-dropdown.html
A LayoutTests/accessibility/resources/jquery-3.6.1.js
M LayoutTests/platform/glib/TestExpectations
M LayoutTests/platform/ios/TestExpectations
A LayoutTests/platform/ios/accessibility/animated-dropdown-expected.txt
M Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp
Log Message:
-----------
AX: Web content can become inaccessible when revealed by an animating dropdown component
https://bugs.webkit.org/show_bug.cgi?id=277160
rdar://132590239
Reviewed by Chris Fleizach.
This bug happened due to this sequence:
1. A button is pressed, animating the dropdown to become open (changing display:none to display:block and quickly
increasing its height from zero to full-height in rapid "ticks").
2. The container of the dropdown and button dynamically becomes ignored, as it no longer has only inline children
(an esoteric condition in `AccessibilityRenderObjet::computeAccessibilityIsIgnored`:
https://github.com/WebKit/WebKit/blob/e27ca2b56be9822117da0ea79062e38e8598cd23/Source/WebCore/accessibility/AccessibilityRenderObject.cpp#L1307)
3. This means the effective parent of the button and dropdown has changed (they have a new unignored parent).
4. In AXIsolatedTree::updateChildren, we prevent deletion of reparented objects via m_protectedFromDeletionIDs.
5. However, the bug is that we clear this list any time we `AXIsolatedTree::queueRemovalsLocked`, rather than once
every tree update cycle (which is essentially by `AXIsolatedTree::queueAppendsAndRemovals`).
6. Because we fail to protect the button from deletion, it is removed from `m_nodeMap` during
`AXIsolatedTree::removeSubtreeFromNodeMap` in the middle of `AXIsolatedTree::updateChildren`.
7. In `AXIsolatedTree::collectNodeChangesForSubtree`, we properly detect that the effective parent for the button
has changed, and queue an entry for it in `AXIsolatedTree::m_needsParentUpdate`.
8. When we process that list in the final `AXIsolatedTree::queueAppendsAndRemovals`, we queue an entry to
`m_pendingParentUpdates` that sets the new parent of the button to the invalid `AXID()`, because we try to get the
new parent of the object from the nodemap, but it was deleted from the nodemap in step 6.
9. The object becomes completely detached from the accessibility tree (having a parent ID of 0), breaking VoiceOver
navigation almost entirely.
Fix this by only clearing `m_protectedFromDeletionIDs` once every tree update cycle (i.e. in
`AXIsolatedTree::queueAppendsAndRemovals`).
This scenario can be triggered by jQuery's slideToggle method (as discovered on a real webpage).
* LayoutTests/accessibility/animated-dropdown-expected.txt: Added.
* LayoutTests/accessibility/animated-dropdown.html: Added.
* LayoutTests/accessibility/resources/jquery-3.6.1.js: Added.
* LayoutTests/platform/glib/TestExpectations: Disable new test.
* LayoutTests/platform/ios/TestExpectations: Enable new test.
* LayoutTests/platform/ios/accessibility/animated-dropdown-expected.txt: Added.
* Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp:
(WebCore::AXIsolatedTree::queueRemovalsLocked):
(WebCore::AXIsolatedTree::queueAppendsAndRemovals):
Canonical link: https://commits.webkit.org/281440@main
To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications
More information about the webkit-changes
mailing list