changeset 40214:452ab00796c7

Fix undefined behaviour. * lib/bitrotate.h (rotl16, rotr16, rotl8, rotr8): Case x to 'unsigned int', to avoid shift operations on 'int'. * lib/xmemdup0.c (xmemdup0): Don't invoke memcpy with a zero size. * tests/test-count-leading-zeros.c (main): Use a random number that has as many bits as TYPE, not only 2*15 or 2*31 bits. * tests/test-count-trailing-zeros.c (main): Likewise. * tests/test-count-one-bits.c (main): Likewise. * tests/test-memmem.c: Don't include "null-ptr.h". (main): Use zerosize_ptr() instead of null_ptr(). * modules/memmem-tests (Files): Remove tests/null-ptr.h.
author Bruno Haible <bruno@clisp.org>
date Sat, 09 Mar 2019 20:32:25 +0100
parents cc3fed3b7788
children 88b18d82fa61
files ChangeLog lib/bitrotate.h lib/xmemdup0.c modules/memmem-tests tests/test-count-leading-zeros.c tests/test-count-one-bits.c tests/test-count-trailing-zeros.c tests/test-memmem.c
diffstat 8 files changed, 106 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Mar 09 00:27:19 2019 +0100
+++ b/ChangeLog	Sat Mar 09 20:32:25 2019 +0100
@@ -1,3 +1,17 @@
+2019-03-09  Bruno Haible  <bruno@clisp.org>
+
+	Fix undefined behaviour.
+	* lib/bitrotate.h (rotl16, rotr16, rotl8, rotr8): Case x to
+	'unsigned int', to avoid shift operations on 'int'.
+	* lib/xmemdup0.c (xmemdup0): Don't invoke memcpy with a zero size.
+	* tests/test-count-leading-zeros.c (main): Use a random number that has
+	as many bits as TYPE, not only 2*15 or 2*31 bits.
+	* tests/test-count-trailing-zeros.c (main): Likewise.
+	* tests/test-count-one-bits.c (main): Likewise.
+	* tests/test-memmem.c: Don't include "null-ptr.h".
+	(main): Use zerosize_ptr() instead of null_ptr().
+	* modules/memmem-tests (Files): Remove tests/null-ptr.h.
+
 2019-03-08  Bruno Haible  <bruno@clisp.org>
 
 	unilbrk/u*-possible-linebreaks: Fix undefined behaviour.
--- a/lib/bitrotate.h	Sat Mar 09 00:27:19 2019 +0100
+++ b/lib/bitrotate.h	Sat Mar 09 20:32:25 2019 +0100
@@ -95,7 +95,8 @@
 BITROTATE_INLINE uint16_t
 rotl16 (uint16_t x, int n)
 {
-  return ((x << n) | (x >> (16 - n))) & UINT16_MAX;
+  return (((unsigned int) x << n) | ((unsigned int) x >> (16 - n)))
+         & UINT16_MAX;
 }
 
 /* Given an unsigned 16-bit argument X, return the value corresponding
@@ -106,7 +107,8 @@
 BITROTATE_INLINE uint16_t
 rotr16 (uint16_t x, int n)
 {
-  return ((x >> n) | (x << (16 - n))) & UINT16_MAX;
+  return (((unsigned int) x >> n) | ((unsigned int) x << (16 - n)))
+         & UINT16_MAX;
 }
 
 /* Given an unsigned 8-bit argument X, return the value corresponding
@@ -117,7 +119,7 @@
 BITROTATE_INLINE uint8_t
 rotl8 (uint8_t x, int n)
 {
-  return ((x << n) | (x >> (8 - n))) & UINT8_MAX;
+  return (((unsigned int) x << n) | ((unsigned int) x >> (8 - n))) & UINT8_MAX;
 }
 
 /* Given an unsigned 8-bit argument X, return the value corresponding
@@ -128,7 +130,7 @@
 BITROTATE_INLINE uint8_t
 rotr8 (uint8_t x, int n)
 {
-  return ((x >> n) | (x << (8 - n))) & UINT8_MAX;
+  return (((unsigned int) x >> n) | ((unsigned int) x << (8 - n))) & UINT8_MAX;
 }
 
 _GL_INLINE_HEADER_END
--- a/lib/xmemdup0.c	Sat Mar 09 00:27:19 2019 +0100
+++ b/lib/xmemdup0.c	Sat Mar 09 20:32:25 2019 +0100
@@ -38,7 +38,8 @@
 xmemdup0 (void const *p, size_t s)
 {
   char *result = xcharalloc (s + 1);
-  memcpy (result, p, s);
+  if (s > 0)
+    memcpy (result, p, s);
   result[s] = 0;
   return result;
 }
--- a/modules/memmem-tests	Sat Mar 09 00:27:19 2019 +0100
+++ b/modules/memmem-tests	Sat Mar 09 20:32:25 2019 +0100
@@ -1,7 +1,6 @@
 Files:
 tests/test-memmem.c
 tests/signature.h
-tests/null-ptr.h
 tests/zerosize-ptr.h
 tests/macros.h
 m4/mmap-anon.m4
--- a/tests/test-count-leading-zeros.c	Sat Mar 09 00:27:19 2019 +0100
+++ b/tests/test-count-leading-zeros.c	Sat Mar 09 20:32:25 2019 +0100
@@ -34,23 +34,34 @@
 {
   int i, j;
 
-#define TEST_COUNT_LEADING_ZEROS(FUNC, TYPE, BITS, MAX, ONE)    \
-  ASSERT (FUNC (0) == BITS);                                    \
-  for (i = 0; i < BITS; i++)                                    \
-    {                                                           \
-      ASSERT (FUNC (ONE << i) == BITS - i - 1);                 \
-      for (j = 0; j < i; j++)                                   \
-        ASSERT (FUNC ((ONE << i) | (ONE << j)) == BITS - i - 1);\
-    }                                                           \
-  for (i = 0; i < 1000; i++)                                    \
-    {                                                           \
-      TYPE value = rand () ^ (rand () << 31 << 1);              \
-      int count = 0;                                            \
-      for (j = 0; j < BITS; j++)                                \
-        if (value & (ONE << j))                                 \
-          count = BITS - j - 1;                                 \
-      ASSERT (count == FUNC (value));                           \
-    }                                                           \
+#define TEST_COUNT_LEADING_ZEROS(FUNC, TYPE, BITS, MAX, ONE)     \
+  ASSERT (FUNC (0) == BITS);                                     \
+  for (i = 0; i < BITS; i++)                                     \
+    {                                                            \
+      ASSERT (FUNC (ONE << i) == BITS - i - 1);                  \
+      for (j = 0; j < i; j++)                                    \
+        ASSERT (FUNC ((ONE << i) | (ONE << j)) == BITS - i - 1); \
+    }                                                            \
+  for (i = 0; i < 1000; i++)                                     \
+    {                                                            \
+      /* RAND_MAX is most often 0x7fff or 0x7fffffff.  */        \
+      TYPE value =                                               \
+        (RAND_MAX <= 0xffff                                      \
+         ? ((TYPE) rand () >> 3)                                 \
+           ^ (((TYPE) rand () >> 3) << 12)                       \
+           ^ (((TYPE) rand () >> 3) << 24)                       \
+           ^ (((TYPE) rand () >> 3) << 30 << 6)                  \
+           ^ (((TYPE) rand () >> 3) << 30 << 18)                 \
+           ^ (((TYPE) rand () >> 3) << 30 << 30)                 \
+         : ((TYPE) rand () >> 3)                                 \
+           ^ (((TYPE) rand () >> 3) << 22)                       \
+           ^ (((TYPE) rand () >> 3) << 22 << 22));               \
+      int count = 0;                                             \
+      for (j = 0; j < BITS; j++)                                 \
+        if (value & (ONE << j))                                  \
+          count = BITS - j - 1;                                  \
+      ASSERT (count == FUNC (value));                            \
+    }                                                            \
   ASSERT (FUNC (MAX) == 0);
 
   TEST_COUNT_LEADING_ZEROS (count_leading_zeros, unsigned int,
--- a/tests/test-count-one-bits.c	Sat Mar 09 00:27:19 2019 +0100
+++ b/tests/test-count-one-bits.c	Sat Mar 09 20:32:25 2019 +0100
@@ -34,22 +34,33 @@
 {
   int i, j;
 
-#define TEST_COUNT_ONE_BITS(FUNC, TYPE, BITS, MAX, ONE) \
-  ASSERT (FUNC (0) == 0);                               \
-  for (i = 0; i < BITS; i++)                            \
-    {                                                   \
-      ASSERT (FUNC (ONE << i) == 1);                    \
-      for (j = i + 1; j < BITS; j++)                    \
-        ASSERT (FUNC ((ONE << i) | (ONE << j)) == 2);   \
-    }                                                   \
-  for (i = 0; i < 1000; i++)                            \
-    {                                                   \
-      TYPE value = rand () ^ (rand () << 31 << 1);      \
-      int count = 0;                                    \
-      for (j = 0; j < BITS; j++)                        \
-        count += (value & (ONE << j)) != 0;             \
-      ASSERT (count == FUNC (value));                   \
-    }                                                   \
+#define TEST_COUNT_ONE_BITS(FUNC, TYPE, BITS, MAX, ONE)   \
+  ASSERT (FUNC (0) == 0);                                 \
+  for (i = 0; i < BITS; i++)                              \
+    {                                                     \
+      ASSERT (FUNC (ONE << i) == 1);                      \
+      for (j = i + 1; j < BITS; j++)                      \
+        ASSERT (FUNC ((ONE << i) | (ONE << j)) == 2);     \
+    }                                                     \
+  for (i = 0; i < 1000; i++)                              \
+    {                                                     \
+      /* RAND_MAX is most often 0x7fff or 0x7fffffff.  */ \
+      TYPE value =                                        \
+        (RAND_MAX <= 0xffff                               \
+         ? ((TYPE) rand () >> 3)                          \
+           ^ (((TYPE) rand () >> 3) << 12)                \
+           ^ (((TYPE) rand () >> 3) << 24)                \
+           ^ (((TYPE) rand () >> 3) << 30 << 6)           \
+           ^ (((TYPE) rand () >> 3) << 30 << 18)          \
+           ^ (((TYPE) rand () >> 3) << 30 << 30)          \
+         : ((TYPE) rand () >> 3)                          \
+           ^ (((TYPE) rand () >> 3) << 22)                \
+           ^ (((TYPE) rand () >> 3) << 22 << 22));        \
+      int count = 0;                                      \
+      for (j = 0; j < BITS; j++)                          \
+        count += (value & (ONE << j)) != 0;               \
+      ASSERT (count == FUNC (value));                     \
+    }                                                     \
   ASSERT (FUNC (MAX) == BITS);
 
   TEST_COUNT_ONE_BITS (count_one_bits, unsigned int, UINT_BIT, UINT_MAX, 1U);
--- a/tests/test-count-trailing-zeros.c	Sat Mar 09 00:27:19 2019 +0100
+++ b/tests/test-count-trailing-zeros.c	Sat Mar 09 20:32:25 2019 +0100
@@ -34,23 +34,34 @@
 {
   int i, j;
 
-#define TEST_COUNT_TRAILING_ZEROS(FUNC, TYPE, BITS, MAX, ONE)   \
-  ASSERT (FUNC (0) == BITS);                                    \
-  for (i = 0; i < BITS; i++)                                    \
-    {                                                           \
-      ASSERT (FUNC (ONE << i) == i);                            \
-      for (j = 0; j < i; j++)                                   \
-        ASSERT (FUNC ((ONE << i) | (ONE << j)) == j);           \
-    }                                                           \
-  for (i = 0; i < 1000; i++)                                    \
-    {                                                           \
-      TYPE value = rand () ^ (rand () << 31 << 1);              \
-      int count = 0;                                            \
-      for (j = BITS - 1; 0 <= j; j--)                           \
-        if (value & (ONE << j))                                 \
-          count = j;                                            \
-      ASSERT (count == FUNC (value));                           \
-    }                                                           \
+#define TEST_COUNT_TRAILING_ZEROS(FUNC, TYPE, BITS, MAX, ONE) \
+  ASSERT (FUNC (0) == BITS);                                  \
+  for (i = 0; i < BITS; i++)                                  \
+    {                                                         \
+      ASSERT (FUNC (ONE << i) == i);                          \
+      for (j = 0; j < i; j++)                                 \
+        ASSERT (FUNC ((ONE << i) | (ONE << j)) == j);         \
+    }                                                         \
+  for (i = 0; i < 1000; i++)                                  \
+    {                                                         \
+      /* RAND_MAX is most often 0x7fff or 0x7fffffff.  */     \
+      TYPE value =                                            \
+        (RAND_MAX <= 0xffff                                   \
+         ? ((TYPE) rand () >> 3)                              \
+           ^ (((TYPE) rand () >> 3) << 12)                    \
+           ^ (((TYPE) rand () >> 3) << 24)                    \
+           ^ (((TYPE) rand () >> 3) << 30 << 6)               \
+           ^ (((TYPE) rand () >> 3) << 30 << 18)              \
+           ^ (((TYPE) rand () >> 3) << 30 << 30)              \
+         : ((TYPE) rand () >> 3)                              \
+           ^ (((TYPE) rand () >> 3) << 22)                    \
+           ^ (((TYPE) rand () >> 3) << 22 << 22));            \
+      int count = 0;                                          \
+      for (j = BITS - 1; 0 <= j; j--)                         \
+        if (value & (ONE << j))                               \
+          count = j;                                          \
+      ASSERT (count == FUNC (value));                         \
+    }                                                         \
   ASSERT (FUNC (MAX) == 0);
 
   TEST_COUNT_TRAILING_ZEROS (count_trailing_zeros, unsigned int,
--- a/tests/test-memmem.c	Sat Mar 09 00:27:19 2019 +0100
+++ b/tests/test-memmem.c	Sat Mar 09 20:32:25 2019 +0100
@@ -26,7 +26,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-#include "null-ptr.h"
 #include "zerosize-ptr.h"
 #include "macros.h"
 
@@ -81,7 +80,7 @@
 
   {
     const char input[] = "foo";
-    const char *result = memmem (input, strlen (input), null_ptr (), 0);
+    const char *result = memmem (input, strlen (input), zerosize_ptr (), 0);
     ASSERT (result == input);
   }