Skip to content

Commit

Permalink
AX: Crash in [WebAccessibilityObjectWrapper textMarkerRangeAtTextMark…
Browse files Browse the repository at this point in the history
…er:forUnit:].

https://bugs.webkit.org/show_bug.cgi?id=260187
rdar://110921099

Reviewed by Tyler Wilcock.

The crash was happening because the Node pointed to by the TextMarker is destroyed in a main loop cycle before it is used as the result of a request coming on the AX thread that is dispatched back to the main thread. This patch fixes the problem by checking whether the pointer is still in the AXObjectCache data structure that keeps track of the Nodes still alive and in use by TextMarkers.

* Source/WebCore/accessibility/AXTextMarker.cpp:
(WebCore::AXTextMarker::operator CharacterOffset const):

Canonical link: https://commits.webkit.org/266909@main
  • Loading branch information
AndresGonzalezApple committed Aug 15, 2023
1 parent f452a97 commit 435522c
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions Source/WebCore/accessibility/AXTextMarker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,22 @@ AXTextMarker::operator CharacterOffset() const
if (isIgnored() || isNull())
return { };

setNodeIfNeeded();
WeakPtr cache = AXTreeStore<AXObjectCache>::axObjectCacheForID(m_data.axTreeID());
if (!cache)
return { };

if (m_data.node) {
// Make sure that this node is still in cache->m_textMarkerNodes. Since this method can be called as a result of a dispatch from the AX thread, the Node may have gone away in a previous main loop cycle.
if (!cache->isNodeInUse(m_data.node))
return { };
} else
setNodeIfNeeded();

CharacterOffset result(m_data.node, m_data.characterStart, m_data.characterOffset);
// When we are at a line wrap and the VisiblePosition is upstream, it means the text marker is at the end of the previous line.
// We use the previous CharacterOffset so that it will match the Range.
if (m_data.affinity == Affinity::Upstream) {
if (WeakPtr cache = AXTreeStore<AXObjectCache>::axObjectCacheForID(m_data.axTreeID()))
return cache->previousCharacterOffset(result, false);
}
if (m_data.affinity == Affinity::Upstream)
return cache->previousCharacterOffset(result, false);
return result;
}

Expand Down

0 comments on commit 435522c

Please sign in to comment.