[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:
Jordan Harband committed 2026-10-23 08:53:59 -07:00
1 parent 35d6e5a000
commit 59e008fd62
3 files changed
+70 -4

No files matched your search

+16
View File
@@ -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
+45
View File
@@ -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