]> Savannah Git Hosting - gnulib.git/commitdiff
Fix undefined behaviour.
authorBruno Haible <bruno@clisp.org>
Sat, 9 Mar 2019 19:32:25 +0000 (20:32 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 9 Mar 2019 19:32:25 +0000 (20:32 +0100)
* 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.

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

index a67ed92ce863761d81a830bc7330fb4eb7dfb864..62ab7565b83487862e094f9da552b0655df04502 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
index 862331e204b2611db52dbd2939845e8b4feea3b1..04b9083657c3cfc4ae0cefeaf9a8d64cb4be1a82 100644 (file)
@@ -95,7 +95,8 @@ rotr_sz (size_t x, int n)
 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 @@ rotl16 (uint16_t x, int n)
 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 @@ rotr16 (uint16_t x, int n)
 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 @@ rotl8 (uint8_t x, int n)
 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
index 4f491be1b8d019d56430cdfcfee115afdb8cd64c..57c1b595e7a33d6fb9812f20314eeb0d1abc555c 100644 (file)
@@ -38,7 +38,8 @@ char *
 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;
 }
index 28c00917a4f97534aa956eff91e3ca722d8ca566..250ccbf060f3c8f7f84dd96211c4514f8c6fcfee 100644 (file)
@@ -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
index 3caae7f060ab95a861a15ba4ace5565dcdf04c24..e94e37ef38c8306b0d048c5c3029982ea7e0821c 100644 (file)
@@ -34,23 +34,34 @@ main (int argc, char *argv[])
 {
   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,
index 109f3eeeb353cc43e8fe053ae18afa52e10a7cfa..852e1d62696b5a8d29ae524986bcabd5b2d970a4 100644 (file)
@@ -34,22 +34,33 @@ main (int argc, char *argv[])
 {
   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);
index 5a1859921a71080cfc7d134e71a64c1596564a38..04d9ddca1213f1ab8c901ead58778f561e270e76 100644 (file)
@@ -34,23 +34,34 @@ main (int argc, char *argv[])
 {
   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,
index ed327e61c0d68849ae7290a89000ac22a5134fe7..17e2e4152199e1eeeb7eb1f1507192bc6a15a17f 100644 (file)
@@ -26,7 +26,6 @@ SIGNATURE_CHECK (memmem, void *, (void const *, size_t, void const *, size_t));
 #include <stdlib.h>
 #include <unistd.h>
 
-#include "null-ptr.h"
 #include "zerosize-ptr.h"
 #include "macros.h"
 
@@ -81,7 +80,7 @@ main (int argc, char *argv[])
 
   {
     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);
   }