From 60eb5305f637e21f7ec4006924c06518ca6de476 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 19 May 2018 11:25:03 -0500 Subject: [PATCH] py/objfloat: Fix undefined shifting behavior in high-quality float hash. When computing e.g. hash(0.4e3) with ubsan enabled, a diagnostic like the following would occur: ../../py/objfloat.c:91:30: runtime error: shift exponent 44 is too large for 32-bit type 'int' By casting constant "1" to the right type the intended value is preserved. --- py/objfloat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/objfloat.c b/py/objfloat.c index e4d5a6570..31c624778 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -88,7 +88,7 @@ typedef uint32_t mp_float_uint_t; if (adj_exp <= MP_FLOAT_FRAC_BITS) { // number may have a fraction; xor the integer part with the fractional part val = (frc >> (MP_FLOAT_FRAC_BITS - adj_exp)) - ^ (frc & ((1 << (MP_FLOAT_FRAC_BITS - adj_exp)) - 1)); + ^ (frc & (((mp_float_uint_t)1 << (MP_FLOAT_FRAC_BITS - adj_exp)) - 1)); } else if ((unsigned int)adj_exp < BITS_PER_BYTE * sizeof(mp_int_t) - 1) { // the number is a (big) whole integer and will fit in val's signed-width val = (mp_int_t)frc << (adj_exp - MP_FLOAT_FRAC_BITS);