Skip to content

Commit

Permalink
Merge pull request #49645 from ClickHouse/fix-one-off-error
Browse files Browse the repository at this point in the history
Fix one-off error in big integers found by UBSan with fuzzer
  • Loading branch information
davenger committed May 8, 2023
2 parents 5629d73 + 8482cf0 commit 6f76c27
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
9 changes: 8 additions & 1 deletion base/base/wide_integer_impl.h
Expand Up @@ -314,7 +314,14 @@ struct integer<Bits, Signed>::_impl

const T alpha = t / static_cast<T>(max_int);

if (alpha <= static_cast<T>(max_int))
/** Here we have to use strict comparison.
* The max_int is 2^64 - 1.
* When casted to floating point type, it will be rounded to the closest representable number,
* which is 2^64.
* But 2^64 is not representable in uint64_t,
* so the maximum representable number will be strictly less.
*/
if (alpha < static_cast<T>(max_int))
self = static_cast<uint64_t>(alpha);
else // max(double) / 2^64 will surely contain less than 52 precision bits, so speed up computations.
set_multiplier<double>(self, static_cast<double>(alpha));
Expand Down
@@ -0,0 +1 @@
1 1
9 changes: 9 additions & 0 deletions tests/queries/0_stateless/02734_big_int_from_float_ubsan.sql
@@ -0,0 +1,9 @@
WITH
18 AS precision,
toUInt256(-1) AS int,
toUInt256(toFloat64(int)) AS converted,
toString(int) AS int_str,
toString(converted) AS converted_str
SELECT
length(int_str) = length(converted_str) AS have_same_length,
substring(int_str, 1, precision) = substring(converted_str, 1, precision) AS have_same_prefix

0 comments on commit 6f76c27

Please sign in to comment.