From 11aa5935bc7edcc5d22e3f916b03d316e6e2ea80 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 22 Apr 2025 14:20:12 -0300 Subject: [PATCH] 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. --- stdlib/strtod_l.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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; } -- 2.47.2