1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! Forensic anomaly analysis for **trash / deleted-file artifacts**, layered on
//! the [`trash_core`] readers. Each platform's analyzer lives in its own module,
//! gated behind a same-named Cargo feature (all enabled by default):
//!
//! | Module | Feature | Scheme | Artifact |
//! |---|---|---|---|
//! | [`windows`] | `windows` | `RECYCLEBIN-*` | Recycle Bin `$I`/`$R` |
//! | [`linux`] | `linux` | `TRASH-*` | freedesktop.org / XDG `.trashinfo` |
//!
//! Every analyzer inspects a parsed reader record + its pairing and reports
//! anomalies as canonical [`forensicnomicon::report::Finding`]s, so trash
//! findings aggregate alongside every other `SecurityRonin` analyzer. Findings
//! are observations, never legal conclusions: the analyst concludes.
//!
//! ```no_run
//! # #[cfg(feature = "windows")]
//! # fn demo(dir: &std::path::Path) -> std::io::Result<()> {
//! use trash_core::{parse_index, scan_pairs};
//! use trash_forensic::audit_pair;
//! for pair in scan_pairs(dir)? {
//! let bytes = std::fs::read(&pair.index_path)?;
//! if let Ok(index) = parse_index(&bytes) {
//! for finding in audit_pair(&index, &pair) {
//! println!("[{:?}] {} — {}", finding.severity, finding.code, finding.note);
//! }
//! }
//! }
//! # Ok(())
//! # }
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
/// Analyzer name, recorded on every finding's [`forensicnomicon::report::Source`]
/// for reproducibility, shared across the per-OS analyzers.
pub const ANALYZER: &str = "trash-forensic";
/// Whether a stored path contains a parent-directory (`..`) component, treating
/// both Windows (`\`) and POSIX (`/`) separators. Matches `..` only as a whole
/// path component, so a filename like `my..notes.txt` is not flagged. Shared by
/// every platform analyzer (path traversal is a cross-platform concealment tell).
pub