`nvm use --delete-prefix`, which nvm itself recommends when it finds a `prefix` or `globalconfig` setting, ran `npm config delete` from the current directory. For a project `.npmrc`, it ran a bare `npm config delete prefix`/`globalconfig`, so npm loaded that untrusted file first, and its `userconfig`, `globalconfig`, or `location=global` keys picked which file npm rewrote, deleted, or chmodded to 0666 - eg, `~/.bashrc` or `~/.aws/credentials`. The builtin and user branches pinned `--userconfig`, but still loaded the project file, so a project `location=global` plus an indented ` globalconfig=` (which nvm's check does not match) redirected those writes the same way. `npm config delete` never edits the project file anyway, so that branch could not do what it claimed. For the project npmrc, no longer run npm at all: with `--delete-prefix`, warn that project npmrc files are not modified and must be edited by hand, and continue, as before. For the builtin, global, and user npmrc files, pass `--prefix` set to the version directory, so npm does not walk up from the current directory to load the project npmrc, and its global config resolves to that version's `etc/npmrc`. Discovered by Anthropic's OSS Scanner, as vulnerability ANT-2026-WYRTKBQ5.
310 lines
16 KiB
Bash
Executable File
310 lines
16 KiB
Bash
Executable File
#!/bin/sh
|
||
|
||
TEST_PWD=$(pwd)
|
||
TEST_DIR="$TEST_PWD/nvm_die_on_prefix_tmp"
|
||
|
||
: nvm.sh
|
||
\. ../../../nvm.sh
|
||
|
||
\. ../../common.sh
|
||
|
||
TEST_VERSION_DIR="${TEST_DIR}/version"
|
||
|
||
cleanup () {
|
||
rm -rf "$TEST_DIR"
|
||
alias nvm_has='\nvm_has'
|
||
alias npm='\npm'
|
||
unset -f nvm_has npm node
|
||
}
|
||
|
||
die () {
|
||
echo "$@";
|
||
cleanup;
|
||
exit 1;
|
||
}
|
||
|
||
[ ! -e "$TEST_DIR" ] && mkdir "$TEST_DIR"
|
||
|
||
try_err nvm_die_on_prefix
|
||
EXPECTED_OUTPUT="First argument \"delete the prefix\" must be zero or one"
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix' did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_1" ] || die "'nvm_die_on_prefix' did not exit with 1; got "$CAPTURED_EXIT_CODE""
|
||
|
||
try_err nvm_die_on_prefix 2
|
||
EXPECTED_OUTPUT="First argument \"delete the prefix\" must be zero or one"
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 2' did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_1" ] || die "'nvm_die_on_prefix' did not exit with 1; got "$CAPTURED_EXIT_CODE""
|
||
|
||
try_err nvm_die_on_prefix 0
|
||
EXPECTED_OUTPUT='Second argument "nvm command", and third argument "nvm version dir", must both be nonempty'
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0' did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_2" ] || die "'nvm_die_on_prefix 0' did not exit with 2; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
nvm_has() { return 1; } # ie, npm is not installed
|
||
OUTPUT="$(nvm_die_on_prefix 0 version_dir foo 2>&1)"
|
||
[ -z "$OUTPUT" ] || die "nvm_die_on_prefix was not a noop when nvm_has returns 1, got '$OUTPUT'"
|
||
|
||
nvm_has() { return 0; }
|
||
|
||
OUTPUT="$(nvm_die_on_prefix 0 foo "$(nvm_version_dir new)" 2>&1)"
|
||
[ -z "$OUTPUT" ] || die "'nvm_die_on_prefix' was not a noop when prefix is good; got '$OUTPUT'"
|
||
|
||
# `nvm_get_os` runs `uname`; it is only needed when an `NPM_CONFIG_PREFIX`
|
||
# variable is set, so with none set it must not run at all
|
||
MOCK_BIN="${TEST_DIR}/bin"
|
||
mkdir -p "${MOCK_BIN}"
|
||
{
|
||
echo '#!/bin/sh'
|
||
echo 'echo "uname was called" >&2'
|
||
echo 'exit 1'
|
||
} > "${MOCK_BIN}/uname"
|
||
chmod +x "${MOCK_BIN}/uname"
|
||
unset NPM_CONFIG_PREFIX npm_config_prefix npm_CONFIG_PREFIX
|
||
OUTPUT="$(PATH="${MOCK_BIN}:${PATH}" nvm_die_on_prefix 0 foo "$(nvm_version_dir new)" 2>&1)"
|
||
[ -z "$OUTPUT" ] || die "'nvm_die_on_prefix' detected the OS (ran uname) when no NPM_CONFIG_PREFIX was set; got '$OUTPUT'"
|
||
|
||
mkdir -p "$(nvm_version_dir new)"
|
||
ln -s "$(nvm_version_dir new)" "$TEST_DIR/node"
|
||
|
||
npm() {
|
||
local args
|
||
args="$@"
|
||
if [ "_$args" = "_config --loglevel=warn get prefix" ]; then
|
||
echo "$TEST_DIR/node"
|
||
fi
|
||
}
|
||
|
||
node() {
|
||
if [ "_$1" = "_-v" ]; then
|
||
echo "v0.0.0"
|
||
fi
|
||
}
|
||
|
||
OUTPUT="$(nvm_die_on_prefix 0 foo "$(nvm_version_dir new)" 2>&1)"
|
||
[ -z "$OUTPUT" ] || die "'nvm_die_on_prefix' was not a noop when directory is equivalent; got '$OUTPUT'"
|
||
|
||
PREFIX=bar try_err nvm_die_on_prefix 0 foo "$(nvm_version_dir new)"
|
||
unset PREFIX
|
||
EXPECTED_OUTPUT='nvm is not compatible with the "PREFIX" environment variable: currently set to "bar"
|
||
Run `unset PREFIX` to unset it.'
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'PREFIX=bar nvm_die_on_prefix 0 foo' did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_3" ] || die "'PREFIX=bar nvm_die_on_prefix 0 foo' did not exit with 3; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
NPM_CONFIG_PREFIX=bar try_err nvm_die_on_prefix 0 foo "$(nvm_version_dir new)"
|
||
unset NPM_CONFIG_PREFIX
|
||
EXPECTED_OUTPUT='nvm is not compatible with the "NPM_CONFIG_PREFIX" environment variable: currently set to "bar"
|
||
Run `unset NPM_CONFIG_PREFIX` to unset it.'
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'NPM_CONFIG_PREFIX=bar nvm_die_on_prefix 0 foo' did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_4" ] || die "'NPM_CONFIG_PREFIX=bar nvm_die_on_prefix 0 foo' did not exit with 4; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
# on Windows, a prefix that does not exist can not be resolved, but it is still not inside `$NVM_DIR`
|
||
(
|
||
nvm_get_os() { nvm_echo win; }
|
||
NPM_CONFIG_PREFIX=bar try_err nvm_die_on_prefix 0 foo "$(nvm_version_dir new)"
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "on Windows, 'NPM_CONFIG_PREFIX=bar nvm_die_on_prefix 0 foo' did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_4" ] || die "on Windows, 'NPM_CONFIG_PREFIX=bar nvm_die_on_prefix 0 foo' did not exit with 4; got '$CAPTURED_EXIT_CODE'"
|
||
) || die 'nvm_die_on_prefix must not skip an unresolvable NPM_CONFIG_PREFIX on Windows'
|
||
|
||
npm_CONFIG_PREFIX=bar try_err nvm_die_on_prefix 0 foo "$(nvm_version_dir new)"
|
||
unset npm_CONFIG_PREFIX
|
||
EXPECTED_OUTPUT='nvm is not compatible with the "npm_CONFIG_PREFIX" environment variable: currently set to "bar"
|
||
Run `unset npm_CONFIG_PREFIX` to unset it.'
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'npm_CONFIG_PREFIX=bar nvm_die_on_prefix 0 foo' did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_4" ] || die "'npm_CONFIG_PREFIX=bar nvm_die_on_prefix 0 foo' did not exit with 4; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
OUTPUT="$(export FOO='This contains NPM_CONFIG_PREFIX' ; nvm_die_on_prefix 0 foo "$(nvm_version_dir new)" 2>&1)"
|
||
[ -z "$OUTPUT" ] || die "'nvm_die_on_prefix' was not a noop; got '$OUTPUT'"
|
||
|
||
# npmrc tests
|
||
(
|
||
cd "${TEST_DIR}"
|
||
touch package.json
|
||
|
||
# project: prefix
|
||
echo 'prefix=garbage' > .npmrc
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your project npmrc file ($(nvm_sanitize_path "${TEST_DIR}")/.npmrc)
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with project .npmrc that has prefix did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with project .npmrc that has prefix did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
# project: globalconfig
|
||
echo 'globalconfig=garbage' > .npmrc
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your project npmrc file ($(nvm_sanitize_path "${TEST_DIR}")/.npmrc)
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with project .npmrc that has globalconfig did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with project .npmrc that has globalconfig did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
rm "${TEST_DIR}/.npmrc" || die '.npmrc could not be removed'
|
||
|
||
mkdir -p "${TEST_VERSION_DIR}"
|
||
GLOBAL_NPMRC="${TEST_VERSION_DIR}/etc/npmrc"
|
||
mkdir -p "${TEST_VERSION_DIR}/etc"
|
||
|
||
BUILTIN_NPMRC="${TEST_VERSION_DIR}/lib/node_modules/npm/npmrc"
|
||
mkdir -p "${TEST_VERSION_DIR}/lib/node_modules/npm/"
|
||
|
||
export HOME="${TEST_VERSION_DIR}"
|
||
USER_NPMRC="${TEST_VERSION_DIR}/.npmrc"
|
||
|
||
# global: prefix
|
||
echo 'prefix=garbage' > "${GLOBAL_NPMRC}"
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your global npmrc file ($(nvm_sanitize_path "${GLOBAL_NPMRC}"))
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with global npmrc that has prefix did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with global npmrc that has prefix did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
# global: globalconfig
|
||
echo 'globalconfig=garbage' > "${GLOBAL_NPMRC}"
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your global npmrc file ($(nvm_sanitize_path "${GLOBAL_NPMRC}"))
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with global npmrc that has globalconfig did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with global npmrc that has globalconfig did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
rm "${GLOBAL_NPMRC}" || die "${GLOBAL_NPMRC} could not be removed"
|
||
|
||
# builtin: prefix
|
||
echo 'prefix=garbage' > "${BUILTIN_NPMRC}"
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your builtin npmrc file ($(nvm_sanitize_path "${BUILTIN_NPMRC}"))
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with builtin npmrc that has prefix did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with builtin npmrc that has prefix did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
# builtin: globalconfig
|
||
echo 'globalconfig=garbage' > "${BUILTIN_NPMRC}"
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your builtin npmrc file ($(nvm_sanitize_path "${BUILTIN_NPMRC}"))
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with builtin npmrc that has globalconfig did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with builtin npmrc that has globalconfig did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
rm "${BUILTIN_NPMRC}" || die "${BUILTIN_NPMRC} could not be removed"
|
||
|
||
# user: prefix
|
||
echo 'prefix=garbage' > "${USER_NPMRC}"
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your user’s .npmrc file ($(nvm_sanitize_path "${USER_NPMRC}"))
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with user .npmrc that has prefix did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with user .npmrc that has prefix did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
# user: globalconfig
|
||
echo 'globalconfig=garbage' > "${USER_NPMRC}"
|
||
try_err nvm_die_on_prefix 0 foo "${TEST_VERSION_DIR}"
|
||
EXPECTED_OUTPUT="Your user’s .npmrc file ($(nvm_sanitize_path "${USER_NPMRC}"))
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Run \`foo\` to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 0 foo' with user .npmrc that has globalconfig did not error with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_10" ] || die "'nvm_die_on_prefix 0 foo' with user .npmrc that has globalconfig did not exit with 10; got '$CAPTURED_EXIT_CODE'"
|
||
)
|
||
|
||
# "delete the prefix": npm must not load the (untrusted) project npmrc, which could otherwise choose
|
||
# the file npm rewrites via `userconfig`/`globalconfig`/`location`, and the project npmrc is never edited
|
||
(
|
||
DELETE_DIR="${TEST_DIR}/delete-prefix"
|
||
DELETE_VERSION_DIR="${DELETE_DIR}/version"
|
||
DELETE_PROJECT_DIR="${DELETE_DIR}/project"
|
||
DELETE_HOME="${DELETE_DIR}/home"
|
||
mkdir -p "${DELETE_VERSION_DIR}/etc" "${DELETE_VERSION_DIR}/lib/node_modules/npm" "${DELETE_PROJECT_DIR}" "${DELETE_HOME}"
|
||
export HOME="${DELETE_HOME}"
|
||
echo 'prefix=garbage' > "${DELETE_VERSION_DIR}/lib/node_modules/npm/npmrc"
|
||
echo 'prefix=garbage' > "${DELETE_VERSION_DIR}/etc/npmrc"
|
||
echo 'prefix=garbage' > "${DELETE_HOME}/.npmrc"
|
||
|
||
cd "${DELETE_PROJECT_DIR}" || die 'could not cd to the project dir'
|
||
touch package.json
|
||
PROJECT_NPMRC_CONTENTS="prefix=garbage
|
||
userconfig=${DELETE_HOME}/victim
|
||
location=global
|
||
globalconfig=${DELETE_HOME}/victim"
|
||
echo "${PROJECT_NPMRC_CONTENTS}" > .npmrc
|
||
|
||
NPM_CALLS="${DELETE_DIR}/npm-calls"
|
||
npm() {
|
||
echo "$*" >> "${NPM_CALLS}"
|
||
}
|
||
|
||
try_err nvm_die_on_prefix 1 foo "${DELETE_VERSION_DIR}"
|
||
|
||
EXPECTED_OUTPUT="Your project npmrc file ($(nvm_sanitize_path "${DELETE_PROJECT_DIR}")/.npmrc)
|
||
has a \`globalconfig\` and/or a \`prefix\` setting, which are incompatible with nvm.
|
||
Project npmrc files are not modified by \`--delete-prefix\`; edit that file to unset it."
|
||
[ "_$CAPTURED_STDERR" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 1 foo' with a project .npmrc that has prefix did not warn with '$EXPECTED_OUTPUT'; got '$CAPTURED_STDERR'"
|
||
[ "_$CAPTURED_EXIT_CODE" = "_0" ] || die "'nvm_die_on_prefix 1 foo' with a project .npmrc that has prefix did not exit with 0; got '$CAPTURED_EXIT_CODE'"
|
||
|
||
EXPECTED_OUTPUT="config --loglevel=warn delete prefix --userconfig=${DELETE_VERSION_DIR}/lib/node_modules/npm/npmrc --prefix=${DELETE_VERSION_DIR}
|
||
config --loglevel=warn delete globalconfig --userconfig=${DELETE_VERSION_DIR}/lib/node_modules/npm/npmrc --prefix=${DELETE_VERSION_DIR}
|
||
config --global --loglevel=warn delete prefix --prefix=${DELETE_VERSION_DIR}
|
||
config --global --loglevel=warn delete globalconfig --prefix=${DELETE_VERSION_DIR}
|
||
config --loglevel=warn delete prefix --userconfig=${DELETE_HOME}/.npmrc --prefix=${DELETE_VERSION_DIR}
|
||
config --loglevel=warn delete globalconfig --userconfig=${DELETE_HOME}/.npmrc --prefix=${DELETE_VERSION_DIR}"
|
||
OUTPUT="$(cat "${NPM_CALLS}")"
|
||
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "'nvm_die_on_prefix 1 foo' did not run npm with a pinned \`--prefix\` (and never for the project npmrc): expected '$EXPECTED_OUTPUT'; got '$OUTPUT'"
|
||
|
||
[ "_$(cat .npmrc)" = "_${PROJECT_NPMRC_CONTENTS}" ] || die "'nvm_die_on_prefix 1 foo' edited the project .npmrc; got '$(cat .npmrc)'"
|
||
) || die "'nvm_die_on_prefix 1 foo' let a project .npmrc influence npm"
|
||
|
||
# nvm_npmrc_bad_news_bears matches `^(prefix|globalconfig) *=`
|
||
NPMRC="${TEST_DIR}/bad-news.npmrc"
|
||
printf 'prefix=x\n' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'prefix=x should be bad news'
|
||
printf 'prefix =x\n' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'prefix =x should be bad news'
|
||
printf 'prefix =x\n' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'prefix =x should be bad news'
|
||
printf 'prefix =\n' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'prefix = should be bad news'
|
||
printf 'foo=1\nprefix = y\n' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'a matching line after a non-matching line should be bad news'
|
||
printf 'prefix=x' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'prefix=x without a trailing newline should be bad news'
|
||
printf 'globalconfig=x\n' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'globalconfig=x should be bad news'
|
||
printf 'globalconfig = x\n' > "${NPMRC}"
|
||
nvm_npmrc_bad_news_bears "${NPMRC}" || die 'globalconfig = x should be bad news'
|
||
|
||
printf 'prefixfoo=x\n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'prefixfoo=x should not be bad news'
|
||
printf 'globalconfigfoo=x\n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'globalconfigfoo=x should not be bad news'
|
||
printf 'prefix x=x\n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'prefix x=x should not be bad news'
|
||
printf 'prefix\t=x\n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'a tab before = should not be bad news'
|
||
printf ' prefix=x\n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'a leading space should not be bad news'
|
||
printf 'Prefix=x\n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'an uppercase key should not be bad news'
|
||
printf 'prefix\n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'a bare prefix should not be bad news'
|
||
printf 'prefix \n' > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'trailing spaces without = should not be bad news'
|
||
: > "${NPMRC}"
|
||
! nvm_npmrc_bad_news_bears "${NPMRC}" || die 'an empty npmrc should not be bad news'
|
||
! nvm_npmrc_bad_news_bears || die 'a missing argument should not be bad news'
|
||
! nvm_npmrc_bad_news_bears "${TEST_DIR}/nonexistent.npmrc" || die 'a missing file should not be bad news'
|
||
|
||
# the npmrc scan must not fork `grep`
|
||
(
|
||
rm -f "${TEST_DIR}/grep-was-called"
|
||
nvm_grep() { : > "${TEST_DIR}/grep-was-called"; return 1; }
|
||
printf 'globalconfig = nope\n' > "${TEST_DIR}/probe.npmrc"
|
||
NVM_PROBE_EXIT=0
|
||
nvm_npmrc_bad_news_bears "${TEST_DIR}/probe.npmrc" || NVM_PROBE_EXIT=$?
|
||
[ ! -e "${TEST_DIR}/grep-was-called" ] || exit 10
|
||
[ "${NVM_PROBE_EXIT}" = 0 ] || exit 11
|
||
) || die 'nvm_npmrc_bad_news_bears must read npmrc files without calling nvm_grep'
|
||
|
||
cleanup
|