From d2fca5f0ec4366ca62c8c9b4e5b0bdb4057f1d24 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sat, 14 Mar 2026 10:16:25 -0700 Subject: [PATCH] [Fix] `nvm_resolve_local_alias`: avoid using variable as printf format string Using a variable as the format string means `%` characters in alias names would be interpreted as format specifiers. Use `%b` format with the variable as an argument to safely interpret `\n` escapes. Bug introduced in https://github.com/nvm-sh/nvm/commit/9b91734f0b6a210f0c6655b0cd25ea288d9ae376. --- nvm.sh | 2 +- .../percent in alias name/nvm_resolve_alias | 17 +++++++++++++++++ .../nvm_resolve_local_alias | 17 +++++++++++++++++ test/fast/Aliases/percent in alias name/setup | 4 ++++ .../fast/Aliases/percent in alias name/teardown | 4 ++++ 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100755 test/fast/Aliases/percent in alias name/nvm_resolve_alias create mode 100755 test/fast/Aliases/percent in alias name/nvm_resolve_local_alias create mode 100755 test/fast/Aliases/percent in alias name/setup create mode 100755 test/fast/Aliases/percent in alias name/teardown diff --git a/nvm.sh b/nvm.sh index 390ee0d..a50601a 100755 --- a/nvm.sh +++ b/nvm.sh @@ -1368,7 +1368,7 @@ nvm_resolve_alias() { break fi - if command printf "${SEEN_ALIASES}" | nvm_grep -q -e "^${ALIAS_TEMP}$"; then + if command printf '%b' "${SEEN_ALIASES}" | nvm_grep -q -e "^${ALIAS_TEMP}$"; then ALIAS="∞" break fi diff --git a/test/fast/Aliases/percent in alias name/nvm_resolve_alias b/test/fast/Aliases/percent in alias name/nvm_resolve_alias new file mode 100755 index 0000000..4d44af6 --- /dev/null +++ b/test/fast/Aliases/percent in alias name/nvm_resolve_alias @@ -0,0 +1,17 @@ +#!/bin/sh +\. ../../../common.sh + +die () { echo "$@" ; exit 1; } + +: nvm.sh +\. ../../../../nvm.sh + +# An alias whose name contains % should resolve directly +try nvm_resolve_alias 'test-%s-alias' +[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_alias test-%s-alias failed with exit code $CAPTURED_EXIT_CODE" +[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_alias test-%s-alias was not v0.0.1; got $CAPTURED_STDOUT" + +# An alias chain that passes through a %-containing alias name should resolve +try nvm_resolve_alias test-pct-chain +[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_alias test-pct-chain failed with exit code $CAPTURED_EXIT_CODE" +[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_alias test-pct-chain was not v0.0.1; got $CAPTURED_STDOUT" diff --git a/test/fast/Aliases/percent in alias name/nvm_resolve_local_alias b/test/fast/Aliases/percent in alias name/nvm_resolve_local_alias new file mode 100755 index 0000000..37f0e97 --- /dev/null +++ b/test/fast/Aliases/percent in alias name/nvm_resolve_local_alias @@ -0,0 +1,17 @@ +#!/bin/sh +\. ../../../common.sh + +die () { echo "$@" ; exit 1; } + +: nvm.sh +\. ../../../../nvm.sh + +# An alias whose name contains % should resolve directly +try nvm_resolve_local_alias 'test-%s-alias' +[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_local_alias test-%s-alias failed with exit code $CAPTURED_EXIT_CODE" +[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_local_alias test-%s-alias was not v0.0.1; got $CAPTURED_STDOUT" + +# An alias chain that passes through a %-containing alias name should resolve +try nvm_resolve_local_alias test-pct-chain +[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_local_alias test-pct-chain failed with exit code $CAPTURED_EXIT_CODE" +[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_local_alias test-pct-chain was not v0.0.1; got $CAPTURED_STDOUT" diff --git a/test/fast/Aliases/percent in alias name/setup b/test/fast/Aliases/percent in alias name/setup new file mode 100755 index 0000000..a926bb1 --- /dev/null +++ b/test/fast/Aliases/percent in alias name/setup @@ -0,0 +1,4 @@ +#!/bin/sh + +echo v0.0.1 > ../../../../alias/test-%s-alias +echo test-%s-alias > ../../../../alias/test-pct-chain diff --git a/test/fast/Aliases/percent in alias name/teardown b/test/fast/Aliases/percent in alias name/teardown new file mode 100755 index 0000000..49dee71 --- /dev/null +++ b/test/fast/Aliases/percent in alias name/teardown @@ -0,0 +1,4 @@ +#!/bin/sh + +rm -f ../../../../alias/test-%s-alias +rm -f ../../../../alias/test-pct-chain