From 3aeae985063c8740f3ec69c90f4047f00024cf3f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 01:52:22 +0000 Subject: [PATCH] Fix advisory parsing for .md format and suppress compiler warnings The RustSec advisory-db uses .md files with TOML in a fenced code block, not plain .toml files. The parser now extracts the TOML block from markdown. Also fixes: - --limit now means "collect up to N enriched entries" instead of "take first N candidates", so it keeps scanning until enough are found - Suppressed dead_code warnings on Issue variant and deserialization-only fields - Updated test fixtures to match the .md format https://claude.ai/code/session_01AeNG3herWfKhos9uZVUY5d --- src/advisory.rs | 19 ++++++++++-- src/main.rs | 30 +++++++++++-------- ...EC-2024-0001.toml => RUSTSEC-2024-0001.md} | 6 ++++ ...EC-2024-0003.toml => RUSTSEC-2024-0003.md} | 6 ++++ ...EC-2024-0002.toml => RUSTSEC-2024-0002.md} | 6 ++++ 5 files changed, 53 insertions(+), 14 deletions(-) rename tests/fixtures/crates/hyper/{RUSTSEC-2024-0001.toml => RUSTSEC-2024-0001.md} (69%) rename tests/fixtures/crates/smallvec/{RUSTSEC-2024-0003.toml => RUSTSEC-2024-0003.md} (69%) rename tests/fixtures/crates/tokio/{RUSTSEC-2024-0002.toml => RUSTSEC-2024-0002.md} (70%) diff --git a/src/advisory.rs b/src/advisory.rs index 0ebcbba..8fdf8a7 100644 --- a/src/advisory.rs +++ b/src/advisory.rs @@ -27,6 +27,7 @@ pub struct AdvisoryMeta { #[serde(default)] pub title: Option, #[serde(default)] + #[allow(dead_code)] pub description: Option, } @@ -35,6 +36,7 @@ pub struct VersionInfo { #[serde(default)] pub patched: Vec, #[serde(default)] + #[allow(dead_code)] pub unaffected: Vec, } @@ -70,6 +72,7 @@ pub enum GithubRef { repo: String, number: u64, }, + #[allow(dead_code)] Issue { owner: String, repo: String, @@ -149,7 +152,8 @@ pub fn parse_advisory_db(db_path: &Path) -> Result> { .filter_map(|e| e.ok()) { let path = entry.path(); - if path.extension().map_or(true, |ext| ext != "toml") { + // Advisory-db uses .md files with TOML in a fenced code block + if path.extension().map_or(true, |ext| ext != "md") { continue; } @@ -171,8 +175,12 @@ fn parse_advisory_file(path: &Path) -> Result { let content = std::fs::read_to_string(path).with_context(|| format!("reading {}", path.display()))?; + // Advisory-db .md files have TOML inside a ```toml ... ``` fenced block + let toml_content = extract_toml_block(&content) + .with_context(|| format!("no TOML block found in {}", path.display()))?; + let file: AdvisoryFile = - toml::from_str(&content).with_context(|| format!("parsing {}", path.display()))?; + toml::from_str(&toml_content).with_context(|| format!("parsing {}", path.display()))?; let mut github_urls = Vec::new(); @@ -202,3 +210,10 @@ fn parse_advisory_file(path: &Path) -> Result { github_urls, }) } + +/// Extract the TOML content from a markdown file with a ```toml fenced block. +fn extract_toml_block(content: &str) -> Option { + let start = content.find("```toml\n")? + "```toml\n".len(); + let end = content[start..].find("```")? + start; + Some(content[start..end].to_string()) +} diff --git a/src/main.rs b/src/main.rs index 0970699..4558992 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,8 @@ struct Args { #[arg(long)] advisory_db: Option, - /// Maximum number of advisories to process (most recent first). + /// Maximum number of enriched entries to collect (most recent first). + /// Processes advisories until this many have been successfully enriched. #[arg(long, default_value = "10")] limit: usize, @@ -77,29 +78,34 @@ fn main() -> Result<()> { candidates.len() ); - let to_process = &candidates[..candidates.len().min(args.limit)]; - println!("Processing {} advisories...\n", to_process.len()); + println!( + "Processing advisories (collecting up to {} enriched entries)...\n", + args.limit + ); // Step 3: Fetch diffs and extract symbols let gh = GithubClient::new(args.github_token); let mut vuln_db = VulnDb::new(); - for (i, adv) in to_process.iter().enumerate() { + for adv in &candidates { + if vuln_db.entries.len() >= args.limit { + break; + } + + let gh_refs = adv.github_refs(); + if gh_refs.is_empty() { + continue; + } + println!( "[{}/{}] {} ({}) - {}", - i + 1, - to_process.len(), + vuln_db.entries.len() + 1, + args.limit, adv.id, adv.package, adv.title ); - let gh_refs = adv.github_refs(); - if gh_refs.is_empty() { - println!(" No parseable GitHub refs, skipping"); - continue; - } - let mut entry = VulnEntry { advisory_id: adv.id.clone(), package: adv.package.clone(), diff --git a/tests/fixtures/crates/hyper/RUSTSEC-2024-0001.toml b/tests/fixtures/crates/hyper/RUSTSEC-2024-0001.md similarity index 69% rename from tests/fixtures/crates/hyper/RUSTSEC-2024-0001.toml rename to tests/fixtures/crates/hyper/RUSTSEC-2024-0001.md index d4d21ee..10c9b67 100644 --- a/tests/fixtures/crates/hyper/RUSTSEC-2024-0001.toml +++ b/tests/fixtures/crates/hyper/RUSTSEC-2024-0001.md @@ -1,3 +1,4 @@ +```toml [advisory] id = "RUSTSEC-2024-0001" package = "hyper" @@ -8,3 +9,8 @@ references = ["https://github.com/hyperium/hyper/commit/abc123def456"] [versions] patched = [">= 1.2.0"] +``` + +# Lenient HTTP header parsing allows request smuggling + +A bug in hyper's header parsing could allow request smuggling. diff --git a/tests/fixtures/crates/smallvec/RUSTSEC-2024-0003.toml b/tests/fixtures/crates/smallvec/RUSTSEC-2024-0003.md similarity index 69% rename from tests/fixtures/crates/smallvec/RUSTSEC-2024-0003.toml rename to tests/fixtures/crates/smallvec/RUSTSEC-2024-0003.md index 05dca43..e15065f 100644 --- a/tests/fixtures/crates/smallvec/RUSTSEC-2024-0003.toml +++ b/tests/fixtures/crates/smallvec/RUSTSEC-2024-0003.md @@ -1,3 +1,4 @@ +```toml [advisory] id = "RUSTSEC-2024-0003" package = "smallvec" @@ -8,3 +9,8 @@ references = [] [versions] patched = [">= 1.13.1"] +``` + +# Buffer overflow in SmallVec::insert_many + +A buffer overflow in SmallVec's insert_many method. diff --git a/tests/fixtures/crates/tokio/RUSTSEC-2024-0002.toml b/tests/fixtures/crates/tokio/RUSTSEC-2024-0002.md similarity index 70% rename from tests/fixtures/crates/tokio/RUSTSEC-2024-0002.toml rename to tests/fixtures/crates/tokio/RUSTSEC-2024-0002.md index ce6a11c..cf8f5df 100644 --- a/tests/fixtures/crates/tokio/RUSTSEC-2024-0002.toml +++ b/tests/fixtures/crates/tokio/RUSTSEC-2024-0002.md @@ -1,3 +1,4 @@ +```toml [advisory] id = "RUSTSEC-2024-0002" package = "tokio" @@ -8,3 +9,8 @@ references = ["https://github.com/tokio-rs/tokio/commit/deadbeef1234"] [versions] patched = [">= 1.36.0"] +``` + +# Race condition in task cancellation + +A race condition in tokio's task cancellation could cause issues.