[Fix] nvm_process_nvmrc: don't show the content of a symlinked .nvmrc
`.nvmrc` is found and read through symlinks, so a repository that commits `.nvmrc` as a symlink to a path outside itself (eg, `../../.npmrc`) made a plain `nvm use`, `nvm install`, or `nvm which` (or `nvm-exec`, or the README's auto-switching shell hook) print that file: the invalid `.nvmrc` message shows everything that was parsed, even with `--silent`, and a one-line file was taken as the version, which is printed in the "Found" message and in later errors. A symlinked `.nvmrc` is still followed, so linking to another version file (eg, `.node-version`, or a parent directory's `.nvmrc`) keeps working, but its content is never shown, and it is valid only if it names a version or an existing alias, via a new `nvm_is_version_or_alias` helper.
This commit is contained in:
2 files changed
+105
-2
No files matched your search
@@ -942,11 +942,43 @@ EOF
|
||||
nvm_echo "${unpaired_line}"
|
||||
}
|
||||
|
||||
nvm_is_version_or_alias() {
|
||||
case "${1-}" in
|
||||
system | 'lts/*') return 0 ;;
|
||||
lts/-*)
|
||||
case "${1#lts/-}" in
|
||||
'' | *[!0-9]*) return 1 ;;
|
||||
esac
|
||||
return 0
|
||||
;;
|
||||
lts/*)
|
||||
case "${1#lts/}" in
|
||||
'' | *[!a-z]*) return 1 ;;
|
||||
esac
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
nvm_is_valid_version "${1-}" || nvm_alias "${1-}" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
nvm_process_nvmrc() {
|
||||
local NVMRC_PATH
|
||||
NVMRC_PATH="$1"
|
||||
|
||||
nvm_process_nvmrc_content "$(command cat "${NVMRC_PATH}")"
|
||||
if [ ! -L "${NVMRC_PATH}" ]; then
|
||||
nvm_process_nvmrc_content "$(command cat "${NVMRC_PATH}")"
|
||||
return
|
||||
fi
|
||||
|
||||
# a symlink can point at any file, so never print its content,
|
||||
# and only accept a version or an existing alias, which would be printed later
|
||||
local NVMRC_VERSION
|
||||
if ! NVMRC_VERSION="$(nvm_process_nvmrc_content "$(command cat "${NVMRC_PATH}")" 2>/dev/null)" \
|
||||
|| ! nvm_is_version_or_alias "${NVMRC_VERSION}"; then
|
||||
nvm_err "invalid .nvmrc! '${NVMRC_PATH}' is a symbolic link, so it must contain a version or an alias name; its content is not shown."
|
||||
return 1
|
||||
fi
|
||||
nvm_echo "${NVMRC_VERSION}"
|
||||
}
|
||||
|
||||
nvm_rc_version() {
|
||||
@@ -6533,7 +6565,7 @@ nvm() {
|
||||
nvm_print_color_legend \
|
||||
nvm_echo_with_colors nvm_err_with_colors \
|
||||
nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \
|
||||
nvm_process_nvmrc nvm_process_nvmrc_content nvm_nvmrc_invalid_msg \
|
||||
nvm_process_nvmrc nvm_process_nvmrc_content nvm_nvmrc_invalid_msg nvm_is_version_or_alias \
|
||||
nvm_write_nvmrc nvm_hash_reset \
|
||||
>/dev/null 2>&1
|
||||
unset NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#!/bin/sh
|
||||
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
|
||||
cleanup() {
|
||||
rm -rf "${TEST_DIR-}"
|
||||
nvm unalias nvmrc_symlink_alias > /dev/null 2>&1
|
||||
unset TEST_DIR
|
||||
}
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
\. ../../common.sh
|
||||
|
||||
TEST_DIR="${PWD}/nvm_process_nvmrc_symlink_tmp"
|
||||
mkdir -p "${TEST_DIR}/home" "${TEST_DIR}/project/packages/a" || die 'failed to create test dirs'
|
||||
printf '//registry.npmjs.org/:_authToken=SECRET\n' > "${TEST_DIR}/home/.npmrc"
|
||||
printf 'https://user:SECRET@github.com\n' > "${TEST_DIR}/home/.git-credentials"
|
||||
|
||||
NVMRC="${TEST_DIR}/project/.nvmrc"
|
||||
|
||||
for TARGET in .npmrc .git-credentials; do
|
||||
rm -f "${NVMRC}"
|
||||
ln -s "../home/${TARGET}" "${NVMRC}" || die 'failed to create the symlink'
|
||||
|
||||
try_err nvm_process_nvmrc "${NVMRC}"
|
||||
[ "${CAPTURED_EXIT_CODE}" != 0 ] || die "expected a symlink to ${TARGET} to be invalid; got exit code ${CAPTURED_EXIT_CODE}"
|
||||
case "${CAPTURED_STDERR}" in
|
||||
*SECRET*) die "expected a symlink to ${TARGET} to not show its content; got \`${CAPTURED_STDERR}\`" ;;
|
||||
esac
|
||||
[ "${CAPTURED_STDERR}" = "invalid .nvmrc! '${NVMRC}' is a symbolic link, so it must contain a version or an alias name; its content is not shown." ] || die "expected the symlink error for ${TARGET}; got \`${CAPTURED_STDERR}\`"
|
||||
|
||||
try nvm_process_nvmrc "${NVMRC}"
|
||||
[ -z "${CAPTURED_STDOUT}" ] || die "expected no version from a symlink to ${TARGET}; got \`${CAPTURED_STDOUT}\`"
|
||||
done
|
||||
|
||||
nvm alias nvmrc_symlink_alias v0.0.1 > /dev/null 2>&1 || die 'failed to create an alias'
|
||||
|
||||
# a deliberate symlink to another version file, in or above the project, still works
|
||||
for VERSION in v20.1.0 20 'v20.0.0-rc.1' node system 'lts/*' lts/iron lts/-1 nvmrc_symlink_alias; do
|
||||
rm -f "${NVMRC}" "${TEST_DIR}/project/packages/a/.nvmrc"
|
||||
printf '%s # comment\n' "${VERSION}" > "${NVMRC}"
|
||||
ln -s ../../.nvmrc "${TEST_DIR}/project/packages/a/.nvmrc" || die 'failed to create the symlink'
|
||||
|
||||
try nvm_process_nvmrc "${TEST_DIR}/project/packages/a/.nvmrc"
|
||||
[ "${CAPTURED_EXIT_CODE}" = 0 ] || die "expected a symlink to an .nvmrc with \`${VERSION}\` to be valid; got exit code ${CAPTURED_EXIT_CODE}"
|
||||
[ "${CAPTURED_STDOUT}" = "${VERSION}" ] || die "expected \`${VERSION}\` from a symlinked .nvmrc; got \`${CAPTURED_STDOUT}\`"
|
||||
done
|
||||
|
||||
for VERSION in not_an_alias lts/Iron 'lts/' 'lts/-x'; do
|
||||
rm -f "${TEST_DIR}/project/.node-version"
|
||||
printf '%s\n' "${VERSION}" > "${TEST_DIR}/project/.node-version"
|
||||
rm -f "${NVMRC}"
|
||||
ln -s .node-version "${NVMRC}" || die 'failed to create the symlink'
|
||||
|
||||
try_err nvm_process_nvmrc "${NVMRC}"
|
||||
[ "${CAPTURED_EXIT_CODE}" != 0 ] || die "expected a symlink to a file with \`${VERSION}\` to be invalid; got exit code ${CAPTURED_EXIT_CODE}"
|
||||
case "${CAPTURED_STDERR}" in
|
||||
*"${VERSION}"*) die "expected a symlink to a file with \`${VERSION}\` to not show its content; got \`${CAPTURED_STDERR}\`" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# a regular file still shows what was parsed
|
||||
rm -f "${NVMRC}"
|
||||
printf 'foo=bar\n' > "${NVMRC}"
|
||||
try_err nvm_process_nvmrc "${NVMRC}"
|
||||
[ "${CAPTURED_EXIT_CODE}" != 0 ] || die "expected an .nvmrc without a version to be invalid; got exit code ${CAPTURED_EXIT_CODE}"
|
||||
nvm_echo "${CAPTURED_STDERR}" | strip_colors | nvm_grep -q '^foo=bar$' || die "expected a regular .nvmrc's parsed content to be shown; got \`${CAPTURED_STDERR}\`"
|
||||
|
||||
cleanup
|
||||
Reference in new issue
Block a user