revert: "add life support to handles cast to string_view (#6092)" - #6097
Merged
Conversation
rwgk
approved these changes
Jun 29, 2026
henryiii
added a commit
to henryiii/pybind11
that referenced
this pull request
Jun 29, 2026
…ind#6092)" This re-applies pybind#6092 (reverting pybind#6097) so the follow-up fixes in this PR can build on it. Assisted-by: ClaudeCode:claude-opus-4.8
rwgk
added a commit
that referenced
this pull request
Jul 29, 2026
* revert: "revert: add life support to handles cast to string_view (#6092)" This re-applies #6092 (reverting #6097) so the follow-up fixes in this PR can build on it. Assisted-by: ClaudeCode:claude-opus-4.8 * fix: don't throw from string_view life support outside a bound function PR #6092 added loader_life_support::add_patient(src) to keep the source object alive when loading a string view, fixing a real use-after-free when a container of views is built from a non-sequence iterable (e.g. a generator): list_caster materializes a temporary tuple that owns the strings and destroys it when load() returns, before the bound function body runs. add_patient throws when there is no life support frame, so casting to a view outside a bound function (e.g. a manual py::cast<std::string_view>) now raises instead of relying on the caller-owned source, a regression from #6092. For these view-into-src cases registration is best effort: inside a bound function it keeps src alive (fixing the UAF), and outside one the caller owns src's lifetime as before. Add try_add_patient(), which returns false instead of throwing when there is no frame, and use it at the three view load sites. add_patient() keeps its strict contract for value-creating conversions. Assisted-by: ClaudeCode:claude-opus-4.8 * fix: only add string_view life support for transient sources Refine the previous commit. Best-effort registration (try_add_patient) silently produces a dangling view when a container of views is built from a generator outside a bound function: there the materialized temporary is released before the view is used, and with no frame nothing keeps it alive. Such a cast cannot be made safe, so it should fail loudly, while a view into a durable, caller-owned object needs no life support at all. The view caster cannot tell a durable source from a pybind11-managed transient one; that provenance lives in the container caster. Introduce an ambient transient_source_guard that the list, set, map, and array casters set around their generator/materialized paths, and have the string caster keep the source alive only when loading from a transient source (via the throwing add_patient, so try_add_patient is no longer needed). This means: - views into durable sources (direct arguments, sequences, manual casts) add no life support and no longer throw outside a bound function, and - a generator used outside a frame throws, rather than silently dangling. The guard restores (rather than clears) the previous value, so a durable container nested in a transient one is correctly treated as transient. Verified with AddressSanitizer: the in-frame generator case is clean, the out-of-frame durable cases succeed, and the out-of-frame generator case throws. Assisted-by: ClaudeCode:claude-opus-4.8 * Revert "fix: only add string_view life support for transient sources" This reverts commit e18b834. * test: cover string_view argument life support * test: cover generated and nested string_view lifetimes * test: cover temporary-backed string_view casts * test: explain string_view lifetime regression tests * docs: clarify string_view lifetime requirements * docs: explain life support for custom view casters --------- Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
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.
🤖 AI text below 🤖
Reverts #6092.
#6092 ("add life support to handles cast to string_view") introduced regressions that are being addressed in #6096. Reverting it here so
masteris clean while the proper fix is worked out.This is a clean revert of 59d7cb2 — it removes the
loader_life_support::add_patient(src)calls added tostring_casterand the accompanyingfunc_with_string_viewstest.Suggested changelog entry
Reverted #6092 (string_view life support), which introduced regressions.