From: Adhemerval Zanella Date: Tue, 22 Apr 2025 17:20:12 +0000 (-0300) Subject: stdlib: Fix UB on strtod X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11aa5935bc7edcc5d22e3f916b03d316e6e2ea80;p=thirdparty%2Fglibc.git stdlib: Fix UB on strtod With glibc built with ubsan it triggers: UBSAN: Undefined behaviour in strtod_l.c:1580:8 shift exponent 41 is too large for 32-bit type 'int' Use the correct constant literal definition based on mp_limb_t size. --- diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index f9572b9ebf..06a93e2afe 100644 --- a/stdlib/strtod_l.c +++ b/stdlib/strtod_l.c @@ -150,9 +150,11 @@ extern FLOAT MPN2FLOAT (mp_srcptr mpn, int exponent, int negative); #if BITS_PER_MP_LIMB == 32 # define MAX_DIG_PER_LIMB 9 # define MAX_FAC_PER_LIMB 1000000000UL +# define SHIFT_CTE(N) N # U #elif BITS_PER_MP_LIMB == 64 # define MAX_DIG_PER_LIMB 19 # define MAX_FAC_PER_LIMB 10000000000000000000ULL +# define SHIFT_CTE(N) N ## UL #else # error "mp_limb_t size " BITS_PER_MP_LIMB "not accounted for" #endif @@ -1572,12 +1574,13 @@ ____STRTOF_INTERNAL (const STRING_TYPE *nptr, STRING_TYPE **endptr, int group, { if (bits + BITS_PER_MP_LIMB <= MANT_DIG) __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, - BITS_PER_MP_LIMB, 0); + BITS_PER_MP_LIMB, SHIFT_CTE (0)); else { used = MANT_DIG - bits; if (used > 0) - __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0); + __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, + SHIFT_CTE (0)); } bits += BITS_PER_MP_LIMB; }