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).