diff --git a/nvm.sh b/nvm.sh index 6538799f..5de201aa 100755 --- a/nvm.sh +++ b/nvm.sh @@ -361,7 +361,17 @@ nvm_is_installed_exact_version() { v*) ;; *) return 1 ;; esac - case "${1#v}" in + local NVM_EXACT_VERSION + NVM_EXACT_VERSION="${1#v}" + case "${NVM_EXACT_VERSION}" in + *-*) + case "${NVM_EXACT_VERSION#*-}" in + '' | .* | *. | *..* | *[!0-9A-Za-z.-]*) return 1 ;; + esac + NVM_EXACT_VERSION="${NVM_EXACT_VERSION%%-*}" + ;; + esac + case "${NVM_EXACT_VERSION}" in *[!0-9.]* | .* | *. | *..* | *.*.*.*) return 1 ;; *.*.*) ;; *) return 1 ;; diff --git a/test/fast/Unit tests/nvm_is_installed_exact_version b/test/fast/Unit tests/nvm_is_installed_exact_version index 10496773..d2772de9 100755 --- a/test/fast/Unit tests/nvm_is_installed_exact_version +++ b/test/fast/Unit tests/nvm_is_installed_exact_version @@ -46,10 +46,21 @@ for VERSION in 'v12.0.0.0' 'v12.0.0.' 'v12..0' 'v.12.0' 'v12.0'; do done # anything that is not an exact vX.Y.Z fails, even if it would resolve to an installed version -for VERSION in '12.0.0' '12' 'v12' 'v12.0' 'v12.0.0-rc.1' 'node' 'stable' 'lts/*' 'iojs-v1.0.0' 'system' 'default'; do +for VERSION in '12.0.0' '12' 'v12' 'v12.0' 'node' 'stable' 'lts/*' 'iojs-v1.0.0' 'system' 'default'; do ! nvm_is_installed_exact_version "$VERSION" || die "$VERSION is not an exact version and should fail" done +# an exact, installed prerelease succeeds, but a malformed one fails, even when installed +for VERSION in 'v12.0.0-rc.1' 'v12.0.0-' 'v12.0.0-.x' 'v12.0.0-a..b' 'v12.0.0-rc.'; do + mkdir -p "$NODE_PATH/$VERSION/bin" + touch "$NODE_PATH/$VERSION/bin/node" + chmod +x "$NODE_PATH/$VERSION/bin/node" +done +nvm_is_installed_exact_version 'v12.0.0-rc.1' || die 'v12.0.0-rc.1 is installed and should succeed' +for VERSION in 'v12.0.0-' 'v12.0.0-.x' 'v12.0.0-a..b' 'v12.0.0-rc.'; do + ! nvm_is_installed_exact_version "$VERSION" || die "$VERSION is not an exact version and should fail, even when installed" +done + # an alias with the exact same name takes precedence, so the fast path must not apply mkdir -p "$(nvm_alias_path)" echo 'v12.0.0' > "$(nvm_alias_path)/v12.0.0" diff --git a/test/fast/Unit tests/nvm_version b/test/fast/Unit tests/nvm_version index 689bca02..766ab3e5 100755 --- a/test/fast/Unit tests/nvm_version +++ b/test/fast/Unit tests/nvm_version @@ -57,6 +57,9 @@ EXPECTED_OUTPUT="v1.2.3" [ "_$CAPTURED_STDOUT" = "_$EXPECTED_OUTPUT" ] || die '"nvm_version v1.2.3" did not return the version itself; got '"$CAPTURED_STDOUT" [ "_$CAPTURED_EXIT_CODE" = "_0" ] || die '"nvm_version v1.2.3" did not exit 0; got '"$CAPTURED_EXIT_CODE" +try nvm_version v1.2.3-rc.1 +[ "_$CAPTURED_STDOUT" = "_v1.2.3-rc.1" ] || die '"nvm_version v1.2.3-rc.1" did not return the version itself; got '"$CAPTURED_STDOUT" + # an exact version that is not installed still falls back to "nvm_ls" nvm_is_version_installed() { return 1; } nvm_ls() { echo "pattern: $1"; } @@ -68,7 +71,7 @@ EXPECTED_OUTPUT="pattern: v1.2.3" # only exact, fully-qualified versions take the fast path nvm_is_version_installed() { die '"nvm_version" must not call "nvm_is_version_installed" for non-exact versions'; } nvm_ls() { echo "pattern: $1"; } -for PATTERN in v1.2 v1 1.2.3 v1.2.3-rc.1 v1.2.3.4 v1.2.3.; do +for PATTERN in v1.2 v1 1.2.3 v1.2.3- v1.2.3-.x v1.2.3-a..b v1.2.3.4 v1.2.3.; do try nvm_version "$PATTERN" EXPECTED_OUTPUT="pattern: $PATTERN" [ "_$CAPTURED_STDOUT" = "_$EXPECTED_OUTPUT" ] || die "nvm_version $PATTERN did not fall back to nvm_ls; got $CAPTURED_STDOUT"