util/resolve: sort versions in matchRequirement - #386
Conversation
|
Thanks for digging into this and identifying the root cause of the issue! I am a bit concerned about sorting in The root discrepancy is actually at the API client:
Therefore, what do you think about:
|
69f0d5c to
70e045f
Compare
|
Thanks for the review @cuixq Good point about keeping Heads up: this PR was automatically closed when I renamed the head branch. The reworked change is now in #387 . |
Fixes #385. Supersedes #386 (closed after a head-branch rename) Continuing the review thread with @cuixq, who suggested sorting at the API client layer and documenting on `Client.Versions` that the versions should be sorted. ## Problem `APIClient.Versions` returned versions in the order returned by the deps.dev API, which is not ascending (for PyPI, at least, it is lexicographic, where "9.1.0" comes after "84.0.0"). The PyPI resolver iterates the version list in descending order, relying on it being sorted ascending, so unpinned transitive requirements resolved to the lexicographic maximum (e.g. `setuptools 9.1.0` instead of `84.0.0`). ## Fix Sort the versions in `APIClient.Versions`, the layer that converts the API response, and document the ordering contract on `Client.Versions`. ## Test `TestVersions` feeds a lexicographically ordered PyPI version list to `APIClient.Versions` and asserts the ascending order, and verified the test fails without the fix.
Fixes #385
Problem
The v3alpha API returns package versions sorted lexicographically by version string (e.g. for setuptools, "9.1.0" sorts after "84.0.0"). The default branch of
MatchRequirement(used by PyPI and other non-NPM systems) passed the list through unsorted, but resolvers assume matches come back in ascending order, the PyPI resolver iterates candidates in reverse (attemptToPinCriterion) and pins the first one that works. Unpinned transitive requirements therefore resolve to the lexicographic maximum (e.g.setuptools 9.1.0instead of84.0.0), producing false-positive vulnerability reports in osv-scanner with--data-source deps.dev.Fix
Call
SortVersionsat the top ofmatchRequirement, mirroring what the NPM branch already does withsortNPMVersions(util/resolve/match.go:163). Covers all systems on the default branch, not just PyPI.Test
Adds
TestMatchRequirement: feeds the lexicographic order returned by the API and asserts matches come back in ascending semver order; verified the test fails without the fix.