← Back to Blog
|4 min read

P = R = F1 = 1.0 across 25 languages

When a CVE is detected in your dependency graph, the first question is not “what is the CVSS score?” It is “does my code actually call the vulnerable function?” Reachability analysis answers that question. And as of PatchOps Guard v0.12.0, our tree-sitter-based engine answers it with perfect accuracy across 25 programming languages.

The benchmark

We maintain a 97-case benchmark built from real CVEs across all 25 supported languages. Each case contains a lockfile declaring a vulnerable dependency, source code that either does or does not call the affected symbol, and a ground-truth label. The benchmark covers:

  • Python, JavaScript, TypeScript, Go, Java, Rust, C#, PHP, Swift, Kotlin, Scala, Dart
  • Ruby, Elixir, Erlang, Lua, Perl, OCaml, Julia
  • C, C++, Objective-C, Haskell, R, Clojure

Every test case exercises real import patterns: qualified imports, aliased imports, re-exports, wildcard imports, and multiline import statements. The result: precision 1.00, recall 1.00, F1 1.00.

How tree-sitter reachability works

Traditional SCA tools check whether a vulnerable package appears in your lockfile. That produces massive false-positive rates — studies show 70-85% of flagged CVEs are unreachable. Our approach is fundamentally different:

  • Parse, do not regex. We use tree-sitter to build a concrete syntax tree of every source file. This handles aliased imports (import numpy as np), qualified access (com.fasterxml.jackson.databind), and language-specific idioms like Elixir’s alias macro.
  • Symbol-level matching. For each vulnerable package, we maintain a curated symbol database. For C/C++ alone, this covers 100 libraries and 2,498 exported symbols (zlib, openssl, libcurl, etc.). We match call sites against these symbols, not just package names.
  • Name variant generation. Packages and modules follow different naming conventions. phoenix on Hex becomes Phoenix in Elixir code. pyyaml on PyPI is imported as yaml. Our _name_variants hook generates all plausible import names from the package name.

Why this matters

A vulnerability that your code never calls is noise. A vulnerability that your code calls through three layers of aliasing is critical. Without precise reachability, you either drown in false positives or miss the real threats. PatchOps Guard eliminates both failure modes.

When reachability analysis determines a CVE is unreachable, the VEX annotation in your SBOM reflects not_affected with a machine-readable justification. When it is reachable, the Defense Window Score increases and the AI repair pipeline prioritizes it. Every decision is traceable.


Explore the benchmark results on the public leaderboard or connect your first repository at patchguard.ai.