1
0
mirror of https://github.com/nvm-sh/nvm.git synced 2026-10-24 07:13:42 +08:00

[Fix] nvm_cd: bypass a user-defined cd function

`\cd` only bypasses aliases, so a user-defined `cd` function (eg, cdhist's) still ran,
and broke `NVM_DIR` auto-detection when it rejected zsh's `-q`.

Use `command cd`, which skips functions in POSIX shells.
zsh's `command` runs `/usr/bin/cd` instead of the builtin,
so use `builtin cd` there, as `nvm_echo` does for `printf`.
`nvm_die_on_prefix` also now uses `nvm_cd` instead of a bare `cd`.

Fixes #3835. See #3836.

Co-authored-by: Elan Ruusamäe <glen@delfi.ee>
This commit is contained in:
Jordan Harband
2026-10-09 21:16:17 -07:00
parent 6dc3765f6b
commit b1b3a0038c
2 changed files with 31 additions and 2 deletions

10
nvm.sh
View File

@@ -41,7 +41,13 @@ nvm_echo_with_colors() {
}
nvm_cd() {
\cd "$@"
# `\cd` still runs a user-defined `cd` function; in zsh, `command cd` runs `/usr/bin/cd` instead of the builtin
if [ -n "${ZSH_VERSION-}" ]; then
# shellcheck disable=SC3044
builtin cd "$@"
else
command cd "$@"
fi
}
# a caller that closed stderr, rather than redirecting it to /dev/null, makes
@@ -3516,7 +3522,7 @@ nvm_die_on_prefix() {
local NVM_CONFIG_VALUE
eval "NVM_CONFIG_VALUE=\"\$${NVM_NPM_CONFIG_x_PREFIX_ENV}\""
if [ -n "${NVM_CONFIG_VALUE-}" ] && [ "_${NVM_OS}" = "_win" ]; then
NVM_CONFIG_VALUE="$(cd "$NVM_CONFIG_VALUE" 2>/dev/null && pwd)"
NVM_CONFIG_VALUE="$(nvm_cd "$NVM_CONFIG_VALUE" 2>/dev/null && pwd)"
fi
if [ -n "${NVM_CONFIG_VALUE-}" ] && ! nvm_tree_contains_path "${NVM_DIR}" "${NVM_CONFIG_VALUE}"; then
nvm deactivate >/dev/null 2>&1

23
test/fast/Unit tests/nvm_cd Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/sh
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../nvm.sh
EXPECTED="$(\cd .. && pwd)"
# a user-defined `cd` function that rejects nvm's arguments, like cdhist's (#3835)
cd() {
echo 'user-defined cd function was called' >&2
return 1
}
OUTPUT="$(nvm_cd .. 2>&1 && pwd)"
[ "${OUTPUT}" = "${EXPECTED}" ] || die "expected '${EXPECTED}', got '${OUTPUT}'"
# shellcheck disable=SC2086
OUTPUT="$(nvm_cd ${NVM_CD_FLAGS} .. 2>&1 && pwd)"
[ "${OUTPUT}" = "${EXPECTED}" ] || die "with NVM_CD_FLAGS '${NVM_CD_FLAGS}', expected '${EXPECTED}', got '${OUTPUT}'"
unset -f cd