Remove dependency on `lexical`
There are soundness issues in the lexical crate. This warning from deny includes explanations of the soundness issues and recommendations for how to get similar functionality without the lexical crate.
From a brief look at the code, it appears that we only use the lexical crate to format floating-point numbers; however, the deny recommendation does not recommend anything for this use-case. One crate that may provide what we need is numfmt.
warning[unsound]: Multiple soundness issues
┌─ /github/workspace/Cargo.lock:70:1 │ 70 │ lexical 6.1.1 registry+https://github.com/rust-lang/crates.io-index │ ------------------------------------------------------------------- unsound advisory detected │= ID: RUSTSEC-2023-0055 = Advisory: https://rustsec.org/advisories/RUSTSEC-2023-0055 =
lexicalcontains multiple soundness issues:
- Bytes::read() allows creating instances of types with invalid bit patterns
- BytesIter::read() advances iterators out of bounds
- The
BytesItertrait has safety invariants but is public and not markedunsafewrite_float()callsMaybeUninit::assume_init()on uninitialized data, which is is not allowed by the Rust abstract machineThe crate also has some correctness issues and appears to be unmaintained.
Alternatives
For quickly parsing floating-point numbers third-party crates are no longer needed. A fast float parsing algorith by the author of
lexicalhas been merged into libcore.For quickly parsing integers, consider
atoiandbtoicrates (100% safe code).atoi_radix10provides even faster parsing, but only with-C target-cpu=native, and at the cost of someunsafe.For formatting integers in a
#[no_std]context consider thenumtoacrate.For working with big numbers consider
num-bigintandnum-traits.
For more context, this appears to be the only function that uses lexical, so it should be fairly straightforward to replace