pub mod attacks;
pub mod bytes;
pub mod decode;
pub mod entropy;
pub mod magic;
pub mod spans;
pub mod xor;
pub use attacks::{
detect_command_injection, detect_lfi, detect_obfuscated_js, detect_path_traversal, detect_rfi,
detect_sql_injection, detect_ssrf, detect_xss, detect_xxe,
};
pub use bytes::{
contains_ci, find_bytes, find_ci, is_alnum, is_base64_char, is_base64url_char, is_boundary,
is_email_domain, is_email_local, is_uri_char, lower_ascii, starts_ci,
};
pub use decode::{
hex_nibble, parse_ipv4, parse_ipv6, parse_jwt, parse_octet, percent_decode_lower,
};
pub use entropy::{high_entropy_offsets, high_entropy_spans, shannon_bits};
pub use magic::{
detect_packed_binary, file_magic_detect, push_if, MagicFinding, MAGIC_CLASS, MAGIC_ELF,
MAGIC_GZIP, MAGIC_MACHO32, MAGIC_MACHO64, MAGIC_PDF, MAGIC_PE, MAGIC_PNG, MAGIC_ZIP,
};
pub use spans::{
advance_while, base64_run_offsets, email_spans, hex_run_offsets, ipv4_spans, ipv6_spans,
jwt_spans, matches_uuid, pem_spans, push_run, rewind_while, run_offsets, span, url_spans,
uuid_spans, ByteSpan,
};
pub use xor::{
best_key, dedupe, detect_xor_single_byte, english_score, looks_like_plaintext, ranges_overlap,
XorSingleByteFinding,
};
pub const MAX_INPUT_LEN: usize = 64 * 1024 * 1024;
pub type DetectionError = String;
pub fn to_u32(value: usize, field: &str) -> Result<u32, DetectionError> {
u32::try_from(value)
.map_err(|_| format!("Fix: reduce input length so {field} {value} fits in U32"))
}
pub fn validate_input(input: &[u8]) -> Result<(), DetectionError> {
if input.len() > MAX_INPUT_LEN {
return Err(format!(
"Fix: reduce security detector input length to <= {MAX_INPUT_LEN} bytes, got {}",
input.len()
));
}
Ok(())
}