Repository navigation
馃悰 fix(activation): escape the bash prompt for both PS1 passes - #3390
Merged
Merged
Conversation
bash decodes its backslash prompt escapes in PS1 before it expands the result, turning \\ into \ and \$ into $ (or # for root). The activate script escaped the environment name for the expansion pass only, so a backslash in the name undid the escaping, and a name such as a\$(touch PWNED) ran the command each time the prompt was drawn. Escape the name a second time under bash so both passes leave it literal. zsh does no decode pass, so it keeps the single escaping.
gaborbernat
added a commit
that referenced
this pull request
Oct 12, 2026
#3390 escapes the bash prompt twice, once for bash's prompt-escape decode and once for its expansion. `test_bash` renders the prompt with `${PS1@P}` on bash 4.4+, but macOS ships bash 3.2, where it falls back to a `sed` that strips one layer of escapes. 馃И The rendered prompt then kept `\$` and `` \` `` and `test_bash` failed on every macOS job, as on [#3391](https://github.com/pypa/virtualenv/actions/runs/38189937681/job/114620308443). The fallback now runs the same `sed` expression twice. On bash 5.3 its output matches `${PS1@P}` for the tester's environment name and the names from the #3390 regression cases.
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.
bash handles
PS1in two passes each time it draws the prompt: it first decodes backslash prompt escapes, turning\\into\and\$into$(or#for root), and then expands the result. The bashactivatescript escaped the environment name for the expansion pass only (#3326), so a backslash in the name undoes that escaping. 馃攼 A name such asa\$(touch PWNED), from the directory,--promptorVIRTUALENV_PROMPT, runs the command each time bash draws the prompt. For root,\$decodes to#, so the same name renders wrong but runs nothing.Under bash,
activatenow escapes backslashes, dollar signs and backticks a second time, so both passes leave the name literal. zsh does no decode pass, so it keeps the single escaping added in 5b91536. The prompt tests gain cases for a backslash before$(...)and before backticks, and for names with a backslash before$, before a backtick, doubled, and trailing; they render through bash 5.2 and zsh 5.9 and pass as root and as an unprivileged user.Every release up to 21.14.6 is affected, and earlier releases before 21.13.0 do not escape the name at all.