vulns: close reviewed open ranges and fix historical subject lookup - #23634
Merged
Conversation
The history walk resolved a resource by its label, so a resource renamed between revisions read as absent, and absence was uncheckable rather than a state of its own. A revision that simply did not ship the vulnerable package therefore ended the walk instead of continuing past it, and a label change could strand the boundary at the rename. Resolve the subject by the upstream ecosystem and name instead, falling back to a scan of the formula's other resources when the label no longer matches, and treat a genuinely absent package as fixed for boundary purposes so the walk carries on to an older affected revision. This also drops a false-positive `scrapy` candidate that a live query surfaced. Signed-off-by: Patrick Linnane <patrick@linnane.io>
A record reviewed while its range was still open keeps that open range
on rewrite. When upstream data later moves the formula to `:fixed`, the
record ends up asserting `range_state: fixed` over `{introduced: "0"}`
with no `fixed` event, which reads to OSV consumers as every version
being affected. Twelve records in the current candidate set are in that
state.
`merge_existing` gains `close_open_ranges`, which appends the walked
boundary to an open range while preserving its reviewed introduction
events, and repairs an invalid range without discarding valid siblings.
The matcher passes it only when a boundary was actually walked, so
`--no-history` still rewrites nothing, and `history_required?` now
treats a non-terminal range as needing a walk so these records are
repaired rather than skipped as already reviewed.
Signed-off-by: Patrick Linnane <patrick@linnane.io>
MikeMcQuaid
approved these changes
Aug 23, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a correctness issue in emitted BREW-* OSV records where previously reviewed advisories could retain “open” ranges during rewrites, causing downstream OSV consumers to interpret all versions as affected when upstream later marks the package :fixed. It also improves historical subject resolution during FormulaVersions walks so resource renames and temporary removals don’t incorrectly truncate boundary discovery.
Changes:
- Add selective range-merging support to close previously reviewed open ranges when a real historical
fixedboundary is discovered, while repairing malformed ranges without discarding valid siblings. - Update historical subject lookup to resolve by upstream ecosystem+package identity (not just resource label), and treat historical absence as “fixed” for boundary-walking purposes so walks can cross gaps.
- Add/extend specs covering terminal-range detection, open-range closure behavior, resource absence gaps, and resource-label renames.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| Library/Homebrew/vulns/osv_export.rb | Adds ranges_terminal? and close_open_ranges merge behavior to safely close open ranges and repair invalid ones. |
| Library/Homebrew/vulns/match.rb | Improves historical subject version resolution across renames and handles subject absence during history walks. |
| Library/Homebrew/dev-cmd/advisory-match.rb | Wires terminal-range detection into --new-history logic and enables open-range closure when history is allowed. |
| Library/Homebrew/test/vulns/osv_export_spec.rb | Adds unit coverage for terminal range detection and targeted range repair/closure behavior. |
| Library/Homebrew/test/vulns/match_spec.rb | Adds coverage for history walking across resource absence and resource-label changes. |
| Library/Homebrew/test/dev-cmd/advisory-match_spec.rb | Adds integration-style coverage for closing open ranges under --new-history and ensuring --no-history preserves them. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
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.
A
BREW-*record reviewed while its range was still open keeps that open range on rewrite, so when upstream data later moves the formula to:fixedthe record assertsrange_state: fixedover{introduced: "0"}with nofixedevent, which reads to OSV consumers as every version being affected. Twelve records in Homebrew/advisory-database's current candidate set are in that state, and ten more are already on main.merge_existinggainsclose_open_ranges, which appends the walked boundary to an open range while preserving its reviewed introduction events, and repairs an invalid range without discarding valid siblings. The matcher passes it only when a boundary was actually walked, so--no-historystill rewrites nothing, andhistory_required?now treats a non-terminal range as needing a walk.Separately, the history walk resolved a resource by its label, so a rename read as absence and absence ended the walk. Subjects now resolve by upstream ecosystem and name, and an absent package counts as fixed for boundary purposes so the walk reaches an older affected revision.
Verified against live OSV data: the twelve close at their real boundaries (
isponsorblocktv2.11.0,mistral-vibe2.24.3,torrra2.1.0), a--no-historyreplay leaves them untouched with zero history walks, and a false-positivescrapycandidate no longer appears among 35 legitimate ones.brew benchmarkresults.brewcommands to reproduce the bug?brew lgtm(style, typechecking and tests) locally?Claude Code (Opus 5) drafted the implementation and tests; I reviewed the diff, verified each new test fails without its fix and passes with it, and ran
brew lgtmplus live replays over the affected records.