aldanor / fast-float-rust

Super-fast float parser in Rust (now part of Rust core)
https://docs.rs/fast-float
Apache License 2.0
275 stars 20 forks source link

Fix Undefined Behavior in `check_len` #28

Closed Alexhuszagh closed 3 years ago

Alexhuszagh commented 3 years ago

Comparison between pointers that do no reference the same array (or 1-past the end of the array) is undefined behavior. Quoting the Rust documentation:

If any of the following conditions are violated, the result is Undefined Behavior:

  • Both the starting and resulting pointer must be either in bounds or one byte past the end of the same allocated object.
  • The computed offset, in bytes, cannot overflow an isize.
  • The offset being in bounds cannot rely on “wrapping around” the address space. That is, the infinite-precision sum must fit in a usize.

Likewise, quoting the LLVM Language Reference:

This value only has defined behavior when used as an operand to the ‘indirectbr’ or ‘callbr’instruction, or for comparisons against null. Pointer equality tests between labels addresses results in undefined behavior — though, again, comparison against null is ok, and no label is equal to the null pointer. This may be passed around as an opaque pointer sized value as long as the bits are not inspected. This allows ptrtoint and arithmetic to be performed on these values so long as the original value is reconstituted before the indirectbr or callbr instruction.

Therefore, the following code is undefined behavior. This should likely justify a new version release once this is published.

https://github.com/aldanor/fast-float-rust/blob/ec1b7d4ff98dc177b1f507e53c0f39a611542811/src/common.rs#L76-L79

aldanor commented 3 years ago

Thanks for detailed investigation and the fix - this was UB indeed (perhaps not immediately obvious).