veeso / range-parser

A rust library to parse ranges representation of any kind of numbers
MIT License
2 stars 1 forks source link

Float range parsing is buggy #1

Open AnthonyMikh opened 3 months ago

AnthonyMikh commented 3 months ago

Since floating point numbers have finite number of bits for mantissa, for very large numbers adding one does not change number:

let x = (1_u64 << f32::MANTISSA_DIGITS) as f32;
assert_eq!(x + 1.0, x); // passes

Since you add ones in order to make up a range, if the range happens to contains such a number, the loop for collecting numbers can never stop. For example, the following code in theory runs indefinitely (in practice it hangs the computer):

let lo = (1_u64 << f32::MANTISSA_DIGITS) as f32;
let hi = lo + hi;
range_parser::parse::<f32>(&format!("{lo}-{hi}"));

Of course, the special values (negative and positive infinity, NaN) exhibit the same property. If start number of a range happens to be parsed as negative infinity, it also makes the loop run indefinitely:

// -1e666 is smaller than the smallest finite number representable in f32,
// so it parses as negative infinity
range_parser::parse::<f32>(&format!("-1e666-0"));
veeso commented 3 months ago

Hi thanks for reporting this. I don't exactly know what should be done though. I mean I could implement some checks:

I mean this could indeed be part of a backend and a user input could hang the server, but usually float is not used in ranges, indeed I wasn't even sure whether to implement it.

But yeah, if a backend accepts the user input as float, this could lead to a security issue, but I'm not sure about the best solution here.

What do you suggest?