[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