mirror of
https://github.com/imjasonh/rustvulncheck
synced 2026-07-08 04:08:07 +00:00
Precise golden integration tests and scanner fixes for edge cases
Scanner fixes: - Block comment tracking: skip lines inside /* ... */ blocks - Skip `use` statements from being matched as call sites - Free function call detection: `parse_cookie(...)` after direct import - Type-aware suppression: when the receiver's type is positively known and doesn't match the vulnerable type, suppress the finding entirely (e.g., .abort() on MyHandle vs JoinHandle) Golden test improvements: - All assertions are now specific: exact counts (deps, reachable symbols, files scanned), exact advisory IDs listed vs reachable, exact call site locations (file:line), exact confidence levels (HIGH vs MEDIUM) - Each test documents its fixture layout and expected positive/negative findings in a header comment New edge_cases_project fixture covering: - Aliased imports (Decoder as HyperDecoder → dec.decode detected) - Free function calls (parse_cookie after direct import) - Commented-out code (block & line comments correctly skipped) - False positive suppression (abort() on MyHandle, parse() on String) - Typed method calls (jar.add(c) with explicit CookieJar type) 38 tests total (33 unit + 5 integration), all passing. https://claude.ai/code/session_011sdj18ZvQYbDVwEKqrWDj1
This commit is contained in:
parent
a2db0d4d15
commit
76921cfde0
10 changed files with 530 additions and 99 deletions
|
|
@ -235,7 +235,15 @@ fn find_call_sites(
|
|||
}
|
||||
}
|
||||
|
||||
// 4. After `use hyper::http::Request;` and calling as method: foo.parse(...)
|
||||
// 4. Free function import: `use cookie::parse::parse_cookie;` → bare `parse_cookie(...)`
|
||||
// When the full symbol is imported directly, the bare name is a valid caller.
|
||||
for (local, full) in &import_map {
|
||||
if *full == symbol {
|
||||
local_callers.push(local.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// 5. After `use hyper::http::Request;` and calling as method: foo.parse(...)
|
||||
// This is lower confidence since we can't verify the receiver type.
|
||||
let method_pattern = format!(".{}(", fn_name);
|
||||
|
||||
|
|
@ -248,12 +256,32 @@ fn find_call_sites(
|
|||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
let mut in_block_comment = false;
|
||||
|
||||
for (line_num, line) in source.lines().enumerate() {
|
||||
let trimmed = line.trim();
|
||||
|
||||
// Skip comments
|
||||
if trimmed.starts_with("//") || trimmed.starts_with("/*") || trimmed.starts_with('*')
|
||||
{
|
||||
// Track block comments: /* ... */
|
||||
if in_block_comment {
|
||||
if trimmed.contains("*/") {
|
||||
in_block_comment = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if trimmed.starts_with("/*") {
|
||||
if !trimmed.contains("*/") {
|
||||
in_block_comment = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip line comments
|
||||
if trimmed.starts_with("//") || trimmed.starts_with('*') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip `use` statements — they are imports, not calls
|
||||
if trimmed.starts_with("use ") {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -290,9 +318,18 @@ fn find_call_sites(
|
|||
b.var_name.ends_with(&format!(".{}", &receiver_var[5..]))
|
||||
&& b.type_path == parent_path
|
||||
});
|
||||
|
||||
if receiver_matches || field_matches {
|
||||
Confidence::High
|
||||
} else {
|
||||
// If we positively know the receiver's type and it
|
||||
// doesn't match, suppress the finding entirely.
|
||||
let type_is_known = type_bindings
|
||||
.iter()
|
||||
.any(|b| b.var_name == receiver_var);
|
||||
if type_is_known {
|
||||
continue; // Known wrong type — not a match
|
||||
}
|
||||
Confidence::Medium
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue