]> Savannah Git Hosting - gnulib.git/commitdiff
xalloc-oversized: check for PTRDIFF_MAX too
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 15 Dec 2016 01:09:04 +0000 (17:09 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 15 Dec 2016 18:19:48 +0000 (10:19 -0800)
This avoids undefined behavior when subtracting pointers to
objects containing more than PTRDIFF_MAX bytes.
* lib/xalloc-oversized.h (__xalloc_oversized, xalloc_oversized):
Also return 1 if the result would exceed PTRDIFF_MAX>
* modules/xalloc-oversized (Depends-on):
Add stdint.

ChangeLog
lib/xalloc-oversized.h
modules/xalloc-oversized

index b7091c116db503998edeb3c919c95c6569471134..767e0c714e5c9c6c398e4e502a4876dbd8f75fd7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2016-12-14  Paul Eggert  <eggert@cs.ucla.edu>
 
+       xalloc-oversized: check for PTRDIFF_MAX too
+       This avoids undefined behavior when subtracting pointers to
+       objects containing more than PTRDIFF_MAX bytes.
+       * lib/xalloc-oversized.h (__xalloc_oversized, xalloc_oversized):
+       Also return 1 if the result would exceed PTRDIFF_MAX>
+       * modules/xalloc-oversized (Depends-on):
+       Add stdint.
+
        dfa: fix glitches in previous commit
        Sorry, I don't know how I managed to commit the wrong version.
        * lib/dfa.c (MIN): Move up.
index 53e6556c6108cfdf63db3d46393bfd02b39ecfda..503bb37801b22d50b703e6db0d47d1f9834c0610 100644 (file)
 #define XALLOC_OVERSIZED_H_
 
 #include <stddef.h>
+#include <stdint.h>
 
 /* Default for (non-Clang) compilers that lack __has_builtin.  */
 #ifndef __has_builtin
 # define __has_builtin(x) 0
 #endif
 
-/* True if N * S would overflow in a size calculation.
+/* True if N * S would overflow in a size_t calculation,
+   or would generate a value larger than PTRDIFF_MAX.
    This expands to a constant expression if N and S are both constants.
    By gnulib convention, SIZE_MAX represents overflow in size
-   calculations, so the conservative dividend to use here is
-   SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
-   However, malloc (SIZE_MAX) fails on all known hosts where
-   sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
-   exactly-SIZE_MAX allocations on such hosts; this avoids a test and
-   branch when S is known to be 1.  */
+   calculations, so the conservative size_t-based dividend to use here
+   is SIZE_MAX - 1.  */
 #define __xalloc_oversized(n, s) \
-    ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
+  ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
 
+#if PTRDIFF_MAX < SIZE_MAX
+typedef ptrdiff_t __xalloc_count_type;
+#else
+typedef size_t __xalloc_count_type;
+#endif
 
-/* Return 1 if an array of N objects, each of size S, cannot exist due
-   to size arithmetic overflow.  S must be positive and N must be
-   nonnegative.  This is a macro, not a function, so that it
-   works correctly even when SIZE_MAX < N.  */
+/* Return 1 if an array of N objects, each of size S, cannot exist
+   reliably due to size or ptrdiff_t arithmetic overflow.  S must be
+   positive and N must be nonnegative.  This is a macro, not a
+   function, so that it works correctly even when SIZE_MAX < N.  */
 
 #if 7 <= __GNUC__ || __has_builtin (__builtin_add_overflow_p)
-# define xalloc_oversized(n, s) __builtin_mul_overflow_p (n, s, (size_t) 1)
+# define xalloc_oversized(n, s) \
+   __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
 #elif ((5 <= __GNUC__ \
         || (__has_builtin (__builtin_mul_overflow) \
             && __has_builtin (__builtin_constant_p))) \
@@ -52,7 +56,8 @@
 # define xalloc_oversized(n, s) \
    (__builtin_constant_p (n) && __builtin_constant_p (s) \
     ? __xalloc_oversized (n, s) \
-    : ({ size_t __xalloc_size; __builtin_mul_overflow (n, s, &__xalloc_size); }))
+    : ({ __xalloc_count_type __xalloc_count; \
+         __builtin_mul_overflow (n, s, &__xalloc_count); }))
 
 /* Other compilers use integer division; this may be slower but is
    more portable.  */
index 7f9bd18f17cd59c6999abb9e47174e0be58b3361..84f66de152ffad3463813c5e95dd04c61324d5d3 100644 (file)
@@ -5,6 +5,7 @@ Files:
 lib/xalloc-oversized.h
 
 Depends-on:
+stdint
 
 configure.ac: