Skip to content

gh-161062: Fix crash on concurrent first read of Element.text or tail - #161063

Draft
gpshead wants to merge 1 commit into
python:mainfrom
gpshead:ft-elementtree-text-join-race
Draft

gpshead wants to merge 1 commit into
python:mainfrom
gpshead:ft-elementtree-text-join-race

Conversation

@gpshead

@gpshead gpshead commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

On the free-threaded build, two threads doing the first read of Element.text or Element.tail on an element produced by the parser could both join the pending chunk list and both release the element's only reference to it, crashing on a freed list. Any text containing an entity such as &, or the whitespace tail of an indented document, is stored that way, so concurrent ET.tostring() or plain attribute reads of a freshly parsed tree are enough to hit it.

element_get_text() and element_get_tail() now share a helper that does the lazy join in the element's critical section. PyUnicode_Join() locks the list, which can suspend the outer critical section, so the helper holds its own reference to the list across the join and re-checks the slot before storing the result; if another thread got there first its string is returned. This is a no-op on the default build.

This is one small piece of gh-146022 and deliberately nothing more: writers (the text/tail setters, __setstate__, the tree builder, the child-list methods) remain unsynchronized and are out of scope here, as are the raw slot reads in __copy__, __deepcopy__ and __getstate__. gh-149816 item (87) "Unsynchronized Element.text borrowed-pointer race" is primarily about a getter racing the setter, which this does not address; its write-up also mentions the getter-vs-getter join race, which is the part fixed here.

Fixes #161062

ANT-2026-V596YS0U

…r tail

On the free-threaded build, join the tree builder's pending text chunks
in the element's critical section so that two readers cannot both join
and release the same list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash on concurrent first read of Element.text or Element.tail on the free-threaded build

1 participant