From 53e5c929ca1b6e4de24bc0706d646f2b15d5c913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodolphe=20Br=C3=A9ard?= Date: Sun, 20 Dec 2020 14:34:30 +0100 Subject: [PATCH] Render a pretty hexdump in the logs --- Cargo.toml | 1 + src/error.rs | 27 +++++++++++++++++++++++++++ src/io.rs | 3 ++- src/lib.rs | 1 + src/parsers/parameters.rs | 7 +------ src/process.rs | 3 ++- 6 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 src/error.rs diff --git a/Cargo.toml b/Cargo.toml index 1f21a69..41bf345 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ include = ["src/**/*", "Cargo.toml", "LICENSE-*.txt"] [dependencies] log = "0.4" nom = "6.0" +pretty-hex = "0.2" [dev-dependencies] simplelog = "0.8" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..0efb99f --- /dev/null +++ b/src/error.rs @@ -0,0 +1,27 @@ +use nom::error::Error; +use nom::Err; +use pretty_hex::pretty_hex; + +fn error_to_string(e: Error<&[u8]>) -> String { + format!( + "parsing error: {:?}: input:{}", + e.code, + get_pretty_hex(&e.input) + ) +} + +pub(crate) fn get_pretty_hex(input: &[u8]) -> String { + let mut s = String::new(); + for l in pretty_hex(&input).split('\n') { + s += &format!("\n{}", l); + } + s +} + +pub(crate) fn nom_err_to_string(e: Err>) -> String { + match e { + Err::Incomplete(_) => e.to_string(), + Err::Error(er) => error_to_string(er), + Err::Failure(er) => error_to_string(er), + } +} diff --git a/src/io.rs b/src/io.rs index 4c6ebee..f1cd3c1 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,3 +1,4 @@ +use crate::error::get_pretty_hex; use std::io::{self, ErrorKind, Read}; use std::sync::mpsc::Sender; @@ -34,7 +35,7 @@ fn do_read_stdin(tx: &Sender>) -> Result<(), String> { let pos = id + 1; let mut line = Vec::with_capacity(pos); line.extend_from_slice(&line_buffer[..pos]); - log::trace!("new line: {:?}", &line); + log::trace!("new line:{}", get_pretty_hex(&line)); tx.send(line).unwrap(); line_buffer.drain(..pos); } diff --git a/src/lib.rs b/src/lib.rs index bc95e95..3958537 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,6 +45,7 @@ mod data_line; mod data_structures; +mod error; mod filter; mod io; mod parsers; diff --git a/src/parsers/parameters.rs b/src/parsers/parameters.rs index c6eaa83..9018250 100644 --- a/src/parsers/parameters.rs +++ b/src/parsers/parameters.rs @@ -339,12 +339,7 @@ mod tests { #[test] fn test_invalid_parse_filter_auth() { - let test_vectors = vec![ - "|\n", - "|\r\n", - "|derp", - "|derp|derpson\n", - ]; + let test_vectors = vec!["|\n", "|\r\n", "|derp", "|derp|derpson\n"]; for test in test_vectors { let res = parse_filter_auth(test.as_bytes()); assert!(!res.is_ok()); diff --git a/src/process.rs b/src/process.rs index f7c7496..d63431c 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,3 +1,4 @@ +use crate::error::nom_err_to_string; use crate::parsers::entry::{parse_entry, EntryOption}; use crate::parsers::parameters::{ parse_filter_auth, parse_filter_connect, parse_filter_data_line, parse_filter_ehlo, @@ -147,7 +148,7 @@ pub(crate) fn line(user_object: &mut T, input: &[u8]) -> Result<(), String> where T: Filter, { - let (input, entry) = parse_entry(input).map_err(|e| e.to_string())?; + let (input, entry) = parse_entry(input).map_err(nom_err_to_string)?; match entry { EntryOption::Report(r) => handle_reports!(user_object, r, input), EntryOption::Filter(f) => {