Module Name: src Committed By: martin Date: Sun Oct 13 15:00:10 UTC 2024
Modified Files: src/lib/libc/compat/gen [netbsd-9]: compat_ldexp_ieee754.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #1905): lib/libc/compat/gen/compat_ldexp_ieee754.c: revision 1.9 libc ldexp(3): Avoid undefined behaviour in arithmetic overflow. PR lib/58347 To generate a diff of this commit: cvs rdiff -u -r1.7.16.1 -r1.7.16.2 \ src/lib/libc/compat/gen/compat_ldexp_ieee754.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/compat/gen/compat_ldexp_ieee754.c diff -u src/lib/libc/compat/gen/compat_ldexp_ieee754.c:1.7.16.1 src/lib/libc/compat/gen/compat_ldexp_ieee754.c:1.7.16.2 --- src/lib/libc/compat/gen/compat_ldexp_ieee754.c:1.7.16.1 Mon May 25 15:26:05 2020 +++ src/lib/libc/compat/gen/compat_ldexp_ieee754.c Sun Oct 13 15:00:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: compat_ldexp_ieee754.c,v 1.7.16.1 2020/05/25 15:26:05 martin Exp $ */ +/* $NetBSD: compat_ldexp_ieee754.c,v 1.7.16.2 2024/10/13 15:00:10 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: compat_ldexp_ieee754.c,v 1.7.16.1 2020/05/25 15:26:05 martin Exp $"); +__RCSID("$NetBSD: compat_ldexp_ieee754.c,v 1.7.16.2 2024/10/13 15:00:10 martin Exp $"); #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -115,17 +115,31 @@ ldexp(double val, int expon) /* * u.v is now normalized and oldexp has been adjusted if necessary. - * Calculate the new exponent and check for underflow and overflow. + * We have + * + * 0 <= oldexp <= DBL_EXP_INFNAN, + * + * but + * + * INT_MIN <= expon <= INT_MAX. + * + * Check for underflow and overflow, and if none, calculate the + * new exponent. */ - newexp = oldexp + expon; - - if (newexp >= DBL_EXP_INFNAN || - (oldexp >= 0 && expon >= DBL_EXP_INFNAN)) { + if (expon >= DBL_EXP_INFNAN - oldexp) { /* * The result overflowed; return +/-Inf. */ return overflow(val); - } else if (newexp <= 0) { + } + + /* + * We now have INT_MIN <= oldexp + expon <= DBL_EXP_INFNAN <= INT_MAX, + * so the arithmetic is safe. + */ + newexp = oldexp + expon; + + if (newexp <= 0) { /* * The output number is either denormal or underflows (see * comments in machine/ieee.h).