Skip to main content

guardy/scan/static_data/
binary_extensions.rs

1//! Binary file extensions with base + custom support
2//!
3//! Provides a global set of binary file extensions that is compiled once
4//! and shared across all threads for O(1) lookup performance.
5
6use std::{
7    collections::HashSet,
8    sync::{Arc, LazyLock},
9};
10
11use anyhow::Result;
12
13/// Load custom binary extensions from configuration
14fn load_custom_extensions() -> Result<Vec<String>> {
15    // TODO: Implement loading from:
16    // - ~/.config/guardy/binary_extensions.txt (one per line)
17    // - Environment variable GUARDY_BINARY_EXTENSIONS (comma-separated)
18    // - ScannerConfig custom extensions
19
20    // For now, return empty
21    Ok(Vec::new())
22}
23
24/// Global shared binary extensions - base + custom merged
25pub static BINARY_EXTENSIONS: LazyLock<Arc<HashSet<String>>> = LazyLock::new(|| {
26    let start = std::time::Instant::now();
27
28    // Base extensions (comprehensive list from v2) - copied exactly from types.rs
29    let base_extensions = vec![
30        // Images
31        "png", "jpg", "jpeg", "gif", "bmp", "ico", "webp", "tiff", "tif", "avif", "heic", "heif",
32        "dng", "raw", "nef", "cr2", "arw", "orf", "rw2", "svg", // Documents
33        "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "odt", "ods", "odp", "indd",
34        // Archives
35        "zip", "tar", "gz", "bz2", "xz", "7z", "rar", "dmg", "iso", "ace", "cab", "lzh", "arj",
36        "br", "zst", "lz4", "lzo", "lzma", "tgz", // Executables & Object Files
37        "exe", "dll", "so", "dylib", "bin", "app", "deb", "rpm", "o", "obj", "lib", "a", "pdb",
38        "exp", "ilk", // Audio/Video
39        "mp3", "wav", "ogg", "flac", "aac", "mp4", "avi", "mkv", "mov", "wmv", "webm", "mp2",
40        "m4a", "wma", "amr", // Fonts
41        "ttf", "otf", "woff", "woff2", "eot",
42        // Security/Crypto (keeping PEM for secret detection)
43        "gpg", "pgp", "p12", "pfx", "der", "crt", "keystore", // Database & Data Files
44        "db", "sqlite", "sqlite3", "mdb", "sst", "ldb", "wal", "snap", "dat", "sas7bdat",
45        "sas7bcat", "rdb", // CAD & Design Files
46        "dwg", "dxf", "skp", "3ds", "max", "blend", "fbx",
47        // Compiler & Build Artifacts
48        "gcno", "gcda", "gcov", "wasm", "webc", // Binary Data & Image Files
49        "img", "dmg", "vhd", "vmdk", "qcow2", "raw", // Other binary formats
50        "pyc", "pyo", "class", "jar", "war", "ear", "swf", "fla", "npy",
51        // NX cache files
52        "nxt", // Common DOS/Legacy executables
53        "com", "bat", "cmd", // Specialized formats that are definitely binary
54        "bas", "pic", "b", "mcw", "ind", "dsk", "z",
55        // Test data and specialized formats that often cause UTF-8 issues
56        "gdiff", "srt", "zeno", "cba", "parquet", "avro", "orc",
57        // Additional problematic formats discovered in scans
58        "pak", "rpak", "webc", "toast", "data", // ai
59        "pt",   // other
60        "crl", "ptx", "sf", "jrprint", "sbt", "nepprj", "psf", "mac", "g3w", "hpi", "o5c", "cf1",
61        "car", "vwx", "md8", "amg", "lb6", "nk2", "dwb", "skn", "signal", "jsa", "hlp", "kcw",
62        "res", "cf2", "cwg", "vpk", "psbt", "sb",
63        // Git and VCS files (large pack files, logs, etc.)
64        "pack", "idx", "raftlog", "map", // Large binary formats causing memory issues
65        "pth", "wasmu", "avif", "part",
66    ];
67
68    let mut all_extensions = HashSet::new();
69
70    // Add base extensions
71    for ext in base_extensions {
72        all_extensions.insert(ext.to_string());
73    }
74
75    // Try to load and add custom extensions
76    match load_custom_extensions() {
77        Ok(custom) => {
78            if !custom.is_empty() {
79                tracing::info!("Loaded {} custom binary extensions", custom.len());
80                for ext in custom {
81                    all_extensions.insert(ext);
82                }
83            }
84        }
85        Err(e) => {
86            tracing::warn!("Failed to load custom binary extensions: {}", e);
87        }
88    }
89
90    tracing::debug!(
91        "Binary extensions initialized with {} extensions in {:?}",
92        all_extensions.len(),
93        start.elapsed()
94    );
95
96    Arc::new(all_extensions)
97});
98
99/// Check if a file extension is binary
100pub fn is_binary_extension(extension: &str) -> bool {
101    BINARY_EXTENSIONS.contains(extension)
102}