Repository navigation
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On the free-threaded build, two threads doing the first read of
Element.textorElement.tailon 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 concurrentET.tostring()or plain attribute reads of a freshly parsed tree are enough to hit it.element_get_text()andelement_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/tailsetters,__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