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