Package Apple Silicon VM exports and cached runtime switching with local cabinet controls and conagent provisioning. Preserve experimental SPIKE 2 emulation. Improve preparation concurrency, Ghidra checkpoints, signature importing, sound indexing and client-side spectrograms. Include regression tests and validation notes.
110 lines
3.8 KiB
Rust
110 lines
3.8 KiB
Rust
use verstack::analysis::*;
|
|
fn function(address: &str, hash: char) -> Function {
|
|
Function {
|
|
address: address.into(),
|
|
name: "unknown".into(),
|
|
symbol_source: "DEFAULT".into(),
|
|
size: 64,
|
|
thunk: false,
|
|
body_sha256: hash.to_string().repeat(64),
|
|
}
|
|
}
|
|
fn facts(functions: Vec<Function>) -> FunctionFacts {
|
|
FunctionFacts {
|
|
processing_revision: 1,
|
|
schema: 1,
|
|
input_sha256: "fixture".into(),
|
|
language: "x86:LE:64:default".into(),
|
|
compiler: "gcc".into(),
|
|
ghidra_version: "fixture".into(),
|
|
analysis_timed_out: false,
|
|
settings: serde_json::json!({}),
|
|
functions,
|
|
}
|
|
}
|
|
#[test]
|
|
fn unique_exact_matches_keep_ambiguous_and_small_functions_unmatched() {
|
|
let mut small = function("5", 'f');
|
|
small.size = 4;
|
|
let a = facts(vec![
|
|
function("1", 'a'),
|
|
function("2", 'b'),
|
|
function("3", 'b'),
|
|
small.clone(),
|
|
]);
|
|
let b = facts(vec![
|
|
function("10", 'a'),
|
|
function("20", 'b'),
|
|
function("30", 'c'),
|
|
small,
|
|
]);
|
|
let result = compare_functions(&a, &b).unwrap();
|
|
assert_eq!(result.matches.len(), 1);
|
|
assert_eq!(result.matches[0].before.address, "1");
|
|
assert_eq!(result.matches[0].after.address, "10");
|
|
assert_eq!(result.unmatched_after.len(), 3);
|
|
}
|
|
#[test]
|
|
fn incompatible_or_incomplete_analysis_is_rejected() {
|
|
let a = facts(vec![]);
|
|
let mut b = facts(vec![]);
|
|
b.language = "ARM".into();
|
|
assert!(compare_functions(&a, &b).is_err());
|
|
b.language = a.language.clone();
|
|
b.analysis_timed_out = true;
|
|
assert!(compare_functions(&a, &b).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn selection_paths_are_not_analysis_settings_but_other_options_are() {
|
|
let mut a = facts(vec![function("1", 'a')]);
|
|
let mut b = facts(vec![function("2", 'a')]);
|
|
a.settings = serde_json::json!({"paths":["pro/game"],"max_cpu":2,"future_option":true});
|
|
b.settings = serde_json::json!({"paths":["le/game"],"max_cpu":2,"future_option":true});
|
|
assert_eq!(compare_functions(&a, &b).unwrap().matches.len(), 1);
|
|
a.settings["checkpoint_dir"] = "/tmp/cache-one".into();
|
|
b.settings["checkpoint_dir"] = "/tmp/cache-two".into();
|
|
assert_eq!(compare_functions(&a, &b).unwrap().matches.len(), 1);
|
|
b.settings["future_option"] = false.into();
|
|
assert!(compare_functions(&a, &b).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn unmatched_evidence_distinguishes_exclusions_and_ambiguity() {
|
|
let a = facts(vec![function("1", 'a'), function("2", 'a')]);
|
|
let mut unavailable = function("30", 'g');
|
|
unavailable.body_sha256.clear();
|
|
let mut thunk = function("40", 'c');
|
|
thunk.thunk = true;
|
|
let b = facts(vec![
|
|
function("10", 'a'),
|
|
function("20", 'b'),
|
|
unavailable,
|
|
thunk,
|
|
]);
|
|
let r = compare_functions(&a, &b).unwrap();
|
|
assert_eq!(r.unmatched_before.len(), 2);
|
|
assert_eq!(r.unmatched_after_reasons["10"], "ambiguous_exact_body");
|
|
assert_eq!(r.unmatched_after_reasons["20"], "no_exact_body_match");
|
|
assert_eq!(r.unmatched_after_reasons["30"], "body_hash_unavailable");
|
|
assert_eq!(r.unmatched_after_reasons["40"], "thunk_excluded");
|
|
let duplicate = facts(vec![function("1", 'a'), function("1", 'b')]);
|
|
assert!(compare_functions(&duplicate, &b).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn refuses_incompatible_processing_revisions() {
|
|
let a = facts(vec![]);
|
|
let mut b = facts(vec![]);
|
|
b.processing_revision = 2;
|
|
assert!(compare_functions(&a, &b).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn automatic_game_selection_excludes_system_menu() {
|
|
assert!(is_game_program("partition-06/pokemon_pro/game"));
|
|
assert!(is_game_program("release/Game.exe"));
|
|
assert!(!is_game_program("partition-06/pokemon_pro/spike3/spike_menu/game"));
|
|
assert!(!is_game_program("partition-02/usr/lib/libmesa.so"));
|
|
}
|