From: Jason Ish Date: Fri, 16 Jun 2017 05:38:04 +0000 (-0600) Subject: rust/json: only output printable characters X-Git-Tag: suricata-4.0.0-rc1~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dbc5be4beaeb7fed9b2c4dc39ff999ec3eb2f04;p=thirdparty%2Fsuricata.git rust/json: only output printable characters Rust strings are UTF8 and we cannot yet rely on jansson having json_stringn on all supported OS distributions yet so sanitize strings to ascii before printing. Also add set_string_from_bytes which is like set_string, but accepts a byte array as input. --- diff --git a/rust/src/json.rs b/rust/src/json.rs index 0ac4d04bad..4f9af2f11a 100644 --- a/rust/src/json.rs +++ b/rust/src/json.rs @@ -68,11 +68,19 @@ impl Json { } } + pub fn set_string_from_bytes(&self, key: &str, val: &[u8]) { + unsafe { + json_object_set_new(self.js, + CString::new(key).unwrap().as_ptr(), + json_string(to_cstring(val).as_ptr())); + } + } + pub fn set_string(&self, key: &str, val: &str) { - unsafe{ + unsafe { json_object_set_new(self.js, CString::new(key).unwrap().as_ptr(), - json_string(CString::new(val).unwrap().as_ptr())); + json_string(to_cstring(val.as_bytes()).as_ptr())); } } @@ -98,3 +106,43 @@ impl Json { } } } + +/// Convert an array of bytes into an ascii printable string replacing +/// non-printable characters (including NULL) with hex value. +/// +/// Newer versions of Jansson have a json_stringn that will allow us +/// to create a string out of a byte array of unicode compliant bytes, +/// but until we can use it across all platforms this is probably the +/// best we can do. +fn to_cstring(val: &[u8]) -> CString { + let mut safe = Vec::with_capacity(val.len()); + for c in val { + if *c == 0 || *c > 0x7f { + safe.extend(format!("\\x{:02x}", *c).as_bytes()); + } else { + safe.push(*c); + } + } + match CString::new(safe) { + Ok(cstr) => cstr, + _ => { + CString::new("").unwrap() + } + } +} + +#[cfg(test)] +mod tests { + + use json::to_cstring; + + #[test] + fn test_to_string() { + assert_eq!("A\\x00A", + to_cstring(&[0x41, 0x00, 0x41]).into_string().unwrap()); + assert_eq!("", to_cstring(&[]).into_string().unwrap()); + assert_eq!("\\x80\\xf1\\xf2\\xf3", + to_cstring(&[0x80, 0xf1, 0xf2, 0xf3]).into_string().unwrap()); + } + +}