jsonbuilder: fix serialization of nan and inf

When outputting a float, check if its infinity, or not a number and
output a null instead.

Using a null was chosen as this is what serde_yaml, Firefox, Chrome,
Node, etc. do.

Ticket: #6921
pull/10774/head
Jason Ish 2 years ago
parent b224209f45
commit 71f59e529c

@ -1,4 +1,4 @@
/* Copyright (C) 2020 Open Information Security Foundation
/* Copyright (C) 2020-2024 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
@ -435,7 +435,7 @@ impl JsonBuilder {
return Err(JsonError::InvalidState);
}
}
self.push_str(&val.to_string())?;
self.push_float(val)?;
Ok(self)
}
@ -650,7 +650,7 @@ impl JsonBuilder {
self.push('"')?;
self.push_str(key)?;
self.push_str("\":")?;
self.push_str(&val.to_string())?;
self.push_float(val)?;
Ok(self)
}
@ -681,6 +681,15 @@ impl JsonBuilder {
self.buf.capacity()
}
fn push_float(&mut self, val: f64) -> Result<(), JsonError> {
if val.is_nan() || val.is_infinite() {
self.push_str("null")?;
} else {
self.push_str(&val.to_string())?;
}
Ok(())
}
/// Encode a string into the buffer, escaping as needed.
///
/// The string is encoded into an intermediate vector as its faster
@ -1339,6 +1348,48 @@ mod test {
jb.close().unwrap();
assert_eq!(jb.buf, r#"[1.1,2.2]"#);
}
#[test]
fn test_set_nan() {
let mut jb = JsonBuilder::try_new_object().unwrap();
jb.set_float("nan", f64::NAN).unwrap();
jb.close().unwrap();
assert_eq!(jb.buf, r#"{"nan":null}"#);
}
#[test]
fn test_append_nan() {
let mut jb = JsonBuilder::try_new_array().unwrap();
jb.append_float(f64::NAN).unwrap();
jb.close().unwrap();
assert_eq!(jb.buf, r#"[null]"#);
}
#[test]
fn test_set_inf() {
let mut jb = JsonBuilder::try_new_object().unwrap();
jb.set_float("inf", f64::INFINITY).unwrap();
jb.close().unwrap();
assert_eq!(jb.buf, r#"{"inf":null}"#);
let mut jb = JsonBuilder::try_new_object().unwrap();
jb.set_float("inf", f64::NEG_INFINITY).unwrap();
jb.close().unwrap();
assert_eq!(jb.buf, r#"{"inf":null}"#);
}
#[test]
fn test_append_inf() {
let mut jb = JsonBuilder::try_new_array().unwrap();
jb.append_float(f64::INFINITY).unwrap();
jb.close().unwrap();
assert_eq!(jb.buf, r#"[null]"#);
let mut jb = JsonBuilder::try_new_array().unwrap();
jb.append_float(f64::NEG_INFINITY).unwrap();
jb.close().unwrap();
assert_eq!(jb.buf, r#"[null]"#);
}
}
// Escape table as seen in serde-json (MIT/Apache license)

Loading…
Cancel
Save