fix: compare large numeric prerelease ids without precision loss - #880
Open
spokodev wants to merge 1 commit into
Open
fix: compare large numeric prerelease ids without precision loss#880spokodev wants to merge 1 commit into
spokodev wants to merge 1 commit into
Problem
Two valid versions whose prerelease numeric identifiers are >=
2^53are reported equal and mis-sorted:Both versions are valid SemVer (there is no magnitude cap on numeric prerelease identifiers in §9), so this violates SemVer 2.0.0 §11.4.1:
9007199254740992and9007199254740993are distinct integers and must order accordingly.Root cause
classes/semver.jsdeliberately keeps numeric prerelease ids>= MAX_SAFE_INTEGERas strings to avoid IEEE-754 precision loss in storage:But
internal/identifiers.jscompareIdentifiersre-introduced that loss for any all-digit identifier:+'9007199254740992'and+'9007199254740993'both evaluate to the same double (9007199254740992), so the comparison sees them as equal.Fix
Compare all-digit identifiers with
BigIntinstead ofNumber, preserving full integer precision:The already-numberified fast path (
typeof a === 'number' && typeof b === 'number', for ids< MAX_SAFE_INTEGER) is untouched, and mixed alphanumeric ordering is unchanged.Tests
Added a unit case in
test/internal/identifiers.jsforcompareIdentifiers/rcompareIdentifierswith ids beyond2^53, and a fixture entry intest/fixtures/comparisons.jsexercisingcompare/gt/eqend to end. Both fail on the unpatched code and pass with the fix. Fullnpm testsuite (including lint and 100% coverage) is green.