panic_attacker/xray/
mod.rs1pub mod analyzer;
8pub mod patterns;
9
10use crate::types::*;
11use anyhow::Result;
12use std::path::Path;
13
14pub use analyzer::Analyzer;
15
16pub fn analyze<P: AsRef<Path>>(target: P) -> Result<XRayReport> {
18 let analyzer = Analyzer::new(target.as_ref())?;
19 analyzer.analyze()
20}
21
22pub fn analyze_verbose<P: AsRef<Path>>(target: P) -> Result<XRayReport> {
24 let analyzer = Analyzer::new_verbose(target.as_ref())?;
25 let report = analyzer.analyze()?;
26
27 println!("X-Ray Analysis Complete");
28 println!(" Language: {:?}", report.language);
29 println!(" Frameworks: {:?}", report.frameworks);
30 println!(" Weak Points: {}", report.weak_points.len());
31 println!(" Recommended Attacks: {:?}", report.recommended_attacks);
32
33 if !report.file_statistics.is_empty() {
35 println!("\n Per-file Breakdown (top 10 by risk):");
36
37 let mut scored: Vec<_> = report
38 .file_statistics
39 .iter()
40 .map(|fs| {
41 let risk = fs.unsafe_blocks * 3
42 + fs.panic_sites * 2
43 + fs.unwrap_calls
44 + fs.threading_constructs * 2;
45 (risk, fs)
46 })
47 .collect();
48 scored.sort_by(|a, b| b.0.cmp(&a.0));
49
50 for (rank, (risk, fs)) in scored.iter().take(10).enumerate() {
51 println!(
52 " {}. {} (risk: {}, lines: {}, unsafe: {}, panics: {}, \
53 unwraps: {}, alloc: {}, io: {}, threads: {})",
54 rank + 1,
55 fs.file_path,
56 risk,
57 fs.lines,
58 fs.unsafe_blocks,
59 fs.panic_sites,
60 fs.unwrap_calls,
61 fs.allocation_sites,
62 fs.io_operations,
63 fs.threading_constructs,
64 );
65 }
66
67 if scored.len() > 10 {
68 println!(" ... and {} more files", scored.len() - 10);
69 }
70 }
71
72 Ok(report)
73}