Render a pretty hexdump in the logs

This commit is contained in:
Rodolphe Bréard 2020-12-20 14:34:30 +01:00
parent f7edffc6cc
commit 53e5c929ca
6 changed files with 34 additions and 8 deletions

View file

@ -14,6 +14,7 @@ include = ["src/**/*", "Cargo.toml", "LICENSE-*.txt"]
[dependencies] [dependencies]
log = "0.4" log = "0.4"
nom = "6.0" nom = "6.0"
pretty-hex = "0.2"
[dev-dependencies] [dev-dependencies]
simplelog = "0.8" simplelog = "0.8"

27
src/error.rs Normal file
View file

@ -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<Error<&[u8]>>) -> String {
match e {
Err::Incomplete(_) => e.to_string(),
Err::Error(er) => error_to_string(er),
Err::Failure(er) => error_to_string(er),
}
}

View file

@ -1,3 +1,4 @@
use crate::error::get_pretty_hex;
use std::io::{self, ErrorKind, Read}; use std::io::{self, ErrorKind, Read};
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
@ -34,7 +35,7 @@ fn do_read_stdin(tx: &Sender<Vec<u8>>) -> Result<(), String> {
let pos = id + 1; let pos = id + 1;
let mut line = Vec::with_capacity(pos); let mut line = Vec::with_capacity(pos);
line.extend_from_slice(&line_buffer[..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(); tx.send(line).unwrap();
line_buffer.drain(..pos); line_buffer.drain(..pos);
} }

View file

@ -45,6 +45,7 @@
mod data_line; mod data_line;
mod data_structures; mod data_structures;
mod error;
mod filter; mod filter;
mod io; mod io;
mod parsers; mod parsers;

View file

@ -339,12 +339,7 @@ mod tests {
#[test] #[test]
fn test_invalid_parse_filter_auth() { fn test_invalid_parse_filter_auth() {
let test_vectors = vec![ let test_vectors = vec!["|\n", "|\r\n", "|derp", "|derp|derpson\n"];
"|\n",
"|\r\n",
"|derp",
"|derp|derpson\n",
];
for test in test_vectors { for test in test_vectors {
let res = parse_filter_auth(test.as_bytes()); let res = parse_filter_auth(test.as_bytes());
assert!(!res.is_ok()); assert!(!res.is_ok());

View file

@ -1,3 +1,4 @@
use crate::error::nom_err_to_string;
use crate::parsers::entry::{parse_entry, EntryOption}; use crate::parsers::entry::{parse_entry, EntryOption};
use crate::parsers::parameters::{ use crate::parsers::parameters::{
parse_filter_auth, parse_filter_connect, parse_filter_data_line, parse_filter_ehlo, parse_filter_auth, parse_filter_connect, parse_filter_data_line, parse_filter_ehlo,
@ -147,7 +148,7 @@ pub(crate) fn line<T>(user_object: &mut T, input: &[u8]) -> Result<(), String>
where where
T: Filter, 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 { match entry {
EntryOption::Report(r) => handle_reports!(user_object, r, input), EntryOption::Report(r) => handle_reports!(user_object, r, input),
EntryOption::Filter(f) => { EntryOption::Filter(f) => {