From dd61ae4bc8e975fd782532a2490ed748faf60958 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 9 Jul 2026 15:43:56 -0700 Subject: [PATCH] [Robustness] `nvm_alias`: explicitly succeed when the alias file is unreadable The sed/awk pipeline exits with awk's status, so an existing-but-unreadable alias file produces empty output with status 0 - but only by accident, alongside sed's read error on stderr. Make that contract explicit: a nonzero status here would flip `nvm_ensure_default_set` from "default is already set" to recreating it, silently overwriting a write-only default alias. --- nvm.sh | 8 ++++ .../nvm_alias handles unreadable alias file | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100755 test/fast/Aliases/nvm_alias handles unreadable alias file diff --git a/nvm.sh b/nvm.sh index eca80dba..ff35373e 100755 --- a/nvm.sh +++ b/nvm.sh @@ -1362,6 +1362,14 @@ nvm_alias() { return 2 fi + if [ ! -r "${NVM_ALIAS_PATH}" ]; then + # an existing-but-unreadable alias file yields empty output with a success + # status - a nonzero status here would make `nvm_ensure_default_set` + # overwrite an existing default alias it merely could not read + nvm_err "Alias file is not readable: ${NVM_ALIAS_PATH}" + return 0 + fi + command sed 's/#.*//; s/[[:space:]]*$//' "${NVM_ALIAS_PATH}" | command awk 'NF' } diff --git a/test/fast/Aliases/nvm_alias handles unreadable alias file b/test/fast/Aliases/nvm_alias handles unreadable alias file new file mode 100755 index 00000000..77196c86 --- /dev/null +++ b/test/fast/Aliases/nvm_alias handles unreadable alias file @@ -0,0 +1,38 @@ +#!/bin/sh + +die () { echo "$@" ; cleanup ; exit 1; } + +cleanup() { + chmod 644 ../../../alias/test-edge-unreadable 2>/dev/null + rm -f ../../../alias/test-edge-unreadable +} + +export NVM_DIR="$(cd ../../.. && pwd)" + +: nvm.sh +\. "${NVM_DIR}/nvm.sh" + +# Create an alias file that exists but can not be read +echo 'v0.0.1' > ../../../alias/test-edge-unreadable +chmod 000 ../../../alias/test-edge-unreadable + +# root (and some containers) can read mode-000 files; nothing to assert there +if [ -r ../../../alias/test-edge-unreadable ]; then + cleanup + exit 0 +fi + +# like the sed/awk pipeline this replaced: empty output, success status, so +# that `nvm_ensure_default_set` does not overwrite an unreadable default alias +OUTPUT="$(nvm_alias test-edge-unreadable 2>/dev/null)" +EXIT_CODE=$? +[ "${EXIT_CODE}" = '0' ] || die "expected exit code 0 for unreadable alias file, got ${EXIT_CODE}" +[ -z "${OUTPUT}" ] || die "expected empty output for unreadable alias file, got >${OUTPUT}<" + +STDERR="$(nvm_alias test-edge-unreadable 2>&1 >/dev/null)" +case "${STDERR}" in + *'not readable'*) ;; + *) die "expected a not-readable warning on stderr, got >${STDERR}<" ;; +esac + +cleanup