Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

gh-140006: Harden fish prompt against shadowed builtins#150936

Open
gaborbernat wants to merge 1 commit into
python:mainpython/cpython:mainfrom
gaborbernat:gh-140006-fish-activate-shadowed-builtinsgaborbernat/cpython:gh-140006-fish-activate-shadowed-builtinsCopy head branch name to clipboard
Open

gh-140006: Harden fish prompt against shadowed builtins#150936
gaborbernat wants to merge 1 commit into
python:mainpython/cpython:mainfrom
gaborbernat:gh-140006-fish-activate-shadowed-builtinsgaborbernat/cpython:gh-140006-fish-activate-shadowed-builtinsCopy head branch name to clipboard

Conversation

@gaborbernat

@gaborbernat gaborbernat commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

The activate.fish prompt override restores the previous command's exit status with echo "exit $old_status" | .. fish resolves a function ahead of a builtin, so a user function . (or function source) shadows the source builtin even inside a pipe. The override then pipes exit $old_status into that function instead of sourcing. A dot-style directory navigator that lists the directory turns this into a directory listing on every prompt, and the exit status handed to the original prompt is lost.

This routes every builtin the prompt path uses through builtin: source, echo, printf, set_color, and the functions calls in deactivate and activation. builtin forces builtin resolution, so no user function can intercept them.

Compatibility

Every command goes through a builtin present with a stable interface since fish 2.0.0 (May 2013):

The script already required fish 2.0.0 through functions --copy, so the minimum supported fish version does not change. No version check is added.

Testing

test_venv.BasicTest.test_fish_activate_shadowed_builtins creates a venv, shadows ./source/echo/printf/set_color with functions, renders the prompt, and asserts the exit status is restored and no shadowed function ran. It fails against the current script and passes with this change. Verified on fish 4.1.2 (the reported version) and 4.7.1.

A user function that shadows the `.`/`source` builtin hijacks the
activate.fish prompt. fish resolves functions ahead of builtins, so the
`echo "exit $status" | .` line that restores the exit status pipes into
the user function instead of sourcing. Dot-style directory navigators
redefine `.`, which made the prompt list the directory on every command
and dropped the exit status handed to the original prompt.

Route every builtin the prompt path uses (`source`, `echo`, `printf`,
`set_color`, `functions`) through `builtin` so no user function can
intercept them. These have all been fish builtins with a stable
interface since fish 2.0.0, the version the script already required
through `functions --copy`, so the minimum supported fish version does
not change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.