bench: harden architecture scan evidence #1
1 changed files with 75 additions and 1 deletions
fix(fold): normalize imported finding paths
commit
e03c2a299b
76
src/fold.rs
76
src/fold.rs
|
|
@ -207,19 +207,45 @@ fn native_backend(value: &Value) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_file(building: &Building, path: &str) -> Option<String> {
|
fn find_file(building: &Building, path: &str) -> Option<String> {
|
||||||
let normalized = path.replace('\\', "/");
|
let normalized = normalize_lexical_path(path);
|
||||||
building
|
building
|
||||||
.nodes
|
.nodes
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|node| node.kind == NodeKind::File)
|
.filter(|node| node.kind == NodeKind::File)
|
||||||
.find(|node| {
|
.find(|node| {
|
||||||
node.path.as_deref().is_some_and(|candidate| {
|
node.path.as_deref().is_some_and(|candidate| {
|
||||||
|
let candidate = normalize_lexical_path(candidate);
|
||||||
normalized == candidate || normalized.ends_with(&format!("/{candidate}"))
|
normalized == candidate || normalized.ends_with(&format!("/{candidate}"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.map(|node| node.id.clone())
|
.map(|node| node.id.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalize_lexical_path(path: &str) -> String {
|
||||||
|
let portable = path.replace('\\', "/");
|
||||||
|
let absolute = portable.starts_with('/');
|
||||||
|
let mut components = Vec::new();
|
||||||
|
for component in portable.split('/') {
|
||||||
|
match component {
|
||||||
|
"" | "." => {}
|
||||||
|
".." => {
|
||||||
|
if components.last().is_some_and(|previous| *previous != "..") {
|
||||||
|
components.pop();
|
||||||
|
} else if !absolute {
|
||||||
|
components.push(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => components.push(component),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let normalized = components.join("/");
|
||||||
|
if absolute {
|
||||||
|
format!("/{normalized}")
|
||||||
|
} else {
|
||||||
|
normalized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn confidence_value(confidence: &str) -> f64 {
|
fn confidence_value(confidence: &str) -> f64 {
|
||||||
match confidence {
|
match confidence {
|
||||||
"concrete-witness" => 1.0,
|
"concrete-witness" => 1.0,
|
||||||
|
|
@ -258,4 +284,52 @@ mod tests {
|
||||||
assert_eq!(finding.attributes["confidence"], "proved");
|
assert_eq!(finding.attributes["confidence"], "proved");
|
||||||
assert_eq!(finding.attributes["backend"], "source");
|
assert_eq!(finding.attributes["backend"], "source");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn normalizes_fold_paths_without_matching_a_missing_neighbor() {
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
let header = dir.path().join("include/yams/core/types.h");
|
||||||
|
fs::create_dir_all(header.parent().unwrap()).unwrap();
|
||||||
|
fs::write(&header, "struct Type {};\n").unwrap();
|
||||||
|
let report = dir.path().join("fold.sarif");
|
||||||
|
fs::write(
|
||||||
|
&report,
|
||||||
|
r#"{
|
||||||
|
"runs": [{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"ruleId": "fold.valid",
|
||||||
|
"message": {"text": "valid"},
|
||||||
|
"locations": [{"physicalLocation": {
|
||||||
|
"artifactLocation": {"uri": "../../include/yams/daemon/components/../../core/types.h"},
|
||||||
|
"region": {"startLine": 1}
|
||||||
|
}}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ruleId": "fold.missing",
|
||||||
|
"message": {"text": "missing"},
|
||||||
|
"locations": [{"physicalLocation": {
|
||||||
|
"artifactLocation": {"uri": "../../include/yams/daemon/components/../../core/missing.h"},
|
||||||
|
"region": {"startLine": 1}
|
||||||
|
}}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut building = scan(dir.path()).unwrap();
|
||||||
|
assert_eq!(import_findings(&mut building, &report).unwrap(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
building
|
||||||
|
.nodes
|
||||||
|
.iter()
|
||||||
|
.filter(|node| node.kind == NodeKind::Finding)
|
||||||
|
.count(),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
assert_eq!(building.diagnostics.len(), 1);
|
||||||
|
assert!(building.diagnostics[0].message.contains("missing.h"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue