From 9bd7685dc3acbb59e205436a5d8375b53b31f323 Mon Sep 17 00:00:00 2001 From: Daniel Heule Date: Fri, 9 Jan 2026 09:54:52 +0100 Subject: [PATCH] Bugfix for hash generation of non utf8 files --- src/rsnmplib/filesum.rs | 25 ++++++++++++++++--------- src/rsnmplib/helper.rs | 20 ++++++++++++++++++++ src/rsnmplib/mod.rs | 18 +++++++++--------- src/rsnmplib/snmp.rs | 4 ++-- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/rsnmplib/filesum.rs b/src/rsnmplib/filesum.rs index 16fb339..fe5a606 100644 --- a/src/rsnmplib/filesum.rs +++ b/src/rsnmplib/filesum.rs @@ -8,9 +8,9 @@ use std::path::Path; pub(crate) fn filesum_filtered( path: &Path, - oldfile: &mut String, + oldfile: &mut Vec, diff_string: &mut String, - re: Option<®ex::Regex>, + re: Option<®ex::bytes::Regex>, ) -> io::Result<(bool, String)> { // Open file for hashing match re { @@ -18,30 +18,37 @@ pub(crate) fn filesum_filtered( None => trace!("try to open file {:?} for hashing", path), } let mut hasher = Sha3_256::new(); - let mut filedata = String::with_capacity(2048); + let mut filedata = Vec::with_capacity(2048); let mut changed = false; // we read only smal files, so its fast to read the whole file to memory, so we can also du a diff - if let Ok(file_contents) = fs::read_to_string(path) { + if let Ok(file_contents) = fs::read(path) { if let Some(re) = re { trace!("Filter lines with regex {:?}", re); - for line in file_contents.lines() { + for line in file_contents.split_inclusive(|&b| b == b'\n') { if re.is_match(line) { - trace!("line {} skipped by filter regex", line); + trace!("line {} skipped by filter regex", String::from_utf8_lossy(line).trim()); continue; } // Update the hasher with the bytes - filedata.push_str(line); + filedata.extend_from_slice(line); } } else { // we do not have a filter regex, so we could simply paste the file to the hasher trace!("Hash file without filter regex"); filedata = file_contents; } - hasher.update(format!("{}\n", filedata).as_bytes()); + + // Debug to find errors + //trace!("Hasher input data {:?}",String::from_utf8_lossy(&filedata)); + + // Update the hasher with the bytes + hasher.update(&filedata); if !oldfile.is_empty() && *oldfile != filedata { diff_string.clear(); - for diff in diff::lines(oldfile, &filedata) { + let ofs = String::from_utf8_lossy(oldfile); + let nfs = String::from_utf8_lossy(&filedata); + for diff in diff::lines(&ofs, &nfs) { match diff { Result::Left(l) => { trace!("Diff - {}", l); // Removed line diff --git a/src/rsnmplib/helper.rs b/src/rsnmplib/helper.rs index f2bf7d1..bfa5d8f 100644 --- a/src/rsnmplib/helper.rs +++ b/src/rsnmplib/helper.rs @@ -1,5 +1,6 @@ use log::{debug, error, info}; use regex::Regex; +use regex::bytes::Regex as BRegex; pub(crate) fn compile_re(regex: Option, name: &str) -> Option { if let Some(r) = regex { @@ -19,3 +20,22 @@ pub(crate) fn compile_re(regex: Option, name: &str) -> Option { None } } + +pub(crate) fn compile_re_bin(regex: Option, name: &str) -> Option { + if let Some(r) = regex { + let re = BRegex::new(&r); + match re { + Ok(r) => { + debug!("Sucessfull compiled {} filter regex: {:?}", name, r); + Some(r) + } + Err(e) => { + error!("Error compiling {} filter regex: {:?}", name, e); + None + } + } + } else { + info!("No filter regex for {} supplied", name); + None + } +} diff --git a/src/rsnmplib/mod.rs b/src/rsnmplib/mod.rs index 4c620fa..9a31435 100644 --- a/src/rsnmplib/mod.rs +++ b/src/rsnmplib/mod.rs @@ -19,7 +19,7 @@ pub mod snmp; use bonding::bonding_status; use config::DataFunctionsFilesum; use filesum::filesum_filtered; -use helper::compile_re; +use helper::{compile_re, compile_re_bin}; use multipath::multipath_status; use processes::Ptypes; use snmp::{Oid, OidData, SnmpData}; @@ -189,10 +189,10 @@ fn t_filesum( #[cfg(target_os = "linux")] { // allocate some strings for holding file contents between check runs - let mut oldpasswd = String::with_capacity(2048); - let mut oldshadow = String::with_capacity(2048); - let mut oldgroup = String::with_capacity(2048); - let mut oldauthkey = String::with_capacity(2048); + let mut oldpasswd = Vec::with_capacity(2048); + let mut oldshadow = Vec::with_capacity(2048); + let mut oldgroup = Vec::with_capacity(2048); + let mut oldauthkey = Vec::with_capacity(2048); let mut hash_passwd = String::with_capacity(128); let mut diff_passwd = String::with_capacity(2048); let mut hash_shadow = String::with_capacity(128); @@ -203,10 +203,10 @@ fn t_filesum( let mut diff_authkey = String::with_capacity(2048); // allocate Option for our regex ... - let re_passwd = compile_re(options.passwd, "passwd"); - let re_shadow = compile_re(options.shadow, "shadow"); - let re_group = compile_re(options.group, "group"); - let re_authkey = compile_re(options.authorized_keys, "authorized_keys"); + let re_passwd = compile_re_bin(options.passwd, "passwd"); + let re_shadow = compile_re_bin(options.shadow, "shadow"); + let re_group = compile_re_bin(options.group, "group"); + let re_authkey = compile_re_bin(options.authorized_keys, "authorized_keys"); // prepare variables which we use in the whole function let oid_filesum_time = Oid::from_str("6.1.0").unwrap(); diff --git a/src/rsnmplib/snmp.rs b/src/rsnmplib/snmp.rs index 87a36d0..ea72328 100644 --- a/src/rsnmplib/snmp.rs +++ b/src/rsnmplib/snmp.rs @@ -49,7 +49,7 @@ impl Oid { x } -/* pub fn add_suffix(&self, o: &Oid) -> Oid { + /* pub fn add_suffix(&self, o: &Oid) -> Oid { let mut x = self.clone(); x.0.extend(o.clone().0); x @@ -111,7 +111,7 @@ pub struct OidData { } impl OidData { - /* + /* pub fn new(base_oid: &str) -> Self { Self { base: base_oid.parse().expect("Unable to parse Oid"),