mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-10-26 00:14:32 +08:00
[Fix] nvm_remote_versions: place io.js versions by major version, not at the literal v4.0.0
io.js versions were inserted into node's version list immediately before the `v4.0.0` line. Whenever node's filtered list did not contain that exact line, every io.js version was appended after all node versions, including newer ones, so `nvm_remote_version`'s `tail -1` could pick an io.js version over the latest matching node version. Node's list is sorted, so it is now split at the first version with a nonzero major, which keeps io.js versions between node v0.x and node v4+ regardless of which node versions the pattern matched Discovered by Anthropic's OSS Scanner, as ANT-2026-AKH0HYWD; the scanner reported it as a vulnerability, but it is not one.
This commit is contained in:
13
nvm.sh
13
nvm.sh
@@ -1119,8 +1119,13 @@ nvm_remote_versions() {
|
||||
# extra space is needed here to avoid weird behavior when `nvm_ls_remote` ends in a `*`
|
||||
NVM_LS_REMOTE_OUTPUT="$(NVM_LTS="${NVM_LTS-}" nvm_ls_remote "${PATTERN-}") " &&:
|
||||
NVM_LS_REMOTE_EXIT_CODE=$?
|
||||
# split output into two
|
||||
NVM_LS_REMOTE_PRE_MERGED_OUTPUT="${NVM_LS_REMOTE_OUTPUT%%v4\.0\.0*}"
|
||||
# split output into two: node v0.x sorts before io.js, and node v4+ after it.
|
||||
# the list is sorted, so cut at the first line whose major is nonzero.
|
||||
case "${NVM_LS_REMOTE_OUTPUT}" in
|
||||
v[1-9]*) NVM_LS_REMOTE_PRE_MERGED_OUTPUT='' ;;
|
||||
*) NVM_LS_REMOTE_PRE_MERGED_OUTPUT="${NVM_LS_REMOTE_OUTPUT%%
|
||||
v[1-9]*}" ;;
|
||||
esac
|
||||
NVM_LS_REMOTE_POST_MERGED_OUTPUT="${NVM_LS_REMOTE_OUTPUT#"$NVM_LS_REMOTE_PRE_MERGED_OUTPUT"}"
|
||||
fi
|
||||
|
||||
@@ -1135,7 +1140,7 @@ nvm_remote_versions() {
|
||||
NVM_LS_REMOTE_IOJS_EXIT_CODE=$?
|
||||
fi
|
||||
|
||||
# the `sed` removes both blank lines, and only-whitespace lines (see "weird behavior" ~19 lines up)
|
||||
# the `sed` removes both blank lines, and only-whitespace lines (see "weird behavior" ~24 lines up)
|
||||
VERSIONS="$(nvm_echo "${NVM_LS_REMOTE_PRE_MERGED_OUTPUT}
|
||||
${NVM_LS_REMOTE_IOJS_OUTPUT}
|
||||
${NVM_LS_REMOTE_POST_MERGED_OUTPUT}" | nvm_grep -v "N/A" | command sed '/^ *$/d')"
|
||||
@@ -1144,7 +1149,7 @@ ${NVM_LS_REMOTE_POST_MERGED_OUTPUT}" | nvm_grep -v "N/A" | command sed '/^ *$/d'
|
||||
nvm_echo 'N/A'
|
||||
return 3
|
||||
fi
|
||||
# the `sed` is to remove trailing whitespaces (see "weird behavior" ~25 lines up)
|
||||
# the `sed` is to remove trailing whitespaces (see "weird behavior" ~33 lines up)
|
||||
nvm_echo "${VERSIONS}" | command sed 's/ *$//g'
|
||||
# shellcheck disable=SC2317
|
||||
if [ "${NVM_LS_REMOTE_EXIT_CODE}" != '0' ]; then
|
||||
|
||||
@@ -70,6 +70,22 @@ try nvm_remote_version node
|
||||
|| die "nvm_remote_version node did not return contents of nvm_ls_remote node; got $CAPTURED_STDOUT"
|
||||
[ "_$CAPTURED_EXIT_CODE" = "_0" ] || die "nvm_remote_version node did not exit with 0, got $CAPTURED_EXIT_CODE"
|
||||
|
||||
# io.js versions do not sort after newer node versions, even when node's list does not include v4.0.0
|
||||
nvm_ls_remote() {
|
||||
case "${1-}" in
|
||||
20 | v20.0.0) echo "v20.0.0" ;;
|
||||
*) echo "N/A"; return 3 ;;
|
||||
esac
|
||||
}
|
||||
nvm_ls_remote_iojs() {
|
||||
echo "iojs-v3.3.1"
|
||||
}
|
||||
for PATTERN in 20 v20.0.0; do
|
||||
try nvm_remote_version "${PATTERN}"
|
||||
[ "_$CAPTURED_STDOUT" = "_v20.0.0" ] || die "nvm_remote_version ${PATTERN} should return v20.0.0, got $CAPTURED_STDOUT"
|
||||
[ "_$CAPTURED_EXIT_CODE" = "_0" ] || die "nvm_remote_version ${PATTERN} should exit with code 0, got $CAPTURED_EXIT_CODE"
|
||||
done
|
||||
|
||||
# Test LTS name rejection (Issue #3474)
|
||||
# When nvm_remote_versions returns a line with LTS name in description,
|
||||
# nvm_remote_version should reject it if the pattern doesn't match the version number
|
||||
|
||||
@@ -69,4 +69,49 @@ try nvm_remote_versions iojs
|
||||
|| die "nvm_remote_versions iojs did not return contents of nvm_ls_remote_iojs; got $CAPTURED_STDOUT"
|
||||
[ "_$CAPTURED_EXIT_CODE" = "_0" ] || die "nvm_remote_versions iojs did not exit with 0, got $CAPTURED_EXIT_CODE"
|
||||
|
||||
# io.js versions sort after node v0.x and before node v4+, even when node's list has no v4.0.0
|
||||
nvm_ls_remote() {
|
||||
echo "v0.10.48"
|
||||
echo "v0.12.18"
|
||||
echo "v4.1.0"
|
||||
echo "v20.0.0 Iron *"
|
||||
}
|
||||
nvm_ls_remote_iojs() {
|
||||
echo "iojs-v1.0.0"
|
||||
echo "iojs-v3.3.1"
|
||||
}
|
||||
try nvm_remote_versions foo
|
||||
[ "_$CAPTURED_STDOUT" = "_v0.10.48
|
||||
v0.12.18
|
||||
iojs-v1.0.0
|
||||
iojs-v3.3.1
|
||||
v4.1.0
|
||||
v20.0.0 Iron *" ] \
|
||||
|| die "nvm_remote_versions foo did not put io.js versions between node v0.x and node v4+; got $CAPTURED_STDOUT"
|
||||
[ "_$CAPTURED_EXIT_CODE" = "_0" ] || die "nvm_remote_versions foo did not exit with 0, got $CAPTURED_EXIT_CODE"
|
||||
|
||||
nvm_ls_remote() {
|
||||
echo "v4.1.0"
|
||||
echo "v20.0.0 Iron *"
|
||||
}
|
||||
try nvm_remote_versions foo
|
||||
[ "_$CAPTURED_STDOUT" = "_iojs-v1.0.0
|
||||
iojs-v3.3.1
|
||||
v4.1.0
|
||||
v20.0.0 Iron *" ] \
|
||||
|| die "nvm_remote_versions foo did not put io.js versions before node v4+ when node has no v0.x; got $CAPTURED_STDOUT"
|
||||
[ "_$CAPTURED_EXIT_CODE" = "_0" ] || die "nvm_remote_versions foo did not exit with 0, got $CAPTURED_EXIT_CODE"
|
||||
|
||||
nvm_ls_remote() {
|
||||
echo "v0.10.48"
|
||||
echo "v0.12.18"
|
||||
}
|
||||
try nvm_remote_versions foo
|
||||
[ "_$CAPTURED_STDOUT" = "_v0.10.48
|
||||
v0.12.18
|
||||
iojs-v1.0.0
|
||||
iojs-v3.3.1" ] \
|
||||
|| die "nvm_remote_versions foo did not put io.js versions after node v0.x when node has no v4+; got $CAPTURED_STDOUT"
|
||||
[ "_$CAPTURED_EXIT_CODE" = "_0" ] || die "nvm_remote_versions foo did not exit with 0, got $CAPTURED_EXIT_CODE"
|
||||
|
||||
cleanup
|
||||
|
||||
Reference in New Issue
Block a user