diff --git a/packages/shared/src/semver.test.ts b/packages/shared/src/semver.test.ts index a66e5b07d8bc..8896b1f46f2e 100644 --- a/packages/shared/src/semver.test.ts +++ b/packages/shared/src/semver.test.ts @@ -35,6 +35,19 @@ describe("semver helpers", () => { expect(compareSemverVersions("2.1.111-beta.1", "2.1.111")).toBeLessThan(0); }); + it("compares numeric prerelease identifiers without rounding or overflowing", () => { + for (const [lower, higher] of [ + ["9007199254740992", "9007199254740993"], + ["9".repeat(310), `1${"0".repeat(310)}`], + ]) { + const before = `1.2.3-rc.${lower}`; + const after = `1.2.3-rc.${higher}`; + expect(compareSemverVersions(before, after)).toBeLessThan(0); + expect(compareSemverVersions(after, before)).toBeGreaterThan(0); + expect(compareSemverVersions(before, before)).toBe(0); + } + }); + it("preserves hyphens within prerelease identifiers", () => { expect(normalizeSemverVersion("20-alpha-1")).toBe("20.0.0-alpha-1"); expect(parseSemver("1.2.3-alpha-1.2")).toEqual({ diff --git a/packages/shared/src/semver.ts b/packages/shared/src/semver.ts index 8d1a354f008b..9c3312399b8e 100644 --- a/packages/shared/src/semver.ts +++ b/packages/shared/src/semver.ts @@ -81,7 +81,12 @@ function comparePrereleaseIdentifier(left: string, right: string): number { const rightNumeric = SEMVER_NUMBER_SEGMENT.test(right); if (leftNumeric && rightNumeric) { - return Number.parseInt(left, 10) - Number.parseInt(right, 10); + const leftDigits = left.replace(/^0+/u, ""); + const rightDigits = right.replace(/^0+/u, ""); + return ( + leftDigits.length - rightDigits.length || + (leftDigits < rightDigits ? -1 : leftDigits > rightDigits ? 1 : 0) + ); } if (leftNumeric) { return -1;