use crate::frx_load::LoadedRules;
use crate::load_request;
use crate::frx_scan::scan_content;
use crate::path_scan::{PathScanRecords, scan_path_records};
use crate::{BIN_PROBE_SIZE, ScanFinding};
use anyhow::Result;
use crate::runtime_cache::CacheWarning;
use std::path::Path;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CandidateScan {
pub identity: usize,
pub display_path: String,
pub findings: Vec<ScanFinding>,
pub scanned_bytes: usize,
}
pub struct Scanner {
loaded: LoadedRules,
}
impl Scanner {
pub fn load(runtime_rules_path: &Path, builtin_rules: bool, explicit: bool) -> Result<Scanner> {
let loaded: LoadedRules = load_request::load(runtime_rules_path, builtin_rules, explicit)?;
return Ok(Scanner { loaded });
}
pub fn cache_warnings(&self) -> &[CacheWarning] {
return self.loaded.cache_warnings();
}
pub fn scan(&self, identity: usize, logical_path: &Path, bytes: &[u8]) -> CandidateScan {
let pathname: PathScanRecords = scan_path_records(logical_path, &self.loaded);
let probe_length: usize = bytes.len().min(BIN_PROBE_SIZE);
let probe: &[u8] = &bytes[..probe_length];
let content: &[u8] = if memchr::memchr(0, probe).is_some() { probe } else { bytes };
let mut findings: Vec<ScanFinding> = pathname.findings;
findings.extend(scan_content(content, &self.loaded));
return CandidateScan {
identity,
display_path: pathname.display,
findings,
scanned_bytes: content.len(),
};
}
}
#[cfg(feature = "fuzzing")]
pub fn scanner_from_text_for_fuzzing(text: &str) -> Result<Scanner> {
let loaded: LoadedRules = crate::frx_load::hybrid_from_text(text)?;
return Ok(Scanner { loaded });
}
#[cfg(test)]
#[path = "scanner_tests.rs"]
mod tests;
#[cfg(test)]
#[path = "scanner_boundary_tests.rs"]
mod boundary_tests;