Skip to content

vulns: close reviewed open ranges and fix historical subject lookup - #23634

Merged
p-linnane merged 2 commits into
mainfrom
advisory-match-close-open-ranges
Aug 23, 2026
Merged

vulns: close reviewed open ranges and fix historical subject lookup#23634
p-linnane merged 2 commits into
mainfrom
advisory-match-close-open-ranges

Conversation

@p-linnane

Copy link
Copy Markdown
Contributor

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 :fixed the record asserts range_state: fixed over {introduced: "0"} with no fixed event, 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_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.

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 (isponsorblocktv 2.11.0, mistral-vibe 2.24.3, torrra 2.1.0), a --no-history replay leaves them untouched with zero history walks, and a false-positive scrapy candidate no longer appears among 35 legitimate ones.


  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include brew benchmark results.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • I did not use AI/LLM to create this PR, or I disclosed the tool/model below and reviewed its output; I did not attribute commits to AI and will answer maintainer questions and review comments myself without AI/LLM.

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 lgtm plus live replays over the affected records.


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>
Copilot AI lite review requested due to automatic review settings August 23, 2026 19:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 fixed boundary 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.

@p-linnane
p-linnane enabled auto-merge August 23, 2026 19:56
@p-linnane
p-linnane added this pull request to the merge queue Aug 23, 2026
Merged via the queue into main with commit e287b9d Aug 23, 2026
48 checks passed
@p-linnane
p-linnane deleted the advisory-match-close-open-ranges branch August 23, 2026 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants