fix: subset false-positive with a prerelease eq and a differing bound#889
Open
spokodev wants to merge 1 commit into
Open
fix: subset false-positive with a prerelease eq and a differing bound#889spokodev wants to merge 1 commit into
spokodev wants to merge 1 commit into
Conversation
`subset(sub, dom)` returned `true` when `sub` combined an exact prerelease
comparator (`=X.Y.Z-pre`) with a `>`/`>=`/`<`/`<=` bound of a different
`[major,minor,patch]` tuple, even though `sub` contains a version outside
`dom`:
subset('=1.1.2-alpha <3.1.0', '<1.0.0') // true, must be false
satisfies('1.1.2-alpha', '=1.1.2-alpha <3.1.0') // true (in sub)
satisfies('1.1.2-alpha', '<1.0.0') // false (not in dom)
In `simpleSubset`, the eqSet-vs-bound checks used
`satisfies(eq, String(gt), options)`, which rebuilds a full Range and
re-applies node-semver's prerelease-exclusion gating, so a prerelease `eq`
is judged not to satisfy a plain bound of another tuple. The code then
treats the eqSet as inconsistent and returns `null` (null set), which
`subset` reports as a subset of everything.
Test the eq version against the raw bound comparator instead
(`gt.test(eq)` / `lt.test(eq)`) — the same fix PR npm#867 applied to the
dom-side checks, which this left in place on the eqSet side.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
subset(sub, dom)returnstrue(claimssub ⊆ dom) when it is actuallyfalse. It triggers whensubcombines an exact prerelease comparator (=X.Y.Z-pre) with a>/>=/</<=bound whose version has a different[major, minor, patch]tuple — a subset false-positive (the dangerous direction):Adding the
<3.1.0bound (which1.1.2-alphasatisfies) can only shrinksub, so it should never turn a non-subset into a subset — a monotonicity violation.Root cause
In
simpleSubset, the eqSet-vs-bound checks usedsatisfies(eq, String(gt), options).satisfiesbuilds a fullRangeand re-applies node-semver's prerelease-exclusion gating, so a prereleaseeq(1.1.2-alpha) is judged not to satisfy a plain bound of a different tuple (<3.1.0). The code then treats the eqSet as inconsistent withsuband returnsnull(a null set), whichsubsetreports as a subset of everything. In reality the eq version does satisfysub, because its own=eqcomparator admits its prerelease.This is the same "re-applying full-range prerelease gating on an isolated comparator" issue that PR #867 fixed on the dom side (
subset.js:177,:195), but it was left in place on the sub (eqSet) side (:127,:131).Fix
Test the eq version against the raw bound comparator (
gt.test(eq)/lt.test(eq)), mirroring PR #867.Tests
Added two
subsetcases (=1.1.2-alpha <3.1.0 ⊄ <1.0.0,<3.1.0-0 1.1.2-alpha ⊄ ~2.0). Both fail onmainand pass with the fix; issue #757's case (^10.2.0-beta.2 ⊂ ^10.2.0-beta.1) stays correct and the ranges tests pass.