Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 803f725dbc584e54cf6b6c81a2e7de7666a622b1
      
https://github.com/WebKit/WebKit/commit/803f725dbc584e54cf6b6c81a2e7de7666a622b1
  Author: Tyler Wilcock <[email protected]>
  Date:   2026-05-10 (Sun, 10 May 2026)

  Changed paths:
    M LayoutTests/accessibility-isolated-tree/TestExpectations
    A 
LayoutTests/accessibility/mac/replaced-element-line-index-hang-expected.txt
    A LayoutTests/accessibility/mac/replaced-element-line-index-hang.html
    M Source/WebCore/accessibility/AXTextMarker.cpp
    M Source/WebCore/accessibility/AXTextRun.h
    M Source/WebCore/accessibility/AccessibilityRenderObject.cpp

  Log Message:
  -----------
  AX: AXTextMarker::findLine can hang when a replaced element (e.g. an image) 
shares a containing block with normal inline content
https://bugs.webkit.org/show_bug.cgi?id=314359
rdar://176509656

Reviewed by Dominic Mazzoni.

AccessibilityRenderObject::textRuns() hardcoded lineIndex = 0 for every replaced
element (image, SVG, video, etc.). When such an element was a DOM sibling of a
soft-wrapping inline text in the same containing block, the hardcoded 0 produced
an AXTextRunLineID identical to the text's first wrap line. 
AXTextMarker::findLine
then returned its input marker on every call, and AXTextMarker::lineIndex spun 
forever
asking nextLineEnd() to advance, hanging the AX thread.

This commit fixes the issue in a few ways:

1. For in-flow inline replaced elements, compute the actual lineIndex via
 InlineIterator::boxFor(), matching the existing pattern in the RenderLineBreak
 branch directly above. The line layout already knows which line it placed the
 element on, we just needed to ask.

2. For out-of-flow replaced elements (float / position:absolute), no line box
 exists. Use the renderer pointer in the lineID's containing-block slot so the
 resulting (renderer*, 0) lineID is unique to that element and can never
 collide with an in-flow text run's lineID. Apply the same hardening to the
 RenderLineBreak no-box fallback for symmetry.

3. AXTextRuns(): change the constructor parameter to void*. The field has
 always been void*, the constructor was the only inconsistency. Removes the
 need for a reinterpret_cast at the new call sites that pass a non-RenderBlock
 pointer for the unique-per-element lineID case.

4. AXTextMarker::lineIndex(): add a non-progress guard so this class of bug
 degrades to "wrong number" instead of hanging the AX thread.

* LayoutTests/accessibility-isolated-tree/TestExpectations:
* LayoutTests/accessibility/mac/replaced-element-line-index-hang-expected.txt: 
Added.
* LayoutTests/accessibility/mac/replaced-element-line-index-hang.html: Added.
* Source/WebCore/accessibility/AXTextMarker.cpp:
(WebCore::AXTextMarker::lineIndex const):
* Source/WebCore/accessibility/AXTextRun.h:
(WebCore::AXTextRuns::AXTextRuns):
* Source/WebCore/accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::textRuns):

Canonical link: https://commits.webkit.org/312968@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to