From ebc5abf3fb5f44cb4b673f2dd58a6f74fe7b35d2 Mon Sep 17 00:00:00 2001 From: Sean Proctor Date: Tue, 26 May 2026 15:25:06 -0400 Subject: [PATCH] fix: reject non-semver candidate versions in isVersionSatisfies Distributions like JetBrains Runtime publish 4-segment versions such as '17.0.8.1+1080.1' that the semver package rejects. Both compareBuild and satisfies throw on these, which surfaced to users as "Error: Invalid Version: 17.0.8.1+1080.1" and aborted the whole install when any available version was non-semver. Guard with an early semver.valid check so unparseable versions are treated as a non-match. Co-Authored-By: Claude Opus 4.7 (1M context) --- __tests__/util.test.ts | 6 +++++- dist/cleanup/index.js | 7 +++++++ dist/setup/index.js | 7 +++++++ src/util.ts | 8 ++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/__tests__/util.test.ts b/__tests__/util.test.ts index 85b76069e..91a8796ff 100644 --- a/__tests__/util.test.ts +++ b/__tests__/util.test.ts @@ -27,7 +27,11 @@ describe('isVersionSatisfies', () => { ['2.5.1+3', '2.5.1+3', true], ['2.5.1+3', '2.5.1+2', false], ['15.0.0+14', '15.0.0+14.1.202003190635', false], - ['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true] + ['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true], + // 4-segment versions (e.g. JetBrains Runtime '17.0.8.1+1080.1') are not + // valid semver — they should be rejected, not throw. + ['25.0.3+480.61', '17.0.8.1+1080.1', false], + ['17', '17.0.8.1+1080.1', false] ])( '%s, %s -> %s', (inputRange: string, inputVersion: string, expected: boolean) => { diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index df5d6c0eb..3109ac598 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -51941,6 +51941,13 @@ function getDownloadArchiveExtension() { exports.getDownloadArchiveExtension = getDownloadArchiveExtension; function isVersionSatisfies(range, version) { var _a; + // Some distributions (e.g. JetBrains Runtime) publish 4-segment versions + // like '17.0.8.1+1080.1' that semver rejects. If the candidate version + // isn't valid semver, it can't match — bail out rather than letting + // compareBuild / satisfies throw. + if (!semver.valid(version)) { + return false; + } if (semver.valid(range)) { // if full version with build digit is provided as a range (such as '1.2.3+4') // we should check for exact equal via compareBuild diff --git a/dist/setup/index.js b/dist/setup/index.js index fb687e03f..31bfe00b0 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -80695,6 +80695,13 @@ function getDownloadArchiveExtension() { exports.getDownloadArchiveExtension = getDownloadArchiveExtension; function isVersionSatisfies(range, version) { var _a; + // Some distributions (e.g. JetBrains Runtime) publish 4-segment versions + // like '17.0.8.1+1080.1' that semver rejects. If the candidate version + // isn't valid semver, it can't match — bail out rather than letting + // compareBuild / satisfies throw. + if (!semver.valid(version)) { + return false; + } if (semver.valid(range)) { // if full version with build digit is provided as a range (such as '1.2.3+4') // we should check for exact equal via compareBuild diff --git a/src/util.ts b/src/util.ts index 0325f7f42..690b775c2 100644 --- a/src/util.ts +++ b/src/util.ts @@ -55,6 +55,14 @@ export function getDownloadArchiveExtension() { } export function isVersionSatisfies(range: string, version: string): boolean { + // Some distributions (e.g. JetBrains Runtime) publish 4-segment versions + // like '17.0.8.1+1080.1' that semver rejects. If the candidate version + // isn't valid semver, it can't match — bail out rather than letting + // compareBuild / satisfies throw. + if (!semver.valid(version)) { + return false; + } + if (semver.valid(range)) { // if full version with build digit is provided as a range (such as '1.2.3+4') // we should check for exact equal via compareBuild