JsonStreamWriter::fp_number_value writes a large-magnitude f64 as a plain-decimal number with more than 100 characters. JsonStreamReader with default settings rejects any number whose text is longer than 100 characters or whose exponent exceeds 99, so a value the writer produced cannot be read back by a reader from the same crate with default settings.
Reproduced on struson 0.7.2 from crates.io, default features.
Reproducer
use struson::reader::{JsonReader, JsonStreamReader};
use struson::writer::{JsonStreamWriter, JsonWriter};
fn main() {
let mut buf: Vec<u8> = Vec::new();
let mut w = JsonStreamWriter::new(&mut buf);
w.fp_number_value(1e100_f64).unwrap();
w.finish_document().unwrap();
let s = String::from_utf8(buf).unwrap();
println!("written length = {}", s.len());
let mut r = JsonStreamReader::new(s.as_bytes());
let read: Result<Result<f64, _>, _> = r.next_number::<f64>();
println!("read back = {:?}", read);
}
Observed
written length = 101
read back = Err(unsupported number value '100000...000' at path '$')
fp_number_value calls to_string on the f64, and 1e100_f64.to_string() is a 101-character plain-decimal string. The default reader returns ReaderError::UnsupportedNumberValue for it. Larger magnitudes such as 5e120 behave the same way.
Expected
A finite f64 written by the crate's own writer with default settings can be read back by the crate's own reader with default settings. Either the writer emits scientific notation for large magnitudes so the text stays short, or the writer and the default reader agree on the same size bound.
Scope
A pipeline that serializes with JsonStreamWriter and later reads with JsonStreamReader, both at defaults, fails on ordinary large f64 values such as physics or finance magnitudes at or above 1e100. The failure surfaces only at read time and only for large inputs, so it is easy to miss in testing.
Root cause
fp_number_value for a finite float uses self.to_string() (src/writer/mod.rs around line 779), which never uses scientific notation and grows without bound for large magnitudes. The default reader sets restrict_number_values: true (src/reader/stream_reader.rs around line 366), which rejects text longer than 100 characters or an exponent above 99. The two defaults disagree on the same value.
JsonStreamWriter::fp_number_valuewrites a large-magnitudef64as a plain-decimal number with more than 100 characters.JsonStreamReaderwith default settings rejects any number whose text is longer than 100 characters or whose exponent exceeds 99, so a value the writer produced cannot be read back by a reader from the same crate with default settings.Reproduced on struson 0.7.2 from crates.io, default features.
Reproducer
Observed
fp_number_valuecallsto_stringon thef64, and1e100_f64.to_string()is a 101-character plain-decimal string. The default reader returnsReaderError::UnsupportedNumberValuefor it. Larger magnitudes such as5e120behave the same way.Expected
A finite
f64written by the crate's own writer with default settings can be read back by the crate's own reader with default settings. Either the writer emits scientific notation for large magnitudes so the text stays short, or the writer and the default reader agree on the same size bound.Scope
A pipeline that serializes with
JsonStreamWriterand later reads withJsonStreamReader, both at defaults, fails on ordinary largef64values such as physics or finance magnitudes at or above1e100. The failure surfaces only at read time and only for large inputs, so it is easy to miss in testing.Root cause
fp_number_valuefor a finite float usesself.to_string()(src/writer/mod.rsaround line 779), which never uses scientific notation and grows without bound for large magnitudes. The default reader setsrestrict_number_values: true(src/reader/stream_reader.rsaround line 366), which rejects text longer than 100 characters or an exponent above 99. The two defaults disagree on the same value.