public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add tests for strdup and strndup (BZ #30266)
@ 2023-03-29 15:04 Joe Simmons-Talbott
  2023-03-29 15:04 ` [PATCH 1/2] strdup: Add tests " Joe Simmons-Talbott
                   ` (7 more replies)
  0 siblings, 8 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-03-29 15:04 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
tests that checked the surrounding bytes of the result as they are not needed.

Joe Simmons-Talbott (2):
  strdup: Add tests (BZ #30266)
  strndup: Add tests (BZ #30266)

 string/Makefile       |   2 +
 string/test-strdup.c  | 247 +++++++++++++++++++++++++++++++++++++++
 string/test-strndup.c | 266 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 515 insertions(+)
 create mode 100644 string/test-strdup.c
 create mode 100644 string/test-strndup.c

-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH 1/2] strdup: Add tests (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
@ 2023-03-29 15:04 ` Joe Simmons-Talbott
  2023-03-30 11:16   ` Adhemerval Zanella Netto
  2023-03-29 15:05 ` [PATCH 2/2] strndup: " Joe Simmons-Talbott
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-03-29 15:04 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy tests for strdup.  Covers some basic testcases with random
strings.  Add a zero-length string testcase.

Signed-off-by: Joe Simmons-Talbott <josimmon@redhat.com>
---
 string/Makefile      |   1 +
 string/test-strdup.c | 247 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 248 insertions(+)
 create mode 100644 string/test-strdup.c

diff --git a/string/Makefile b/string/Makefile
index c84b49aaa5..472e318aea 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -157,6 +157,7 @@ tests := \
   test-strcmp \
   test-strcpy \
   test-strcspn \
+  test-strdup \
   test-strlen \
   test-strncasecmp \
   test-strncat \
diff --git a/string/test-strdup.c b/string/test-strdup.c
new file mode 100644
index 0000000000..fa551b9b30
--- /dev/null
+++ b/string/test-strdup.c
@@ -0,0 +1,247 @@
+/* Test and measure strdup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+		  //
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strdup"
+# else
+#  define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define STRDUP strdup
+# else
+#  define STRDUP wcsdup
+# endif
+
+IMPL (STRDUP, 1)
+
+/* Also check the generic implementation.  */
+#undef STRDUP
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(a)
+#undef libc_hidden_def
+#define libc_hidden_def(a)
+#undef weak_alias
+#define weak_alias(a,b)
+#undef attribute_hidden
+#define attribute_hidden
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+  char *dst;
+  char src[1] = {0};
+
+  FOR_EACH_IMPL (impl, 0)
+    {
+      dst = CALL (impl, src);
+
+      TEST_COMPARE_STRING (dst, src);
+    }
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  char *d;
+  d = CALL (impl, src);
+
+  if (STRCMP (d, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     impl->name, d, src);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcsrchr: align1 and align2 here mean align not in bytes,
+	 but in wchar_ts, in bytes it will equal to align * (sizeof
+	 (wchar_t)).  For strrchr we need to check all alignments from
+	 0 to 63 since some assembly implementations have separate
+	 prolog for alignments more 48. */
+
+      align1 = random () & (63 / sizeof (CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof (CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  MEMSET (p2 - 64, '\1', 512 + 64);
+	  res = (UCHAR *) CALL (impl, (CHAR *) (p1 + align1));
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  for (j = align2 + len + 1; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (MEMCMP (p1 + align1, res, len + 1))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_zero_len_test ();
+  do_random_tests ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH 2/2] strndup: Add tests (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
  2023-03-29 15:04 ` [PATCH 1/2] strdup: Add tests " Joe Simmons-Talbott
@ 2023-03-29 15:05 ` Joe Simmons-Talbott
  2023-03-30 11:19   ` Adhemerval Zanella Netto
  2023-03-30 14:50 ` [PATCH v2 0/2] Add tests for strdup and strndup " Joe Simmons-Talbott
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-03-29 15:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strncpy tests for strndup.  Covers some basic testcases with random
strings.  Remove tests that set the destination's bytes and checked the
resulting buffer's bytes.

Signed-off-by: Joe Simmons-Talbott <josimmon@redhat.com>
---
 string/Makefile       |   1 +
 string/test-strndup.c | 266 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 267 insertions(+)
 create mode 100644 string/test-strndup.c

diff --git a/string/Makefile b/string/Makefile
index 472e318aea..2eef6f1dfc 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -163,6 +163,7 @@ tests := \
   test-strncat \
   test-strncmp \
   test-strncpy \
+  test-strndup \
   test-strnlen \
   test-strpbrk \
   test-strrchr \
diff --git a/string/test-strndup.c b/string/test-strndup.c
new file mode 100644
index 0000000000..032b0775b8
--- /dev/null
+++ b/string/test-strndup.c
@@ -0,0 +1,266 @@
+/* Test strndup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define STRNLEN wcsnlen
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define MEMCMP memcmp
+# define MEMSET memset
+# define STRNLEN strnlen
+#endif /* !WIDE */
+
+
+#ifndef STRNDUP_RESULT
+# define STRNDUP_RESULT(dst, len, n) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strndup"
+# else
+#  define TEST_NAME "wcsndup"
+# endif /* WIDE */
+# include "test-string.h"
+# ifndef WIDE
+#  define STRNDUP strndup
+# else
+#  define STRNDUP wcsndup
+# endif /* WIDE */
+
+
+IMPL (STRNDUP, 1)
+
+
+#endif /* !STRNDUP_RESULT */
+
+typedef CHAR *(*proto_t) (const CHAR *, size_t);
+
+static void
+do_one_test (impl_t *impl, const CHAR *src, size_t len, size_t n)
+{
+  char *dst;
+  dst = CALL (impl, src, n);
+  size_t res;
+
+  res = memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR));
+  if (res != 0)
+    {
+      printf("JOE: res: %ld\n", res);
+      error (0, 0, "Wrong result in function %s", impl->name);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+
+/* For wcsndup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+  CHAR *s1;
+  const size_t maxoffset = 64;
+
+  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
+  s1 = (CHAR *) buf1 + BUF1PAGES * page_size / sizeof(CHAR) - maxoffset;
+  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
+     (maxoffset - 1).  */
+
+  MEMSET (s1, 'a', maxoffset - 1);
+  s1[maxoffset - 1] = '\0';
+
+  /* Both strings are bounded to a page with read/write access and the next
+     page is protected with PROT_NONE (meaning that any access outside of the
+     page regions will trigger an invalid memory access).
+
+     The loop copies the string s1 for all possible offsets up to maxoffset
+     for both inputs with a size larger than s1 (so memory access outside the
+     expected memory regions might trigger invalid access).  */
+
+  for (size_t off1 = 0; off1 < maxoffset; off1++)
+    {
+      for (size_t off2 = 0; off2 < maxoffset; off2++)
+	{
+	  FOR_EACH_IMPL (impl, 0)
+	    do_one_test (impl, s1 + off1, maxoffset - off1 - 1,
+			 maxoffset + (maxoffset - off2));
+	}
+    }
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcsndup: align1 and align2 here mean align not in bytes,
+	 but in wchar_ts, in bytes it will equal to align * (sizeof
+	 (wchar_t)).  */
+
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  res = (UCHAR *) CALL (impl, (CHAR *) (p1 + align1), size);
+	  j = len + 1;
+	  if (size < j)
+	    j = size;
+	  if (MEMCMP (p1 + align1, res, j))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, SMALL_CHAR);
+      do_test (i, i, 16, 16, BIG_CHAR);
+      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
+      do_test (2 * i, i, 16, 16, BIG_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 1/2] strdup: Add tests (BZ #30266)
  2023-03-29 15:04 ` [PATCH 1/2] strdup: Add tests " Joe Simmons-Talbott
@ 2023-03-30 11:16   ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-03-30 11:16 UTC (permalink / raw)
  To: Joe Simmons-Talbott, libc-alpha



On 29/03/23 12:04, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strcpy tests for strdup.  Covers some basic testcases with random
> strings.  Add a zero-length string testcase.
> 
> Signed-off-by: Joe Simmons-Talbott <josimmon@redhat.com>
> ---
>  string/Makefile      |   1 +
>  string/test-strdup.c | 247 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 248 insertions(+)
>  create mode 100644 string/test-strdup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index c84b49aaa5..472e318aea 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -157,6 +157,7 @@ tests := \
>    test-strcmp \
>    test-strcpy \
>    test-strcspn \
> +  test-strdup \
>    test-strlen \
>    test-strncasecmp \
>    test-strncat \
> diff --git a/string/test-strdup.c b/string/test-strdup.c
> new file mode 100644
> index 0000000000..fa551b9b30
> --- /dev/null
> +++ b/string/test-strdup.c
> @@ -0,0 +1,247 @@
> +/* Test and measure strdup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +		  //
> +#include <support/check.h>
> +
> +#ifdef WIDE
> +# include <wchar.h>
> +# define CHAR wchar_t
> +# define UCHAR wchar_t
> +# define sfmt "ls"
> +# define BIG_CHAR WCHAR_MAX
> +# define SMALL_CHAR 1273
> +# define STRCMP wcscmp
> +# define MEMCMP wmemcmp
> +# define MEMSET wmemset
> +#else
> +# define CHAR char
> +# define UCHAR unsigned char
> +# define sfmt "s"
> +# define BIG_CHAR CHAR_MAX
> +# define SMALL_CHAR 127
> +# define STRCMP strcmp
> +# define MEMCMP memcmp
> +# define MEMSET memset
> +#endif
> +
> +#ifndef STRDUP_RESULT
> +# define STRDUP_RESULT(dst, len) dst
> +# define TEST_MAIN
> +# ifndef WIDE
> +#  define TEST_NAME "strdup"
> +# else
> +#  define TEST_NAME "wcsdup"
> +# endif
> +# include "test-string.h"
> +# ifndef WIDE
> +#  define STRDUP strdup
> +# else
> +#  define STRDUP wcsdup
> +# endif
> +
> +IMPL (STRDUP, 1)
> +
> +/* Also check the generic implementation.  */
> +#undef STRDUP
> +#undef libc_hidden_builtin_def
> +#define libc_hidden_builtin_def(a)
> +#undef libc_hidden_def
> +#define libc_hidden_def(a)
> +#undef weak_alias
> +#define weak_alias(a,b)
> +#undef attribute_hidden
> +#define attribute_hidden
> +#endif
> +
> +typedef CHAR *(*proto_t) (const CHAR *);
> +
> +static void
> +do_zero_len_test (void)
> +{
> +  char *dst;
> +  char src[1] = {0};

Use '\0' here.

> +
> +  FOR_EACH_IMPL (impl, 0)
> +    {
> +      dst = CALL (impl, src);
> +
> +      TEST_COMPARE_STRING (dst, src);
> +    }
> +}

The strdup code implementation does not use ifunc and I think it would be 
unlike to use anytime soon, so there is no need to include and test the
default implementation nor use IMPL here.  Just call it directly:

  static void
  do_zero_len_test (void)
  {
     src [1] = { '\0' };
     char *dst = strdup (src);
     TEST_COMPARE_STRING (dst, src);
  }

> +
> +static void
> +do_one_test (impl_t *impl, const CHAR *src,
> +	     size_t len __attribute__((unused)))
> +{
> +  char *d;
> +  d = CALL (impl, src);
> +
> +  if (STRCMP (d, src) != 0)
> +    {
> +      error (0, 0,
> +	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
> +	     impl->name, d, src);
> +      ret = 1;
> +      return;
> +    }
> +}

Same as before.

> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +/* For wcsdup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
> +   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; i++)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +
> +  FOR_EACH_IMPL (impl, 0)
> +    do_one_test (impl, s1, len);
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;
> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* For wcsrchr: align1 and align2 here mean align not in bytes,
> +	 but in wchar_ts, in bytes it will equal to align * (sizeof
> +	 (wchar_t)).  For strrchr we need to check all alignments from
> +	 0 to 63 since some assembly implementations have separate
> +	 prolog for alignments more 48. */

The sentence sounds strange, so maybe (also double space after period):

  /* align1 and align2 are expressed is wchar_t and not in bytes for wide
     char test, and thus it will be equal to align times wchar_t size.

     For non wide version we need to check all alignments from 0 to 63 
     since some assembly implementations have separate prolog for alignments 
     more 48.  */

> +
> +      align1 = random () & (63 / sizeof (CHAR));
> +      if (random () & 1)
> +	align2 = random () & (63 / sizeof (CHAR));
> +      else
> +	align2 = align1 + (random () & 24);
> +      len = random () & 511;
> +      j = align1;
> +      if (align2 > j)
> +	j = align2;
> +      if (len + j >= 511)
> +	len = 510 - j - (random () & 7);
> +      j = len + align1 + 64;
> +      if (j > 512)
> +	j = 512;
> +      for (i = 0; i < j; i++)
> +	{
> +	  if (i == len + align1)
> +	    p1[i] = 0;
> +	  else
> +	    {
> +	      p1[i] = random () & BIG_CHAR;
> +	      if (i >= align1 && i < len + align1 && !p1[i])
> +		p1[i] = (random () & SMALL_CHAR) + 3;
> +	    }
> +	}
> +
> +      FOR_EACH_IMPL (impl, 1)
> +	{
> +	  MEMSET (p2 - 64, '\1', 512 + 64);
> +	  res = (UCHAR *) CALL (impl, (CHAR *) (p1 + align1));
> +	  for (j = 0; j < align2 + 64; ++j)
> +	    {
> +	      if (p2[j - 64] != '\1')
> +		{
> +		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
> +			 n, impl->name, align1, align2, len);
> +		  ret = 1;
> +		  break;
> +		}
> +	    }
> +	  for (j = align2 + len + 1; j < 512; ++j)
> +	    {
> +	      if (p2[j] != '\1')
> +		{
> +		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
> +			 n, impl->name, align1, align2, len);
> +		  ret = 1;
> +		  break;
> +		}
> +	    }
> +	  if (MEMCMP (p1 + align1, res, len + 1))
> +	    {
> +	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
> +		     n, impl->name, align1, align2, len);
> +	      ret = 1;
> +	    }
> +	}
> +    }
> +}
> +
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%23s", "");
> +  FOR_EACH_IMPL (impl, 0)
> +    printf ("\t%s", impl->name);
> +  putchar ('\n');
> +
> +  for (i = 0; i < 16; ++i)
> +    {
> +      do_test (0, 0, i, SMALL_CHAR);
> +      do_test (0, 0, i, BIG_CHAR);
> +      do_test (0, i, i, SMALL_CHAR);
> +      do_test (i, 0, i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
> +      do_test (2 * i, i, 8 << i, BIG_CHAR);
> +      do_test (i, i, 8 << i, SMALL_CHAR);
> +      do_test (i, i, 8 << i, BIG_CHAR);
> +    }
> +
> +  do_zero_len_test ();
> +  do_random_tests ();
> +
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 2/2] strndup: Add tests (BZ #30266)
  2023-03-29 15:05 ` [PATCH 2/2] strndup: " Joe Simmons-Talbott
@ 2023-03-30 11:19   ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-03-30 11:19 UTC (permalink / raw)
  To: libc-alpha



On 29/03/23 12:05, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strncpy tests for strndup.  Covers some basic testcases with random
> strings.  Remove tests that set the destination's bytes and checked the
> resulting buffer's bytes.
> 
> Signed-off-by: Joe Simmons-Talbott <josimmon@redhat.com>

I guess the buildbot compiler version is different than one I used, but I
am seeing this failure on i686:

test-strndup.c: In function ‘do_one_test’:
test-strndup.c:72:27: error: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘size_t’ {aka ‘unsigned int’} [-Werror=format=]
   72 |       printf("JOE: res: %ld\n", res);
      |                         ~~^     ~~~
      |                           |     |
      |                           |     size_t {aka unsigned int}
      |                           long int
      |                         %d

> ---
>  string/Makefile       |   1 +
>  string/test-strndup.c | 266 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 267 insertions(+)
>  create mode 100644 string/test-strndup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index 472e318aea..2eef6f1dfc 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -163,6 +163,7 @@ tests := \
>    test-strncat \
>    test-strncmp \
>    test-strncpy \
> +  test-strndup \
>    test-strnlen \
>    test-strpbrk \
>    test-strrchr \
> diff --git a/string/test-strndup.c b/string/test-strndup.c
> new file mode 100644
> index 0000000000..032b0775b8
> --- /dev/null
> +++ b/string/test-strndup.c
> @@ -0,0 +1,266 @@
> +/* Test strndup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifdef WIDE
> +# include <wchar.h>
> +# define CHAR wchar_t
> +# define UCHAR wchar_t
> +# define BIG_CHAR WCHAR_MAX
> +# define SMALL_CHAR 1273
> +# define MEMCMP wmemcmp
> +# define MEMSET wmemset
> +# define STRNLEN wcsnlen
> +#else
> +# define CHAR char
> +# define UCHAR unsigned char
> +# define BIG_CHAR CHAR_MAX
> +# define SMALL_CHAR 127
> +# define MEMCMP memcmp
> +# define MEMSET memset
> +# define STRNLEN strnlen
> +#endif /* !WIDE */
> +
> +
> +#ifndef STRNDUP_RESULT
> +# define STRNDUP_RESULT(dst, len, n) dst
> +# define TEST_MAIN
> +# ifndef WIDE
> +#  define TEST_NAME "strndup"
> +# else
> +#  define TEST_NAME "wcsndup"
> +# endif /* WIDE */
> +# include "test-string.h"
> +# ifndef WIDE
> +#  define STRNDUP strndup
> +# else
> +#  define STRNDUP wcsndup
> +# endif /* WIDE */
> +
> +
> +IMPL (STRNDUP, 1)
> +
> +
> +#endif /* !STRNDUP_RESULT */
> +
> +typedef CHAR *(*proto_t) (const CHAR *, size_t);
> +
> +static void
> +do_one_test (impl_t *impl, const CHAR *src, size_t len, size_t n)
> +{
> +  char *dst;
> +  dst = CALL (impl, src, n);

The strndup code implementation does not use ifunc and I think it would be 
unlike to use anytime soon, so there is no need to include and test the
default implementation nor use IMPL here.  Just call it directly:


> +  size_t res;
> +
> +  res = memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR));

Mayse use WMEMCMP here, since you does define above? Or you can just
compare with TEST_COMPARE_BLOB.

> +  if (res != 0)
> +    {
> +      printf("JOE: res: %ld\n", res);
> +      error (0, 0, "Wrong result in function %s", impl->name);
> +      ret = 1;
> +      return;
> +    }
> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +
> +/* For wcsndup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; ++i)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
> +       ++i)
> +    s1[i] = 32 + 32 * i % (max_char - 32);
> +
> +  FOR_EACH_IMPL (impl, 0)
> +    do_one_test (impl, s1, len, n);
> +}
> +
> +static void
> +do_page_tests (void)
> +{
> +  CHAR *s1;
> +  const size_t maxoffset = 64;
> +
> +  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
> +  s1 = (CHAR *) buf1 + BUF1PAGES * page_size / sizeof(CHAR) - maxoffset;
> +  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
> +     (maxoffset - 1).  */
> +
> +  MEMSET (s1, 'a', maxoffset - 1);
> +  s1[maxoffset - 1] = '\0';
> +
> +  /* Both strings are bounded to a page with read/write access and the next
> +     page is protected with PROT_NONE (meaning that any access outside of the
> +     page regions will trigger an invalid memory access).
> +
> +     The loop copies the string s1 for all possible offsets up to maxoffset
> +     for both inputs with a size larger than s1 (so memory access outside the
> +     expected memory regions might trigger invalid access).  */
> +
> +  for (size_t off1 = 0; off1 < maxoffset; off1++)
> +    {
> +      for (size_t off2 = 0; off2 < maxoffset; off2++)
> +	{
> +	  FOR_EACH_IMPL (impl, 0)
> +	    do_one_test (impl, s1 + off1, maxoffset - off1 - 1,
> +			 maxoffset + (maxoffset - off2));
> +	}
> +    }
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len, size, mode;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* For wcsndup: align1 and align2 here mean align not in bytes,
> +	 but in wchar_ts, in bytes it will equal to align * (sizeof
> +	 (wchar_t)).  */
> +
> +      mode = random ();
> +      if (mode & 1)
> +	{
> +	  size = random () & 255;
> +	  align1 = 512 - size - (random () & 15);
> +	  if (mode & 2)
> +	    align2 = align1 - (random () & 24);
> +	  else
> +	    align2 = align1 - (random () & 31);
> +	  if (mode & 4)
> +	    {
> +	      j = align1;
> +	      align1 = align2;
> +	      align2 = j;
> +	    }
> +	  if (mode & 8)
> +	    len = size - (random () & 31);
> +	  else
> +	    len = 512;
> +	  if (len >= 512)
> +	    len = random () & 511;
> +	}
> +      else
> +	{
> +	  align1 = random () & 31;
> +	  if (mode & 2)
> +	    align2 = random () & 31;
> +	  else
> +	    align2 = align1 + (random () & 24);
> +	  len = random () & 511;
> +	  j = align1;
> +	  if (align2 > j)
> +	    j = align2;
> +	  if (mode & 4)
> +	    {
> +	      size = random () & 511;
> +	      if (size + j > 512)
> +		size = 512 - j - (random () & 31);
> +	    }
> +	  else
> +	    size = 512 - j;
> +	  if ((mode & 8) && len + j >= 512)
> +	    len = 512 - j - (random () & 7);
> +	}
> +      j = len + align1 + 64;
> +      if (j > 512)
> +	j = 512;
> +      for (i = 0; i < j; i++)
> +	{
> +	  if (i == len + align1)
> +	    p1[i] = 0;
> +	  else
> +	    {
> +	      p1[i] = random () & BIG_CHAR;
> +	      if (i >= align1 && i < len + align1 && !p1[i])
> +		p1[i] = (random () & SMALL_CHAR) + 3;
> +	    }
> +	}
> +
> +      FOR_EACH_IMPL (impl, 1)
> +	{
> +	  res = (UCHAR *) CALL (impl, (CHAR *) (p1 + align1), size);
> +	  j = len + 1;
> +	  if (size < j)
> +	    j = size;
> +	  if (MEMCMP (p1 + align1, res, j))
> +	    {
> +	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
> +		     n, impl->name, align1, align2, len);
> +	      ret = 1;
> +	    }
> +	}
> +    }
> +}
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%28s", "");
> +  FOR_EACH_IMPL (impl, 0)
> +    printf ("\t%s", impl->name);
> +  putchar ('\n');
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, i, 16, 16, SMALL_CHAR);
> +      do_test (i, i, 16, 16, BIG_CHAR);
> +      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
> +      do_test (2 * i, i, 16, 16, BIG_CHAR);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
> +      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  do_random_tests ();
> +  do_page_tests ();
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 0/2]  Add tests for strdup and strndup (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
  2023-03-29 15:04 ` [PATCH 1/2] strdup: Add tests " Joe Simmons-Talbott
  2023-03-29 15:05 ` [PATCH 2/2] strndup: " Joe Simmons-Talbott
@ 2023-03-30 14:50 ` Joe Simmons-Talbott
  2023-03-30 14:50   ` [PATCH v2 1/2] strdup: Add tests " Joe Simmons-Talbott
  2023-03-30 14:50   ` [PATCH v2 2/2] strndup: " Joe Simmons-Talbott
  2023-04-04 19:00 ` [PATCH v3 0/3] string: Add tests for strdup and strndup " Joe Simmons-Talbott
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-03-30 14:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
tests that checked the surrounding bytes of the result as they are not needed.

Changes to v1: Since strdup and strndup are not ifuncs and likely won't
be, call them directly.  Use TEST_COMPARE_BLOB() rather than memcmp().
Clear up wording in a comment.

Joe Simmons-Talbott (2):
  strdup: Add tests (BZ #30266)
  strndup: Add tests (BZ #30266)

 string/Makefile       |   2 +
 string/test-strdup.c  | 241 +++++++++++++++++++++++++++++++++++++++
 string/test-strndup.c | 255 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 498 insertions(+)
 create mode 100644 string/test-strdup.c
 create mode 100644 string/test-strndup.c

-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 1/2] strdup: Add tests (BZ #30266)
  2023-03-30 14:50 ` [PATCH v2 0/2] Add tests for strdup and strndup " Joe Simmons-Talbott
@ 2023-03-30 14:50   ` Joe Simmons-Talbott
  2023-04-04 13:44     ` Adhemerval Zanella Netto
  2023-03-30 14:50   ` [PATCH v2 2/2] strndup: " Joe Simmons-Talbott
  1 sibling, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-03-30 14:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy tests for strdup.  Covers some basic testcases with random
strings.  Add a zero-length string testcase.

Signed-off-by: Joe Simmons-Talbott <josimmon@redhat.com>
---
 string/Makefile      |   1 +
 string/test-strdup.c | 241 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 242 insertions(+)
 create mode 100644 string/test-strdup.c

diff --git a/string/Makefile b/string/Makefile
index c84b49aaa5..472e318aea 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -157,6 +157,7 @@ tests := \
   test-strcmp \
   test-strcpy \
   test-strcspn \
+  test-strdup \
   test-strlen \
   test-strncasecmp \
   test-strncat \
diff --git a/string/test-strdup.c b/string/test-strdup.c
new file mode 100644
index 0000000000..04eedafc24
--- /dev/null
+++ b/string/test-strdup.c
@@ -0,0 +1,241 @@
+/* Test and measure strdup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+		  //
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strdup"
+# else
+#  define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define STRDUP strdup
+# else
+#  define STRDUP wcsdup
+# endif
+
+IMPL (STRDUP, 1)
+
+/* Also check the generic implementation.  */
+#undef STRDUP
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(a)
+#undef libc_hidden_def
+#define libc_hidden_def(a)
+#undef weak_alias
+#define weak_alias(a,b)
+#undef attribute_hidden
+#define attribute_hidden
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+  char src[1] = { '\0' };
+  char *dst = strdup (src);
+
+  TEST_COMPARE_STRING (dst, src);
+}
+
+static void
+do_one_test (const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  char *dst = strdup (src);
+
+  if (STRCMP (dst, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function strdup dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     dst, src);
+      ret = 1;
+      return;
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  do_one_test (s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
+     char test, and thus it will be equal to align times wchar_t size.
+
+     For non wide version we need to check all alignments from 0 to 63
+     since some assembly implementations have separate prolog for alignments
+     more 48.  */
+
+      align1 = random () & (63 / sizeof (CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof (CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  MEMSET (p2 - 64, '\1', 512 + 64);
+	  res = (UCHAR *) CALL (impl, (CHAR *) (p1 + align1));
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  for (j = align2 + len + 1; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (MEMCMP (p1 + align1, res, len + 1))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_zero_len_test ();
+  do_random_tests ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 2/2] strndup: Add tests (BZ #30266)
  2023-03-30 14:50 ` [PATCH v2 0/2] Add tests for strdup and strndup " Joe Simmons-Talbott
  2023-03-30 14:50   ` [PATCH v2 1/2] strdup: Add tests " Joe Simmons-Talbott
@ 2023-03-30 14:50   ` Joe Simmons-Talbott
  1 sibling, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-03-30 14:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strncpy tests for strndup.  Covers some basic testcases with random
strings.  Remove tests that set the destination's bytes and checked the
resulting buffer's bytes.

Signed-off-by: Joe Simmons-Talbott <josimmon@redhat.com>
---
 string/Makefile       |   1 +
 string/test-strndup.c | 255 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 256 insertions(+)
 create mode 100644 string/test-strndup.c

diff --git a/string/Makefile b/string/Makefile
index 472e318aea..2eef6f1dfc 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -163,6 +163,7 @@ tests := \
   test-strncat \
   test-strncmp \
   test-strncpy \
+  test-strndup \
   test-strnlen \
   test-strpbrk \
   test-strrchr \
diff --git a/string/test-strndup.c b/string/test-strndup.c
new file mode 100644
index 0000000000..ab6428f4fb
--- /dev/null
+++ b/string/test-strndup.c
@@ -0,0 +1,255 @@
+/* Test strndup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define STRNLEN wcsnlen
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define MEMCMP memcmp
+# define MEMSET memset
+# define STRNLEN strnlen
+#endif /* !WIDE */
+
+
+#ifndef STRNDUP_RESULT
+# define STRNDUP_RESULT(dst, len, n) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strndup"
+# else
+#  define TEST_NAME "wcsndup"
+# endif /* WIDE */
+# include "test-string.h"
+# ifndef WIDE
+#  define STRNDUP strndup
+# else
+#  define STRNDUP wcsndup
+# endif /* WIDE */
+
+
+IMPL (STRNDUP, 1)
+
+
+#endif /* !STRNDUP_RESULT */
+
+typedef CHAR *(*proto_t) (const CHAR *, size_t);
+
+static void
+do_one_test (const CHAR *src, size_t len, size_t n)
+{
+  char *dst = strndup(src, n);
+  size_t s = (len > n ? n: len) * sizeof (CHAR);
+
+  TEST_COMPARE_BLOB(dst, s, src, s);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+
+/* For wcsndup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  do_one_test (s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+  CHAR *s1;
+  const size_t maxoffset = 64;
+
+  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
+  s1 = (CHAR *) buf1 + BUF1PAGES * page_size / sizeof(CHAR) - maxoffset;
+  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
+     (maxoffset - 1).  */
+
+  MEMSET (s1, 'a', maxoffset - 1);
+  s1[maxoffset - 1] = '\0';
+
+  /* Both strings are bounded to a page with read/write access and the next
+     page is protected with PROT_NONE (meaning that any access outside of the
+     page regions will trigger an invalid memory access).
+
+     The loop copies the string s1 for all possible offsets up to maxoffset
+     for both inputs with a size larger than s1 (so memory access outside the
+     expected memory regions might trigger invalid access).  */
+
+  for (size_t off1 = 0; off1 < maxoffset; off1++)
+    {
+      for (size_t off2 = 0; off2 < maxoffset; off2++)
+	{
+	  do_one_test (s1 + off1, maxoffset - off1 - 1,
+			 maxoffset + (maxoffset - off2));
+	}
+    }
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcsndup: align1 and align2 here mean align not in bytes,
+	 but in wchar_ts, in bytes it will equal to align * (sizeof
+	 (wchar_t)).  */
+
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+	res = (UCHAR *) strndup ((CHAR *) (p1 + align1), size);
+	j = len + 1;
+	if (size < j)
+	  j = size;
+	if (MEMCMP (p1 + align1, res, j))
+	  {
+	    error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+	       n, "strndup", align1, align2, len);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, SMALL_CHAR);
+      do_test (i, i, 16, 16, BIG_CHAR);
+      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
+      do_test (2 * i, i, 16, 16, BIG_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 1/2] strdup: Add tests (BZ #30266)
  2023-03-30 14:50   ` [PATCH v2 1/2] strdup: Add tests " Joe Simmons-Talbott
@ 2023-04-04 13:44     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-04 13:44 UTC (permalink / raw)
  To: Joe Simmons-Talbott, libc-alpha



On 30/03/23 11:50, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strcpy tests for strdup.  Covers some basic testcases with random
> strings.  Add a zero-length string testcase.
> 
> Signed-off-by: Joe Simmons-Talbott <josimmon@redhat.com>
> ---
>  string/Makefile      |   1 +
>  string/test-strdup.c | 241 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 242 insertions(+)
>  create mode 100644 string/test-strdup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index c84b49aaa5..472e318aea 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -157,6 +157,7 @@ tests := \
>    test-strcmp \
>    test-strcpy \
>    test-strcspn \
> +  test-strdup \
>    test-strlen \
>    test-strncasecmp \
>    test-strncat \
> diff --git a/string/test-strdup.c b/string/test-strdup.c
> new file mode 100644
> index 0000000000..04eedafc24
> --- /dev/null
> +++ b/string/test-strdup.c
> @@ -0,0 +1,241 @@
> +/* Test and measure strdup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +		  //

Spurious '//'.

> +#include <support/check.h>
> +
> +#ifdef WIDE
> +# include <wchar.h>
> +# define CHAR wchar_t
> +# define UCHAR wchar_t
> +# define sfmt "ls"
> +# define BIG_CHAR WCHAR_MAX
> +# define SMALL_CHAR 1273
> +# define STRCMP wcscmp
> +# define MEMCMP wmemcmp
> +# define MEMSET wmemset
> +#else
> +# define CHAR char
> +# define UCHAR unsigned char
> +# define sfmt "s"
> +# define BIG_CHAR CHAR_MAX
> +# define SMALL_CHAR 127
> +# define STRCMP strcmp
> +# define MEMCMP memcmp
> +# define MEMSET memset
> +#endif
> +
> +#ifndef STRDUP_RESULT
> +# define STRDUP_RESULT(dst, len) dst
> +# define TEST_MAIN
> +# ifndef WIDE
> +#  define TEST_NAME "strdup"
> +# else
> +#  define TEST_NAME "wcsdup"
> +# endif
> +# include "test-string.h"
> +# ifndef WIDE
> +#  define STRDUP strdup
> +# else
> +#  define STRDUP wcsdup
> +# endif
> +
> +IMPL (STRDUP, 1)

There is no need to use IMPL here, no architecture provides strdup ifunc
variants.

> +
> +/* Also check the generic implementation.  */
> +#undef STRDUP
> +#undef libc_hidden_builtin_def
> +#define libc_hidden_builtin_def(a)
> +#undef libc_hidden_def
> +#define libc_hidden_def(a)
> +#undef weak_alias
> +#define weak_alias(a,b)
> +#undef attribute_hidden
> +#define attribute_hidden
> +#endif

This is also not required (it is essentially dead definitions).

> +
> +typedef CHAR *(*proto_t) (const CHAR *);
> +
> +static void
> +do_zero_len_test (void)
> +{
> +  char src[1] = { '\0' };
> +  char *dst = strdup (src);
> +
> +  TEST_COMPARE_STRING (dst, src);

Since you are testing the interface, also call free here (and it avoid
leak reports on memory profiling tools).

> +}
> +
> +static void
> +do_one_test (const CHAR *src,
> +	     size_t len __attribute__((unused)))
> +{
> +  char *dst = strdup (src);
> +
> +  if (STRCMP (dst, src) != 0)
> +    {
> +      error (0, 0,
> +	     "Wrong result in function strdup dst \"%" sfmt "\" src \"%" sfmt "\"",
> +	     dst, src);
> +      ret = 1;
> +      return;
> +    }
> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +/* For wcsdup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
> +   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; i++)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +
> +  do_one_test (s1, len);
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512;

This variable is not required (see below).

> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
> +     char test, and thus it will be equal to align times wchar_t size.
> +
> +     For non wide version we need to check all alignments from 0 to 63
> +     since some assembly implementations have separate prolog for alignments
> +     more 48.  */
> +
> +      align1 = random () & (63 / sizeof (CHAR));
> +      if (random () & 1)
> +	align2 = random () & (63 / sizeof (CHAR));
> +      else
> +	align2 = align1 + (random () & 24);
> +      len = random () & 511;
> +      j = align1;
> +      if (align2 > j)
> +	j = align2;
> +      if (len + j >= 511)
> +	len = 510 - j - (random () & 7);
> +      j = len + align1 + 64;
> +      if (j > 512)
> +	j = 512;
> +      for (i = 0; i < j; i++)
> +	{
> +	  if (i == len + align1)
> +	    p1[i] = 0;
> +	  else
> +	    {
> +	      p1[i] = random () & BIG_CHAR;
> +	      if (i >= align1 && i < len + align1 && !p1[i])
> +		p1[i] = (random () & SMALL_CHAR) + 3;
> +	    }
> +	}
> +
> +      FOR_EACH_IMPL (impl, 1)

As before, there is no need to use the ifunc variant test mechanism. 

> +	{
> +	  MEMSET (p2 - 64, '\1', 512 + 64);
> +	  res = (UCHAR *) CALL (impl, (CHAR *) (p1 + align1));

This test does not make sense: strdup returns a newly allocated buffer on
'res' and you test the 'p2' which is different mmap region.  Just use:

  char *r = strdup (p1 + align1)
  TEST_COMPARE_STRING (r, (CHAR *) (p1 + align1));
  free (r);

Since you can really check out of bounds access (as other string tests do)
without trigger UB.


> +	  for (j = 0; j < align2 + 64; ++j)
> +	    {
> +	      if (p2[j - 64] != '\1')
> +		{
> +		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
> +			 n, impl->name, align1, align2, len);
> +		  ret = 1;
> +		  break;
> +		}
> +	    }
> +	  for (j = align2 + len + 1; j < 512; ++j)
> +	    {
> +	      if (p2[j] != '\1')
> +		{
> +		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
> +			 n, impl->name, align1, align2, len);
> +		  ret = 1;
> +		  break;
> +		}
> +	    }
> +	  if (MEMCMP (p1 + align1, res, len + 1))
> +	    {
> +	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
> +		     n, impl->name, align1, align2, len);
> +	      ret = 1;
> +	    }
> +	}
> +    }
> +}
> +
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%23s", "");
> +  FOR_EACH_IMPL (impl, 0)
> +    printf ("\t%s", impl->name);
> +  putchar ('\n');
> +
> +  for (i = 0; i < 16; ++i)
> +    {
> +      do_test (0, 0, i, SMALL_CHAR);
> +      do_test (0, 0, i, BIG_CHAR);
> +      do_test (0, i, i, SMALL_CHAR);
> +      do_test (i, 0, i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
> +      do_test (2 * i, i, 8 << i, BIG_CHAR);
> +      do_test (i, i, 8 << i, SMALL_CHAR);
> +      do_test (i, i, 8 << i, BIG_CHAR);
> +    }
> +
> +  do_zero_len_test ();
> +  do_random_tests ();
> +
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 0/3] string: Add tests for strdup and strndup (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
                   ` (2 preceding siblings ...)
  2023-03-30 14:50 ` [PATCH v2 0/2] Add tests for strdup and strndup " Joe Simmons-Talbott
@ 2023-04-04 19:00 ` Joe Simmons-Talbott
  2023-04-04 19:00   ` [PATCH v3 1/3] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
                     ` (2 more replies)
  2023-04-10 15:59 ` [PATCH v4 0/4] string: Add tests for strdup and " Joe Simmons-Talbott
                   ` (3 subsequent siblings)
  7 siblings, 3 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-04 19:00 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
tests that checked the surrounding bytes of the result as they are not needed.

Changes to v2: Remove the rest of the ifunc bits.  Mark two variables as
unused so that we can use string/test-string.h for functions that aren't
ifuncs.

Changes to v1: Since strdup and strndup are not ifuncs and likely won't
be, call them directly.  Use TEST_COMPARE_BLOB() rather than memcmp().
Clear up wording in a comment.


Joe Simmons-Talbott (3):
  string: Allow use of test-string.h for non-ifunc implementations.
  string: Add tests for strdup (BZ #30266)
  Add tests for strndup (BZ #30266)

 string/Makefile       |   2 +
 string/test-strdup.c  | 201 +++++++++++++++++++++++++++++++++
 string/test-string.h  |   4 +-
 string/test-strndup.c | 250 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 455 insertions(+), 2 deletions(-)
 create mode 100644 string/test-strdup.c
 create mode 100644 string/test-strndup.c

-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 1/3] string: Allow use of test-string.h for non-ifunc implementations.
  2023-04-04 19:00 ` [PATCH v3 0/3] string: Add tests for strdup and strndup " Joe Simmons-Talbott
@ 2023-04-04 19:00   ` Joe Simmons-Talbott
  2023-04-07 18:19     ` Adhemerval Zanella Netto
  2023-04-04 19:00   ` [PATCH v3 2/3] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
  2023-04-04 19:00   ` [PATCH v3 3/3] string: Add tests for strndup " Joe Simmons-Talbott
  2 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-04 19:00 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Mark two variables as unused to silence warning when using
test-string.h for non-ifunc implemenations.
---
 string/test-string.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/string/test-string.h b/string/test-string.h
index 41de973479..8bcb8afd0a 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -130,8 +130,8 @@ cmdline_process_function (int c)
 /* Increase size of FUNC_LIST if assert is triggered at run-time.  */
 static struct libc_ifunc_impl func_list[32];
 static int func_count;
-static int impl_count = -1;
-static impl_t *impl_array;
+static int impl_count __attribute__ ((unused)) = -1;
+static impl_t *impl_array __attribute__ ((unused));
 
 # define FOR_EACH_IMPL(impl, notall) \
   impl_t *impl;								\
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 2/3] string: Add tests for strdup (BZ #30266)
  2023-04-04 19:00 ` [PATCH v3 0/3] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  2023-04-04 19:00   ` [PATCH v3 1/3] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
@ 2023-04-04 19:00   ` Joe Simmons-Talbott
  2023-04-04 19:17     ` Noah Goldstein
  2023-04-07 18:19     ` Adhemerval Zanella Netto
  2023-04-04 19:00   ` [PATCH v3 3/3] string: Add tests for strndup " Joe Simmons-Talbott
  2 siblings, 2 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-04 19:00 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy tests for strdup.  Covers some basic testcases with random
strings.  Add a zero-length string testcase.
---
 string/Makefile      |   1 +
 string/test-strdup.c | 201 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 202 insertions(+)
 create mode 100644 string/test-strdup.c

diff --git a/string/Makefile b/string/Makefile
index c84b49aaa5..472e318aea 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -157,6 +157,7 @@ tests := \
   test-strcmp \
   test-strcpy \
   test-strcspn \
+  test-strdup \
   test-strlen \
   test-strncasecmp \
   test-strncat \
diff --git a/string/test-strdup.c b/string/test-strdup.c
new file mode 100644
index 0000000000..f45fb4c852
--- /dev/null
+++ b/string/test-strdup.c
@@ -0,0 +1,201 @@
+/* Test and measure strdup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strdup"
+# else
+#  define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define STRDUP strdup
+# else
+#  define STRDUP wcsdup
+# endif
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+  char src[1] = { '\0' };
+  char *dst = STRDUP (src);
+
+  TEST_COMPARE_STRING (dst, src);
+  free(dst);
+}
+
+static void
+do_one_test (const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  char *dst = STRDUP (src);
+
+  if (STRCMP (dst, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     TEST_NAME, dst, src);
+      ret = 1;
+	  free(dst);
+      return;
+    }
+  free(dst);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  do_one_test (s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
+     char test, and thus it will be equal to align times wchar_t size.
+
+     For non wide version we need to check all alignments from 0 to 63
+     since some assembly implementations have separate prolog for alignments
+     more 48.  */
+
+      align1 = random () & (63 / sizeof (CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof (CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+    res = (UCHAR *) STRDUP((CHAR *) p1 + align1);
+	TEST_COMPARE_STRING((CHAR *) res, (CHAR *) (p1 + align1));
+	free(res);
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  printf ("\t%s", TEST_NAME);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_zero_len_test ();
+  do_random_tests ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 3/3] string: Add tests for strndup (BZ #30266)
  2023-04-04 19:00 ` [PATCH v3 0/3] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  2023-04-04 19:00   ` [PATCH v3 1/3] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
  2023-04-04 19:00   ` [PATCH v3 2/3] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-04 19:00   ` Joe Simmons-Talbott
  2023-04-07 18:19     ` Adhemerval Zanella Netto
  2 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-04 19:00 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strncpy tests for strndup.  Covers some basic testcases with random
strings.  Remove tests that set the destination's bytes and checked the
resulting buffer's bytes.
---
 string/Makefile       |   1 +
 string/test-strndup.c | 250 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 251 insertions(+)
 create mode 100644 string/test-strndup.c

diff --git a/string/Makefile b/string/Makefile
index 472e318aea..2eef6f1dfc 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -163,6 +163,7 @@ tests := \
   test-strncat \
   test-strncmp \
   test-strncpy \
+  test-strndup \
   test-strnlen \
   test-strpbrk \
   test-strrchr \
diff --git a/string/test-strndup.c b/string/test-strndup.c
new file mode 100644
index 0000000000..a65373fa96
--- /dev/null
+++ b/string/test-strndup.c
@@ -0,0 +1,250 @@
+/* Test strndup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define STRNLEN wcsnlen
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define MEMCMP memcmp
+# define MEMSET memset
+# define STRNLEN strnlen
+#endif /* !WIDE */
+
+
+#ifndef STRNDUP_RESULT
+# define STRNDUP_RESULT(dst, len, n) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strndup"
+# else
+#  define TEST_NAME "wcsndup"
+# endif /* WIDE */
+# include "test-string.h"
+# ifndef WIDE
+#  define STRNDUP strndup
+# else
+#  define STRNDUP wcsndup
+# endif /* WIDE */
+
+#endif /* !STRNDUP_RESULT */
+
+typedef CHAR *(*proto_t) (const CHAR *, size_t);
+
+static void
+do_one_test (const CHAR *src, size_t len, size_t n)
+{
+  char *dst = STRNDUP(src, n);
+  size_t s = (len > n ? n: len) * sizeof (CHAR);
+
+  TEST_COMPARE_BLOB(dst, s, src, s);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+
+/* For wcsndup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  do_one_test (s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+  CHAR *s1;
+  const size_t maxoffset = 64;
+
+  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
+  s1 = (CHAR *) buf1 + BUF1PAGES * page_size / sizeof(CHAR) - maxoffset;
+  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
+     (maxoffset - 1).  */
+
+  MEMSET (s1, 'a', maxoffset - 1);
+  s1[maxoffset - 1] = '\0';
+
+  /* Both strings are bounded to a page with read/write access and the next
+     page is protected with PROT_NONE (meaning that any access outside of the
+     page regions will trigger an invalid memory access).
+
+     The loop copies the string s1 for all possible offsets up to maxoffset
+     for both inputs with a size larger than s1 (so memory access outside the
+     expected memory regions might trigger invalid access).  */
+
+  for (size_t off1 = 0; off1 < maxoffset; off1++)
+    {
+      for (size_t off2 = 0; off2 < maxoffset; off2++)
+	{
+	  do_one_test (s1 + off1, maxoffset - off1 - 1,
+			 maxoffset + (maxoffset - off2));
+	}
+    }
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcsndup: align1 and align2 here mean align not in bytes,
+	 but in wchar_ts, in bytes it will equal to align * (sizeof
+	 (wchar_t)).  */
+
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+	res = (UCHAR *) STRNDUP ((CHAR *) (p1 + align1), size);
+	j = len + 1;
+	if (size < j)
+	  j = size;
+	if (MEMCMP (p1 + align1, res, j))
+	  {
+	    error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+	       n, "strndup", align1, align2, len);
+	    ret = 1;
+	  }
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  printf ("\t%s", TEST_NAME);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, SMALL_CHAR);
+      do_test (i, i, 16, 16, BIG_CHAR);
+      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
+      do_test (2 * i, i, 16, 16, BIG_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 2/3] string: Add tests for strdup (BZ #30266)
  2023-04-04 19:00   ` [PATCH v3 2/3] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-04 19:17     ` Noah Goldstein
  2023-04-04 19:40       ` Adhemerval Zanella Netto
  2023-04-07 18:19     ` Adhemerval Zanella Netto
  1 sibling, 1 reply; 48+ messages in thread
From: Noah Goldstein @ 2023-04-04 19:17 UTC (permalink / raw)
  To: Joe Simmons-Talbott; +Cc: libc-alpha

On Tue, Apr 4, 2023 at 2:02 PM Joe Simmons-Talbott via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> Copy strcpy tests for strdup.  Covers some basic testcases with random
> strings.  Add a zero-length string testcase.
> ---
>  string/Makefile      |   1 +
>  string/test-strdup.c | 201 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 202 insertions(+)
>  create mode 100644 string/test-strdup.c
>
> diff --git a/string/Makefile b/string/Makefile
> index c84b49aaa5..472e318aea 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -157,6 +157,7 @@ tests := \
>    test-strcmp \
>    test-strcpy \
>    test-strcspn \
> +  test-strdup \
>    test-strlen \
>    test-strncasecmp \
>    test-strncat \
> diff --git a/string/test-strdup.c b/string/test-strdup.c
> new file mode 100644
> index 0000000000..f45fb4c852
> --- /dev/null
> +++ b/string/test-strdup.c
> @@ -0,0 +1,201 @@
> +/* Test and measure strdup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <support/check.h>
> +
> +#ifdef WIDE
> +# include <wchar.h>
> +# define CHAR wchar_t
> +# define UCHAR wchar_t
> +# define sfmt "ls"
> +# define BIG_CHAR WCHAR_MAX
> +# define SMALL_CHAR 1273
> +# define STRCMP wcscmp
> +# define MEMCMP wmemcmp
> +# define MEMSET wmemset
> +#else
> +# define CHAR char
> +# define UCHAR unsigned char
> +# define sfmt "s"
> +# define BIG_CHAR CHAR_MAX
> +# define SMALL_CHAR 127
> +# define STRCMP strcmp
> +# define MEMCMP memcmp
> +# define MEMSET memset
> +#endif
> +
> +#ifndef STRDUP_RESULT
> +# define STRDUP_RESULT(dst, len) dst
> +# define TEST_MAIN
> +# ifndef WIDE
> +#  define TEST_NAME "strdup"
> +# else
> +#  define TEST_NAME "wcsdup"
> +# endif
> +# include "test-string.h"
> +# ifndef WIDE
> +#  define STRDUP strdup
> +# else
> +#  define STRDUP wcsdup
> +# endif
> +#endif
> +
> +typedef CHAR *(*proto_t) (const CHAR *);
> +
> +static void
> +do_zero_len_test (void)
> +{
> +  char src[1] = { '\0' };
> +  char *dst = STRDUP (src);
> +
> +  TEST_COMPARE_STRING (dst, src);
> +  free(dst);
> +}
> +
> +static void
> +do_one_test (const CHAR *src,
> +            size_t len __attribute__((unused)))
> +{
> +  char *dst = STRDUP (src);
> +
> +  if (STRCMP (dst, src) != 0)
> +    {
> +      error (0, 0,
> +            "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
> +            TEST_NAME, dst, src);
> +      ret = 1;
> +         free(dst);
> +      return;
> +    }
> +  free(dst);
> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +/* For wcsdup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
> +   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; i++)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +
> +  do_one_test (s1, len);
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
> +     char test, and thus it will be equal to align times wchar_t size.
> +
> +     For non wide version we need to check all alignments from 0 to 63
> +     since some assembly implementations have separate prolog for alignments
> +     more 48.  */
> +
> +      align1 = random () & (63 / sizeof (CHAR));
> +      if (random () & 1)
> +       align2 = random () & (63 / sizeof (CHAR));
> +      else
> +       align2 = align1 + (random () & 24);
> +      len = random () & 511;
> +      j = align1;
> +      if (align2 > j)
> +       j = align2;
> +      if (len + j >= 511)
> +       len = 510 - j - (random () & 7);
> +      j = len + align1 + 64;
> +      if (j > 512)
> +       j = 512;
> +      for (i = 0; i < j; i++)
> +       {
> +         if (i == len + align1)
> +           p1[i] = 0;
> +         else
> +           {
> +             p1[i] = random () & BIG_CHAR;
> +             if (i >= align1 && i < len + align1 && !p1[i])
> +               p1[i] = (random () & SMALL_CHAR) + 3;
> +           }
> +       }
> +
> +    res = (UCHAR *) STRDUP((CHAR *) p1 + align1);
> +       TEST_COMPARE_STRING((CHAR *) res, (CHAR *) (p1 + align1));
> +       free(res);
> +    }
> +}
> +
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%23s", "");
> +  printf ("\t%s", TEST_NAME);
> +  putchar ('\n');
> +
> +  for (i = 0; i < 16; ++i)
> +    {
> +      do_test (0, 0, i, SMALL_CHAR);
> +      do_test (0, 0, i, BIG_CHAR);
> +      do_test (0, i, i, SMALL_CHAR);
> +      do_test (i, 0, i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
> +      do_test (2 * i, i, 8 << i, BIG_CHAR);
> +      do_test (i, i, 8 << i, SMALL_CHAR);
> +      do_test (i, i, 8 << i, BIG_CHAR);
> +    }
> +
> +  do_zero_len_test ();
> +  do_random_tests ();
> +
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>
> --
> 2.39.2
>
What about including test-strcpy and just creating macros for FREE?

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 2/3] string: Add tests for strdup (BZ #30266)
  2023-04-04 19:17     ` Noah Goldstein
@ 2023-04-04 19:40       ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-04 19:40 UTC (permalink / raw)
  To: libc-alpha, Noah Goldstein



On 04/04/23 16:17, Noah Goldstein via Libc-alpha wrote:


> What about including test-strcpy and just creating macros for FREE?

test-strcpy add extra complexity to handle ifunc and uses an external
mmap buffer to check of OOB access, which for strdup does not add much.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 1/3] string: Allow use of test-string.h for non-ifunc implementations.
  2023-04-04 19:00   ` [PATCH v3 1/3] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
@ 2023-04-07 18:19     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-07 18:19 UTC (permalink / raw)
  To: Joe Simmons-Talbott, libc-alpha



On 04/04/23 16:00, Joe Simmons-Talbott via Libc-alpha wrote:
> Mark two variables as unused to silence warning when using
> test-string.h for non-ifunc implemenations.

s/implemenations/implementations

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  string/test-string.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/string/test-string.h b/string/test-string.h
> index 41de973479..8bcb8afd0a 100644
> --- a/string/test-string.h
> +++ b/string/test-string.h
> @@ -130,8 +130,8 @@ cmdline_process_function (int c)
>  /* Increase size of FUNC_LIST if assert is triggered at run-time.  */
>  static struct libc_ifunc_impl func_list[32];
>  static int func_count;
> -static int impl_count = -1;
> -static impl_t *impl_array;
> +static int impl_count __attribute__ ((unused)) = -1;
> +static impl_t *impl_array __attribute__ ((unused));
>  
>  # define FOR_EACH_IMPL(impl, notall) \
>    impl_t *impl;								\

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 2/3] string: Add tests for strdup (BZ #30266)
  2023-04-04 19:00   ` [PATCH v3 2/3] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
  2023-04-04 19:17     ` Noah Goldstein
@ 2023-04-07 18:19     ` Adhemerval Zanella Netto
  2023-04-10 13:53       ` Joe Simmons-Talbott
  1 sibling, 1 reply; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-07 18:19 UTC (permalink / raw)
  To: libc-alpha, Joe Simmons-Talbott



On 04/04/23 16:00, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strcpy tests for strdup.  Covers some basic testcases with random
> strings.  Add a zero-length string testcase.

Just minor style issue.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  string/Makefile      |   1 +
>  string/test-strdup.c | 201 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 202 insertions(+)
>  create mode 100644 string/test-strdup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index c84b49aaa5..472e318aea 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -157,6 +157,7 @@ tests := \
>    test-strcmp \
>    test-strcpy \
>    test-strcspn \
> +  test-strdup \
>    test-strlen \
>    test-strncasecmp \
>    test-strncat \
> diff --git a/string/test-strdup.c b/string/test-strdup.c
> new file mode 100644
> index 0000000000..f45fb4c852
> --- /dev/null
> +++ b/string/test-strdup.c
> @@ -0,0 +1,201 @@
> +/* Test and measure strdup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <support/check.h>
> +
> +#ifdef WIDE
> +# include <wchar.h>
> +# define CHAR wchar_t
> +# define UCHAR wchar_t
> +# define sfmt "ls"
> +# define BIG_CHAR WCHAR_MAX
> +# define SMALL_CHAR 1273
> +# define STRCMP wcscmp
> +# define MEMCMP wmemcmp
> +# define MEMSET wmemset
> +#else
> +# define CHAR char
> +# define UCHAR unsigned char
> +# define sfmt "s"
> +# define BIG_CHAR CHAR_MAX
> +# define SMALL_CHAR 127
> +# define STRCMP strcmp
> +# define MEMCMP memcmp
> +# define MEMSET memset
> +#endif

Do you plan to add wcsdup tests as well?

> +
> +#ifndef STRDUP_RESULT
> +# define STRDUP_RESULT(dst, len) dst
> +# define TEST_MAIN
> +# ifndef WIDE
> +#  define TEST_NAME "strdup"
> +# else
> +#  define TEST_NAME "wcsdup"
> +# endif
> +# include "test-string.h"
> +# ifndef WIDE
> +#  define STRDUP strdup
> +# else
> +#  define STRDUP wcsdup
> +# endif
> +#endif
> +
> +typedef CHAR *(*proto_t) (const CHAR *);
> +
> +static void
> +do_zero_len_test (void)
> +{
> +  char src[1] = { '\0' };
> +  char *dst = STRDUP (src);
> +
> +  TEST_COMPARE_STRING (dst, src);
> +  free(dst);
> +}
> +
> +static void
> +do_one_test (const CHAR *src,
> +	     size_t len __attribute__((unused)))
> +{
> +  char *dst = STRDUP (src);
> +
> +  if (STRCMP (dst, src) != 0)
> +    {
> +      error (0, 0,
> +	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
> +	     TEST_NAME, dst, src);
> +      ret = 1;
> +	  free(dst);

Indentation seems off here.

> +      return;
> +    }
> +  free(dst);
> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +/* For wcsdup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
> +   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; i++)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +
> +  do_one_test (s1, len);
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
> +     char test, and thus it will be equal to align times wchar_t size.
> +
> +     For non wide version we need to check all alignments from 0 to 63
> +     since some assembly implementations have separate prolog for alignments
> +     more 48.  */
> +
> +      align1 = random () & (63 / sizeof (CHAR));
> +      if (random () & 1)
> +	align2 = random () & (63 / sizeof (CHAR));
> +      else
> +	align2 = align1 + (random () & 24);
> +      len = random () & 511;
> +      j = align1;
> +      if (align2 > j)
> +	j = align2;
> +      if (len + j >= 511)
> +	len = 510 - j - (random () & 7);
> +      j = len + align1 + 64;
> +      if (j > 512)
> +	j = 512;
> +      for (i = 0; i < j; i++)
> +	{
> +	  if (i == len + align1)
> +	    p1[i] = 0;
> +	  else
> +	    {
> +	      p1[i] = random () & BIG_CHAR;
> +	      if (i >= align1 && i < len + align1 && !p1[i])
> +		p1[i] = (random () & SMALL_CHAR) + 3;
> +	    }
> +	}
> +
> +    res = (UCHAR *) STRDUP((CHAR *) p1 + align1);

Indentation seems off.

> +	TEST_COMPARE_STRING((CHAR *) res, (CHAR *) (p1 + align1));
> +	free(res);

Missing space before '('.

> +    }
> +}
> +
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%23s", "");
> +  printf ("\t%s", TEST_NAME);
> +  putchar ('\n');
> +
> +  for (i = 0; i < 16; ++i)
> +    {
> +      do_test (0, 0, i, SMALL_CHAR);
> +      do_test (0, 0, i, BIG_CHAR);
> +      do_test (0, i, i, SMALL_CHAR);
> +      do_test (i, 0, i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
> +      do_test (2 * i, i, 8 << i, BIG_CHAR);
> +      do_test (i, i, 8 << i, SMALL_CHAR);
> +      do_test (i, i, 8 << i, BIG_CHAR);
> +    }
> +
> +  do_zero_len_test ();
> +  do_random_tests ();
> +
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 3/3] string: Add tests for strndup (BZ #30266)
  2023-04-04 19:00   ` [PATCH v3 3/3] string: Add tests for strndup " Joe Simmons-Talbott
@ 2023-04-07 18:19     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-07 18:19 UTC (permalink / raw)
  To: libc-alpha, Joe Simmons-Talbott



On 04/04/23 16:00, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strncpy tests for strndup.  Covers some basic testcases with random
> strings.  Remove tests that set the destination's bytes and checked the
> resulting buffer's bytes.
> ---
>  string/Makefile       |   1 +
>  string/test-strndup.c | 250 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 251 insertions(+)
>  create mode 100644 string/test-strndup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index 472e318aea..2eef6f1dfc 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -163,6 +163,7 @@ tests := \
>    test-strncat \
>    test-strncmp \
>    test-strncpy \
> +  test-strndup \
>    test-strnlen \
>    test-strpbrk \
>    test-strrchr \
> diff --git a/string/test-strndup.c b/string/test-strndup.c
> new file mode 100644
> index 0000000000..a65373fa96
> --- /dev/null
> +++ b/string/test-strndup.c
> @@ -0,0 +1,250 @@
> +/* Test strndup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <support/check.h>
> +
> +#ifdef WIDE
> +# include <wchar.h>
> +# define CHAR wchar_t
> +# define UCHAR wchar_t
> +# define BIG_CHAR WCHAR_MAX
> +# define SMALL_CHAR 1273
> +# define MEMCMP wmemcmp
> +# define MEMSET wmemset
> +# define STRNLEN wcsnlen
> +#else
> +# define CHAR char
> +# define UCHAR unsigned char
> +# define BIG_CHAR CHAR_MAX
> +# define SMALL_CHAR 127
> +# define MEMCMP memcmp
> +# define MEMSET memset
> +# define STRNLEN strnlen
> +#endif /* !WIDE */
> +

We don't have wcsndup, so I think you can just simplify it to support 'char'.

> +
> +#ifndef STRNDUP_RESULT
> +# define STRNDUP_RESULT(dst, len, n) dst
> +# define TEST_MAIN
> +# ifndef WIDE
> +#  define TEST_NAME "strndup"
> +# else
> +#  define TEST_NAME "wcsndup"
> +# endif /* WIDE */
> +# include "test-string.h"
> +# ifndef WIDE
> +#  define STRNDUP strndup
> +# else
> +#  define STRNDUP wcsndup
> +# endif /* WIDE */
> +
> +#endif /* !STRNDUP_RESULT */
> +
> +typedef CHAR *(*proto_t) (const CHAR *, size_t);

There is no need of this typedef.

> +
> +static void
> +do_one_test (const CHAR *src, size_t len, size_t n)
> +{
> +  char *dst = STRNDUP(src, n);
> +  size_t s = (len > n ? n: len) * sizeof (CHAR);
> +
> +  TEST_COMPARE_BLOB(dst, s, src, s);
> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +
> +/* For wcsndup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; ++i)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
> +       ++i)
> +    s1[i] = 32 + 32 * i % (max_char - 32);
> +
> +  do_one_test (s1, len, n);
> +}
> +
> +static void
> +do_page_tests (void)
> +{
> +  CHAR *s1;
> +  const size_t maxoffset = 64;
> +
> +  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
> +  s1 = (CHAR *) buf1 + BUF1PAGES * page_size / sizeof(CHAR) - maxoffset;
> +  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
> +     (maxoffset - 1).  */
> +
> +  MEMSET (s1, 'a', maxoffset - 1);
> +  s1[maxoffset - 1] = '\0';
> +
> +  /* Both strings are bounded to a page with read/write access and the next
> +     page is protected with PROT_NONE (meaning that any access outside of the
> +     page regions will trigger an invalid memory access).
> +
> +     The loop copies the string s1 for all possible offsets up to maxoffset
> +     for both inputs with a size larger than s1 (so memory access outside the
> +     expected memory regions might trigger invalid access).  */
> +
> +  for (size_t off1 = 0; off1 < maxoffset; off1++)
> +    {
> +      for (size_t off2 = 0; off2 < maxoffset; off2++)
> +	{
> +	  do_one_test (s1 + off1, maxoffset - off1 - 1,
> +			 maxoffset + (maxoffset - off2));
> +	}
> +    }
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len, size, mode;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* For wcsndup: align1 and align2 here mean align not in bytes,
> +	 but in wchar_ts, in bytes it will equal to align * (sizeof
> +	 (wchar_t)).  */
> +
> +      mode = random ();
> +      if (mode & 1)
> +	{
> +	  size = random () & 255;
> +	  align1 = 512 - size - (random () & 15);
> +	  if (mode & 2)
> +	    align2 = align1 - (random () & 24);
> +	  else
> +	    align2 = align1 - (random () & 31);
> +	  if (mode & 4)
> +	    {
> +	      j = align1;
> +	      align1 = align2;
> +	      align2 = j;
> +	    }
> +	  if (mode & 8)
> +	    len = size - (random () & 31);
> +	  else
> +	    len = 512;
> +	  if (len >= 512)
> +	    len = random () & 511;
> +	}
> +      else
> +	{
> +	  align1 = random () & 31;
> +	  if (mode & 2)
> +	    align2 = random () & 31;
> +	  else
> +	    align2 = align1 + (random () & 24);
> +	  len = random () & 511;
> +	  j = align1;
> +	  if (align2 > j)
> +	    j = align2;
> +	  if (mode & 4)
> +	    {
> +	      size = random () & 511;
> +	      if (size + j > 512)
> +		size = 512 - j - (random () & 31);
> +	    }
> +	  else
> +	    size = 512 - j;
> +	  if ((mode & 8) && len + j >= 512)
> +	    len = 512 - j - (random () & 7);
> +	}
> +      j = len + align1 + 64;
> +      if (j > 512)
> +	j = 512;
> +      for (i = 0; i < j; i++)
> +	{
> +	  if (i == len + align1)
> +	    p1[i] = 0;
> +	  else
> +	    {
> +	      p1[i] = random () & BIG_CHAR;
> +	      if (i >= align1 && i < len + align1 && !p1[i])
> +		p1[i] = (random () & SMALL_CHAR) + 3;
> +	    }
> +	}
> +
> +	res = (UCHAR *) STRNDUP ((CHAR *) (p1 + align1), size);
> +	j = len + 1;
> +	if (size < j)
> +	  j = size;
> +	if (MEMCMP (p1 + align1, res, j))
> +	  {
> +	    error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
> +	       n, "strndup", align1, align2, len);
> +	    ret = 1;
> +	  }
> +    }

You can use TEST_COMPARE_BLOB here:

   res = strndup ((CHAR *) (p1 + align1), size);
   TEST_COMPARE_BLOB (res, size, (CHAR *) (p1 + align1), size);
   free (res);

> +}
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%28s", "");
> +  printf ("\t%s", TEST_NAME);
> +  putchar ('\n');
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, i, 16, 16, SMALL_CHAR);
> +      do_test (i, i, 16, 16, BIG_CHAR);
> +      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
> +      do_test (2 * i, i, 16, 16, BIG_CHAR);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
> +      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  do_random_tests ();
> +  do_page_tests ();
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 2/3] string: Add tests for strdup (BZ #30266)
  2023-04-07 18:19     ` Adhemerval Zanella Netto
@ 2023-04-10 13:53       ` Joe Simmons-Talbott
  2023-04-10 14:44         ` Adhemerval Zanella Netto
  0 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-10 13:53 UTC (permalink / raw)
  To: Adhemerval Zanella Netto; +Cc: libc-alpha

On Fri, Apr 07, 2023 at 03:19:38PM -0300, Adhemerval Zanella Netto wrote:
> 
> 
> On 04/04/23 16:00, Joe Simmons-Talbott via Libc-alpha wrote:
> > Copy strcpy tests for strdup.  Covers some basic testcases with random
> > strings.  Add a zero-length string testcase.
> 
> Just minor style issue.
> 
> LGTM, thanks.
> 
> Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
> 
> > ---
> >  string/Makefile      |   1 +
> >  string/test-strdup.c | 201 +++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 202 insertions(+)
> >  create mode 100644 string/test-strdup.c
> > 
> > diff --git a/string/Makefile b/string/Makefile
> > index c84b49aaa5..472e318aea 100644
> > --- a/string/Makefile
> > +++ b/string/Makefile
> > @@ -157,6 +157,7 @@ tests := \
> >    test-strcmp \
> >    test-strcpy \
> >    test-strcspn \
> > +  test-strdup \
> >    test-strlen \
> >    test-strncasecmp \
> >    test-strncat \
> > diff --git a/string/test-strdup.c b/string/test-strdup.c
> > new file mode 100644
> > index 0000000000..f45fb4c852
> > --- /dev/null
> > +++ b/string/test-strdup.c
> > @@ -0,0 +1,201 @@
> > +/* Test and measure strdup functions.
> > +   Copyright (C) 2023 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later version.
> > +
> > +   The GNU C Library is distributed in the hope that it will be useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <https://www.gnu.org/licenses/>.  */
> > +
> > +#include <support/check.h>
> > +
> > +#ifdef WIDE
> > +# include <wchar.h>
> > +# define CHAR wchar_t
> > +# define UCHAR wchar_t
> > +# define sfmt "ls"
> > +# define BIG_CHAR WCHAR_MAX
> > +# define SMALL_CHAR 1273
> > +# define STRCMP wcscmp
> > +# define MEMCMP wmemcmp
> > +# define MEMSET wmemset
> > +#else
> > +# define CHAR char
> > +# define UCHAR unsigned char
> > +# define sfmt "s"
> > +# define BIG_CHAR CHAR_MAX
> > +# define SMALL_CHAR 127
> > +# define STRCMP strcmp
> > +# define MEMCMP memcmp
> > +# define MEMSET memset
> > +#endif
> 
> Do you plan to add wcsdup tests as well?

I assumed the above would cover that as well.  Do I need to indicate in
the Makefile to run these tests with and without WIDE defined?  Does
TEST_COMPARE_STRING handle wide strings as well?

Thanks,
Joe


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 2/3] string: Add tests for strdup (BZ #30266)
  2023-04-10 13:53       ` Joe Simmons-Talbott
@ 2023-04-10 14:44         ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-10 14:44 UTC (permalink / raw)
  To: Joe Simmons-Talbott; +Cc: libc-alpha



On 10/04/23 10:53, Joe Simmons-Talbott wrote:
> On Fri, Apr 07, 2023 at 03:19:38PM -0300, Adhemerval Zanella Netto wrote:
>>
>>
>> On 04/04/23 16:00, Joe Simmons-Talbott via Libc-alpha wrote:
>>> Copy strcpy tests for strdup.  Covers some basic testcases with random
>>> strings.  Add a zero-length string testcase.
>>
>> Just minor style issue.
>>
>> LGTM, thanks.
>>
>> Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
>>
>>> ---
>>>  string/Makefile      |   1 +
>>>  string/test-strdup.c | 201 +++++++++++++++++++++++++++++++++++++++++++
>>>  2 files changed, 202 insertions(+)
>>>  create mode 100644 string/test-strdup.c
>>>
>>> diff --git a/string/Makefile b/string/Makefile
>>> index c84b49aaa5..472e318aea 100644
>>> --- a/string/Makefile
>>> +++ b/string/Makefile
>>> @@ -157,6 +157,7 @@ tests := \
>>>    test-strcmp \
>>>    test-strcpy \
>>>    test-strcspn \
>>> +  test-strdup \
>>>    test-strlen \
>>>    test-strncasecmp \
>>>    test-strncat \
>>> diff --git a/string/test-strdup.c b/string/test-strdup.c
>>> new file mode 100644
>>> index 0000000000..f45fb4c852
>>> --- /dev/null
>>> +++ b/string/test-strdup.c
>>> @@ -0,0 +1,201 @@
>>> +/* Test and measure strdup functions.
>>> +   Copyright (C) 2023 Free Software Foundation, Inc.
>>> +   This file is part of the GNU C Library.
>>> +
>>> +   The GNU C Library is free software; you can redistribute it and/or
>>> +   modify it under the terms of the GNU Lesser General Public
>>> +   License as published by the Free Software Foundation; either
>>> +   version 2.1 of the License, or (at your option) any later version.
>>> +
>>> +   The GNU C Library is distributed in the hope that it will be useful,
>>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> +   Lesser General Public License for more details.
>>> +
>>> +   You should have received a copy of the GNU Lesser General Public
>>> +   License along with the GNU C Library; if not, see
>>> +   <https://www.gnu.org/licenses/>.  */
>>> +
>>> +#include <support/check.h>
>>> +
>>> +#ifdef WIDE
>>> +# include <wchar.h>
>>> +# define CHAR wchar_t
>>> +# define UCHAR wchar_t
>>> +# define sfmt "ls"
>>> +# define BIG_CHAR WCHAR_MAX
>>> +# define SMALL_CHAR 1273
>>> +# define STRCMP wcscmp
>>> +# define MEMCMP wmemcmp
>>> +# define MEMSET wmemset
>>> +#else
>>> +# define CHAR char
>>> +# define UCHAR unsigned char
>>> +# define sfmt "s"
>>> +# define BIG_CHAR CHAR_MAX
>>> +# define SMALL_CHAR 127
>>> +# define STRCMP strcmp
>>> +# define MEMCMP memcmp
>>> +# define MEMSET memset
>>> +#endif
>>
>> Do you plan to add wcsdup tests as well?
> 
> I assumed the above would cover that as well.  Do I need to indicate in
> the Makefile to run these tests with and without WIDE defined?  Does
> TEST_COMPARE_STRING handle wide strings as well?

You need to actually enable by adding it on wcsmbs/Makefile.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 0/4] string: Add tests for strdup and strndup (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
                   ` (3 preceding siblings ...)
  2023-04-04 19:00 ` [PATCH v3 0/3] string: Add tests for strdup and strndup " Joe Simmons-Talbott
@ 2023-04-10 15:59 ` Joe Simmons-Talbott
  2023-04-10 15:59   ` [PATCH v4 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
                     ` (3 more replies)
  2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
                   ` (2 subsequent siblings)
  7 siblings, 4 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-10 15:59 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
tests that checked the surrounding bytes of the result as they are not needed.

Changes to v3:
  * string/test-strdup.c - Style cleanup.  Make sure we're using CHAR
    rather than char for wide character support.
  * string/test-strndup.c - Remove unneeded wide character support since
    there is no wcsndup().  Use TEST_COMPARE_BLOB rather than memcmp().
  * wcsmbs - Enable wcsdup() testcases.

Changes to v2: Remove the rest of the ifunc bits.  Mark two variables as
unused so that we can use string/test-string.h for functions that aren't
ifuncs.

Changes to v1: Since strdup and strndup are not ifuncs and likely won't
be, call them directly.  Use TEST_COMPARE_BLOB() rather than memcmp().
Clear up wording in a comment.

Joe Simmons-Talbott (3):
  string: Allow use of test-string.h for non-ifunc implementations.
  string: Add tests for strdup (BZ #30266)
  string: Add tests for strndup (BZ #30266)

 string/Makefile       |   2 +
 string/test-strdup.c  | 203 ++++++++++++++++++++++++++++++++++++++
 string/test-string.h  |   4 +-
 string/test-strndup.c | 222 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 429 insertions(+), 2 deletions(-)
 create mode 100644 string/test-strdup.c
 create mode 100644 string/test-strndup.c

-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 1/4] string: Allow use of test-string.h for non-ifunc implementations.
  2023-04-10 15:59 ` [PATCH v4 0/4] string: Add tests for strdup and " Joe Simmons-Talbott
@ 2023-04-10 15:59   ` Joe Simmons-Talbott
  2023-04-10 15:59   ` [PATCH v4 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-10 15:59 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Mark two variables as unused to silence warning when using
test-string.h for non-ifunc implementations.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 string/test-string.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/string/test-string.h b/string/test-string.h
index 41de973479..8bcb8afd0a 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -130,8 +130,8 @@ cmdline_process_function (int c)
 /* Increase size of FUNC_LIST if assert is triggered at run-time.  */
 static struct libc_ifunc_impl func_list[32];
 static int func_count;
-static int impl_count = -1;
-static impl_t *impl_array;
+static int impl_count __attribute__ ((unused)) = -1;
+static impl_t *impl_array __attribute__ ((unused));
 
 # define FOR_EACH_IMPL(impl, notall) \
   impl_t *impl;								\
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 2/4] string: Add tests for strdup (BZ #30266)
  2023-04-10 15:59 ` [PATCH v4 0/4] string: Add tests for strdup and " Joe Simmons-Talbott
  2023-04-10 15:59   ` [PATCH v4 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
@ 2023-04-10 15:59   ` Joe Simmons-Talbott
  2023-04-11 16:57     ` Adhemerval Zanella Netto
  2023-04-10 15:59   ` [PATCH v4 3/4] string: Add tests for strndup " Joe Simmons-Talbott
  2023-04-10 15:59   ` [PATCH v4 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
  3 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-10 15:59 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy tests for strdup.  Covers some basic testcases with random
strings.  Add a zero-length string testcase.
---
 string/Makefile      |   1 +
 string/test-strdup.c | 203 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 204 insertions(+)
 create mode 100644 string/test-strdup.c

diff --git a/string/Makefile b/string/Makefile
index c84b49aaa5..472e318aea 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -157,6 +157,7 @@ tests := \
   test-strcmp \
   test-strcpy \
   test-strcspn \
+  test-strdup \
   test-strlen \
   test-strncasecmp \
   test-strncat \
diff --git a/string/test-strdup.c b/string/test-strdup.c
new file mode 100644
index 0000000000..8a1a267782
--- /dev/null
+++ b/string/test-strdup.c
@@ -0,0 +1,203 @@
+/* Test and measure strdup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define TCS TEST_COMPARE_STRING_WIDE
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+# define TCS TEST_COMPARE_STRING
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strdup"
+# else
+#  define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define STRDUP strdup
+# else
+#  define STRDUP wcsdup
+# endif
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+  CHAR src[1] = { '\0' };
+  CHAR *dst = STRDUP (src);
+
+  TCS (dst, src);
+  free (dst);
+}
+
+static void
+do_one_test (const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  CHAR *dst = STRDUP (src);
+
+  if (STRCMP (dst, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     TEST_NAME, dst, src);
+      ret = 1;
+      free (dst);
+      return;
+    }
+  free (dst);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  do_one_test (s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
+     char test, and thus it will be equal to align times wchar_t size.
+
+     For non wide version we need to check all alignments from 0 to 63
+     since some assembly implementations have separate prolog for alignments
+     more 48.  */
+
+      align1 = random () & (63 / sizeof (CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof (CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      res = (UCHAR *) STRDUP((CHAR *) p1 + align1);
+      TCS ((CHAR *) res, (CHAR *) (p1 + align1));
+      free (res);
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  printf ("\t%s", TEST_NAME);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_zero_len_test ();
+  do_random_tests ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 3/4] string: Add tests for strndup (BZ #30266)
  2023-04-10 15:59 ` [PATCH v4 0/4] string: Add tests for strdup and " Joe Simmons-Talbott
  2023-04-10 15:59   ` [PATCH v4 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
  2023-04-10 15:59   ` [PATCH v4 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-10 15:59   ` Joe Simmons-Talbott
  2023-04-11 17:29     ` Adhemerval Zanella Netto
  2023-04-10 15:59   ` [PATCH v4 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
  3 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-10 15:59 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strncpy tests for strndup.  Covers some basic testcases with random
strings.  Remove tests that set the destination's bytes and checked the
resulting buffer's bytes.  Remove wide character test support since
wcsndup() doesn't exist.
---
 string/Makefile       |   1 +
 string/test-strndup.c | 222 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 223 insertions(+)
 create mode 100644 string/test-strndup.c

diff --git a/string/Makefile b/string/Makefile
index 472e318aea..2eef6f1dfc 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -163,6 +163,7 @@ tests := \
   test-strncat \
   test-strncmp \
   test-strncpy \
+  test-strndup \
   test-strnlen \
   test-strpbrk \
   test-strrchr \
diff --git a/string/test-strndup.c b/string/test-strndup.c
new file mode 100644
index 0000000000..b5665a3eec
--- /dev/null
+++ b/string/test-strndup.c
@@ -0,0 +1,222 @@
+/* Test strndup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#define CHAR char
+#define UCHAR unsigned char
+#define BIG_CHAR CHAR_MAX
+#define SMALL_CHAR 127
+#define MEMSET memset
+
+
+#ifndef STRNDUP_RESULT
+# define STRNDUP_RESULT(dst, len, n) dst
+# define TEST_MAIN
+# define TEST_NAME "strndup"
+# include "test-string.h"
+
+#endif /* !STRNDUP_RESULT */
+
+static void
+do_one_test (const CHAR *src, size_t len, size_t n)
+{
+  CHAR *dst = strndup(src, n);
+  size_t s = (len > n ? n: len) * sizeof (CHAR);
+
+  TEST_COMPARE_BLOB(dst, s, src, s);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+
+/* For wcsndup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  do_one_test (s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+  CHAR *s1;
+  const size_t maxoffset = 64;
+
+  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
+  s1 = (CHAR *) buf1 + BUF1PAGES * page_size / sizeof(CHAR) - maxoffset;
+  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
+     (maxoffset - 1).  */
+
+  MEMSET (s1, 'a', maxoffset - 1);
+  s1[maxoffset - 1] = '\0';
+
+  /* Both strings are bounded to a page with read/write access and the next
+     page is protected with PROT_NONE (meaning that any access outside of the
+     page regions will trigger an invalid memory access).
+
+     The loop copies the string s1 for all possible offsets up to maxoffset
+     for both inputs with a size larger than s1 (so memory access outside the
+     expected memory regions might trigger invalid access).  */
+
+  for (size_t off1 = 0; off1 < maxoffset; off1++)
+    {
+      for (size_t off2 = 0; off2 < maxoffset; off2++)
+	{
+	  do_one_test (s1 + off1, maxoffset - off1 - 1,
+			 maxoffset + (maxoffset - off2));
+	}
+    }
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* For wcsndup: align1 and align2 here mean align not in bytes,
+	 but in wchar_ts, in bytes it will equal to align * (sizeof
+	 (wchar_t)).  */
+
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+	res = (UCHAR *) strndup ((CHAR *) (p1 + align1), size);
+	j = len + 1;
+	if (size < j)
+	  j = size;
+	TEST_COMPARE_BLOB (res, j, (CHAR *) (p1 + align1), j);
+	free (res);
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  printf ("\t%s", TEST_NAME);
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, SMALL_CHAR);
+      do_test (i, i, 16, 16, BIG_CHAR);
+      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
+      do_test (2 * i, i, 16, 16, BIG_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 4/4] wcsmbs: Add wcsdup() tests.  (BZ #30266)
  2023-04-10 15:59 ` [PATCH v4 0/4] string: Add tests for strdup and " Joe Simmons-Talbott
                     ` (2 preceding siblings ...)
  2023-04-10 15:59   ` [PATCH v4 3/4] string: Add tests for strndup " Joe Simmons-Talbott
@ 2023-04-10 15:59   ` Joe Simmons-Talbott
  2023-04-11 17:30     ` Adhemerval Zanella Netto
  3 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-10 15:59 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Enable wide character testcases for wcsdup().
---
 wcsmbs/Makefile      | 2 +-
 wcsmbs/test-wcsdup.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 wcsmbs/test-wcsdup.c

diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index b12a3b0750..bd39335b0e 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -49,7 +49,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
-		wcscspn wmemchr wmemset
+		wcscspn wmemchr wmemset wcsdup
 tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
 	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
 	 tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
diff --git a/wcsmbs/test-wcsdup.c b/wcsmbs/test-wcsdup.c
new file mode 100644
index 0000000000..e39e063d0b
--- /dev/null
+++ b/wcsmbs/test-wcsdup.c
@@ -0,0 +1,2 @@
+#define WIDE 1
+#include "../string/test-strdup.c"
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v4 2/4] string: Add tests for strdup (BZ #30266)
  2023-04-10 15:59   ` [PATCH v4 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-11 16:57     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-11 16:57 UTC (permalink / raw)
  To: Joe Simmons-Talbott, libc-alpha



On 10/04/23 12:59, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strcpy tests for strdup.  Covers some basic testcases with random
> strings.  Add a zero-length string testcase.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  string/Makefile      |   1 +
>  string/test-strdup.c | 203 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 204 insertions(+)
>  create mode 100644 string/test-strdup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index c84b49aaa5..472e318aea 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -157,6 +157,7 @@ tests := \
>    test-strcmp \
>    test-strcpy \
>    test-strcspn \
> +  test-strdup \
>    test-strlen \
>    test-strncasecmp \
>    test-strncat \
> diff --git a/string/test-strdup.c b/string/test-strdup.c
> new file mode 100644
> index 0000000000..8a1a267782
> --- /dev/null
> +++ b/string/test-strdup.c
> @@ -0,0 +1,203 @@
> +/* Test and measure strdup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <support/check.h>
> +
> +#ifdef WIDE
> +# include <wchar.h>
> +# define CHAR wchar_t
> +# define UCHAR wchar_t
> +# define sfmt "ls"
> +# define BIG_CHAR WCHAR_MAX
> +# define SMALL_CHAR 1273
> +# define STRCMP wcscmp
> +# define MEMCMP wmemcmp
> +# define MEMSET wmemset
> +# define TCS TEST_COMPARE_STRING_WIDE
> +#else
> +# define CHAR char
> +# define UCHAR unsigned char
> +# define sfmt "s"
> +# define BIG_CHAR CHAR_MAX
> +# define SMALL_CHAR 127
> +# define STRCMP strcmp
> +# define MEMCMP memcmp
> +# define MEMSET memset
> +# define TCS TEST_COMPARE_STRING
> +#endif
> +
> +#ifndef STRDUP_RESULT
> +# define STRDUP_RESULT(dst, len) dst
> +# define TEST_MAIN
> +# ifndef WIDE
> +#  define TEST_NAME "strdup"
> +# else
> +#  define TEST_NAME "wcsdup"
> +# endif
> +# include "test-string.h"
> +# ifndef WIDE
> +#  define STRDUP strdup
> +# else
> +#  define STRDUP wcsdup
> +# endif
> +#endif
> +
> +typedef CHAR *(*proto_t) (const CHAR *);
> +
> +static void
> +do_zero_len_test (void)
> +{
> +  CHAR src[1] = { '\0' };
> +  CHAR *dst = STRDUP (src);
> +
> +  TCS (dst, src);
> +  free (dst);
> +}
> +
> +static void
> +do_one_test (const CHAR *src,
> +	     size_t len __attribute__((unused)))
> +{
> +  CHAR *dst = STRDUP (src);
> +
> +  if (STRCMP (dst, src) != 0)
> +    {
> +      error (0, 0,
> +	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
> +	     TEST_NAME, dst, src);
> +      ret = 1;
> +      free (dst);
> +      return;
> +    }
> +  free (dst);
> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +/* For wcsdup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
> +   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; i++)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +
> +  do_one_test (s1, len);
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
> +     char test, and thus it will be equal to align times wchar_t size.
> +
> +     For non wide version we need to check all alignments from 0 to 63
> +     since some assembly implementations have separate prolog for alignments
> +     more 48.  */
> +
> +      align1 = random () & (63 / sizeof (CHAR));
> +      if (random () & 1)
> +	align2 = random () & (63 / sizeof (CHAR));
> +      else
> +	align2 = align1 + (random () & 24);
> +      len = random () & 511;
> +      j = align1;
> +      if (align2 > j)
> +	j = align2;
> +      if (len + j >= 511)
> +	len = 510 - j - (random () & 7);
> +      j = len + align1 + 64;
> +      if (j > 512)
> +	j = 512;
> +      for (i = 0; i < j; i++)
> +	{
> +	  if (i == len + align1)
> +	    p1[i] = 0;
> +	  else
> +	    {
> +	      p1[i] = random () & BIG_CHAR;
> +	      if (i >= align1 && i < len + align1 && !p1[i])
> +		p1[i] = (random () & SMALL_CHAR) + 3;
> +	    }
> +	}
> +
> +      res = (UCHAR *) STRDUP((CHAR *) p1 + align1);
> +      TCS ((CHAR *) res, (CHAR *) (p1 + align1));
> +      free (res);
> +    }
> +}
> +
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%23s", "");
> +  printf ("\t%s", TEST_NAME);
> +  putchar ('\n');
> +
> +  for (i = 0; i < 16; ++i)
> +    {
> +      do_test (0, 0, i, SMALL_CHAR);
> +      do_test (0, 0, i, BIG_CHAR);
> +      do_test (0, i, i, SMALL_CHAR);
> +      do_test (i, 0, i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
> +      do_test (2 * i, i, 8 << i, BIG_CHAR);
> +      do_test (i, i, 8 << i, SMALL_CHAR);
> +      do_test (i, i, 8 << i, BIG_CHAR);
> +    }
> +
> +  do_zero_len_test ();
> +  do_random_tests ();
> +
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v4 3/4] string: Add tests for strndup (BZ #30266)
  2023-04-10 15:59   ` [PATCH v4 3/4] string: Add tests for strndup " Joe Simmons-Talbott
@ 2023-04-11 17:29     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-11 17:29 UTC (permalink / raw)
  To: libc-alpha, Joe Simmons-Talbott



On 10/04/23 12:59, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strncpy tests for strndup.  Covers some basic testcases with random
> strings.  Remove tests that set the destination's bytes and checked the
> resulting buffer's bytes.  Remove wide character test support since
> wcsndup() doesn't exist.

Some minor issues below.

> ---
>  string/Makefile       |   1 +
>  string/test-strndup.c | 222 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 223 insertions(+)
>  create mode 100644 string/test-strndup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index 472e318aea..2eef6f1dfc 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -163,6 +163,7 @@ tests := \
>    test-strncat \
>    test-strncmp \
>    test-strncpy \
> +  test-strndup \
>    test-strnlen \
>    test-strpbrk \
>    test-strrchr \

Ok.

> diff --git a/string/test-strndup.c b/string/test-strndup.c
> new file mode 100644
> index 0000000000..b5665a3eec
> --- /dev/null
> +++ b/string/test-strndup.c
> @@ -0,0 +1,222 @@
> +/* Test strndup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <support/check.h>
> +
> +#define CHAR char
> +#define UCHAR unsigned char
> +#define BIG_CHAR CHAR_MAX
> +#define SMALL_CHAR 127
> +#define MEMSET memset
> +
> +
> +#ifndef STRNDUP_RESULT
> +# define STRNDUP_RESULT(dst, len, n) dst
> +# define TEST_MAIN
> +# define TEST_NAME "strndup"
> +# include "test-string.h"
> +
> +#endif /* !STRNDUP_RESULT */

Just remove these definitions and use the definitions directly.

> +
> +static void
> +do_one_test (const CHAR *src, size_t len, size_t n)
> +{
> +  CHAR *dst = strndup(src, n);
> +  size_t s = (len > n ? n: len) * sizeof (CHAR);
> +
> +  TEST_COMPARE_BLOB(dst, s, src, s);
> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
> +{
> +  size_t i;
> +  CHAR *s1;
> +
> +/* For wcsndup: align1 and align2 here mean alignment not in bytes,
> +   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)).  */

This comment does not really apply (wcsndup does not exit).

> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (CHAR) >= page_size)
> +    return;
> +
> +  s1 = (CHAR *) (buf1) + align1;
> +
> +  for (i = 0; i < len; ++i)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +  for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64;
> +       ++i)
> +    s1[i] = 32 + 32 * i % (max_char - 32);
> +
> +  do_one_test (s1, len, n);
> +}
> +
> +static void
> +do_page_tests (void)
> +{
> +  CHAR *s1;
> +  const size_t maxoffset = 64;
> +
> +  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
> +  s1 = (CHAR *) buf1 + BUF1PAGES * page_size / sizeof(CHAR) - maxoffset;
Space after 'sizeof'.

> +  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
> +     (maxoffset - 1).  */
> +
> +  MEMSET (s1, 'a', maxoffset - 1);
> +  s1[maxoffset - 1] = '\0';
> +
> +  /* Both strings are bounded to a page with read/write access and the next
> +     page is protected with PROT_NONE (meaning that any access outside of the
> +     page regions will trigger an invalid memory access).
> +
> +     The loop copies the string s1 for all possible offsets up to maxoffset
> +     for both inputs with a size larger than s1 (so memory access outside the
> +     expected memory regions might trigger invalid access).  */
> +
> +  for (size_t off1 = 0; off1 < maxoffset; off1++)
> +    {
> +      for (size_t off2 = 0; off2 < maxoffset; off2++)
> +	{
> +	  do_one_test (s1 + off1, maxoffset - off1 - 1,
> +			 maxoffset + (maxoffset - off2));
> +	}
> +    }
> +}

No need to brackets for single line code.

> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len, size, mode;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *res;
> +
> +  for (n = 0; n < ITERATIONS; n++)
> +    {
> +      /* For wcsndup: align1 and align2 here mean align not in bytes,
> +	 but in wchar_ts, in bytes it will equal to align * (sizeof
> +	 (wchar_t)).  */

Same as before.

> +
> +      mode = random ();
> +      if (mode & 1)
> +	{
> +	  size = random () & 255;
> +	  align1 = 512 - size - (random () & 15);
> +	  if (mode & 2)
> +	    align2 = align1 - (random () & 24);
> +	  else
> +	    align2 = align1 - (random () & 31);
> +	  if (mode & 4)
> +	    {
> +	      j = align1;
> +	      align1 = align2;
> +	      align2 = j;
> +	    }
> +	  if (mode & 8)
> +	    len = size - (random () & 31);
> +	  else
> +	    len = 512;
> +	  if (len >= 512)
> +	    len = random () & 511;
> +	}
> +      else
> +	{
> +	  align1 = random () & 31;
> +	  if (mode & 2)
> +	    align2 = random () & 31;
> +	  else
> +	    align2 = align1 + (random () & 24);
> +	  len = random () & 511;
> +	  j = align1;
> +	  if (align2 > j)
> +	    j = align2;
> +	  if (mode & 4)
> +	    {
> +	      size = random () & 511;
> +	      if (size + j > 512)
> +		size = 512 - j - (random () & 31);
> +	    }
> +	  else
> +	    size = 512 - j;
> +	  if ((mode & 8) && len + j >= 512)
> +	    len = 512 - j - (random () & 7);
> +	}
> +      j = len + align1 + 64;
> +      if (j > 512)
> +	j = 512;
> +      for (i = 0; i < j; i++)
> +	{
> +	  if (i == len + align1)
> +	    p1[i] = 0;
> +	  else
> +	    {
> +	      p1[i] = random () & BIG_CHAR;
> +	      if (i >= align1 && i < len + align1 && !p1[i])
> +		p1[i] = (random () & SMALL_CHAR) + 3;
> +	    }
> +	}
> +
> +	res = (UCHAR *) strndup ((CHAR *) (p1 + align1), size);
> +	j = len + 1;
> +	if (size < j)
> +	  j = size;
> +	TEST_COMPARE_BLOB (res, j, (CHAR *) (p1 + align1), j);
> +	free (res);
> +    }
> +}
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%28s", "");
> +  printf ("\t%s", TEST_NAME);
> +  putchar ('\n');
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, i, 16, 16, SMALL_CHAR);
> +      do_test (i, i, 16, 16, BIG_CHAR);
> +      do_test (i, 2 * i, 16, 16, SMALL_CHAR);
> +      do_test (2 * i, i, 16, 16, BIG_CHAR);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR);
> +      do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
> +      do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
> +    }
> +
> +  do_random_tests ();
> +  do_page_tests ();
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v4 4/4] wcsmbs: Add wcsdup() tests. (BZ #30266)
  2023-04-10 15:59   ` [PATCH v4 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
@ 2023-04-11 17:30     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-11 17:30 UTC (permalink / raw)
  To: libc-alpha, Joe Simmons-Talbott



On 10/04/23 12:59, Joe Simmons-Talbott via Libc-alpha wrote:
> Enable wide character testcases for wcsdup().

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  wcsmbs/Makefile      | 2 +-
>  wcsmbs/test-wcsdup.c | 2 ++
>  2 files changed, 3 insertions(+), 1 deletion(-)
>  create mode 100644 wcsmbs/test-wcsdup.c
> 
> diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
> index b12a3b0750..bd39335b0e 100644
> --- a/wcsmbs/Makefile
> +++ b/wcsmbs/Makefile
> @@ -49,7 +49,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
>  
>  strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
>  		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
> -		wcscspn wmemchr wmemset
> +		wcscspn wmemchr wmemset wcsdup
>  tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
>  	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
>  	 tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
> diff --git a/wcsmbs/test-wcsdup.c b/wcsmbs/test-wcsdup.c
> new file mode 100644
> index 0000000000..e39e063d0b
> --- /dev/null
> +++ b/wcsmbs/test-wcsdup.c
> @@ -0,0 +1,2 @@
> +#define WIDE 1
> +#include "../string/test-strdup.c"

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 0/4] string: Add tests for strdup and strndup (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
                   ` (4 preceding siblings ...)
  2023-04-10 15:59 ` [PATCH v4 0/4] string: Add tests for strdup and " Joe Simmons-Talbott
@ 2023-04-11 19:05 ` Joe Simmons-Talbott
  2023-04-11 19:05   ` [PATCH v5 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
                     ` (4 more replies)
  2023-04-20 16:54 ` [PATCH v6 " Joe Simmons-Talbott
  2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  7 siblings, 5 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-11 19:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
tests that checked the surrounding bytes of the result as they are not needed.

Changes to v4:
  * string/test-strndup.c - Remove no longer needed defines.  Remove
    unneeded comments.  Minor style cleanup.

Changes to v3:
  * string/test-strdup.c - Style cleanup.  Make sure we're using CHAR
    rather than char for wide character support.
  * string/test-strndup.c - Remove unneeded wide character support since
    there is no wcsndup().  Use TEST_COMPARE_BLOB rather than memcmp().
  * wcsmbs - Enable wcsdup() testcases.

Changes to v2: Remove the rest of the ifunc bits.  Mark two variables as
unused so that we can use string/test-string.h for functions that aren't
ifuncs.

Changes to v1: Since strdup and strndup are not ifuncs and likely won't
be, call them directly.  Use TEST_COMPARE_BLOB() rather than memcmp().
Clear up wording in a comment.


Joe Simmons-Talbott (4):
  string: Allow use of test-string.h for non-ifunc implementations.
  string: Add tests for strdup (BZ #30266)
  string: Add tests for strndup (BZ #30266)
  wcsmbs: Add wcsdup() tests. (BZ #30266)

 string/Makefile       |   2 +
 string/test-strdup.c  | 203 ++++++++++++++++++++++++++++++++++++++++++
 string/test-string.h  |   4 +-
 string/test-strndup.c | 200 +++++++++++++++++++++++++++++++++++++++++
 wcsmbs/Makefile       |   2 +-
 wcsmbs/test-wcsdup.c  |   2 +
 6 files changed, 410 insertions(+), 3 deletions(-)
 create mode 100644 string/test-strdup.c
 create mode 100644 string/test-strndup.c
 create mode 100644 wcsmbs/test-wcsdup.c

-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 1/4] string: Allow use of test-string.h for non-ifunc implementations.
  2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
@ 2023-04-11 19:05   ` Joe Simmons-Talbott
  2023-04-11 19:05   ` [PATCH v5 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-11 19:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Mark two variables as unused to silence warning when using
test-string.h for non-ifunc implementations.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 string/test-string.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/string/test-string.h b/string/test-string.h
index 41de973479..8bcb8afd0a 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -130,8 +130,8 @@ cmdline_process_function (int c)
 /* Increase size of FUNC_LIST if assert is triggered at run-time.  */
 static struct libc_ifunc_impl func_list[32];
 static int func_count;
-static int impl_count = -1;
-static impl_t *impl_array;
+static int impl_count __attribute__ ((unused)) = -1;
+static impl_t *impl_array __attribute__ ((unused));
 
 # define FOR_EACH_IMPL(impl, notall) \
   impl_t *impl;								\
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 2/4] string: Add tests for strdup (BZ #30266)
  2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  2023-04-11 19:05   ` [PATCH v5 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
@ 2023-04-11 19:05   ` Joe Simmons-Talbott
  2023-04-20 15:51     ` Adhemerval Zanella Netto
  2023-04-11 19:05   ` [PATCH v5 3/4] string: Add tests for strndup " Joe Simmons-Talbott
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-11 19:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Copy strcpy tests for strdup.  Covers some basic testcases with random
strings.  Add a zero-length string testcase.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 string/Makefile      |   1 +
 string/test-strdup.c | 203 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 204 insertions(+)
 create mode 100644 string/test-strdup.c

diff --git a/string/Makefile b/string/Makefile
index c84b49aaa5..472e318aea 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -157,6 +157,7 @@ tests := \
   test-strcmp \
   test-strcpy \
   test-strcspn \
+  test-strdup \
   test-strlen \
   test-strncasecmp \
   test-strncat \
diff --git a/string/test-strdup.c b/string/test-strdup.c
new file mode 100644
index 0000000000..8a1a267782
--- /dev/null
+++ b/string/test-strdup.c
@@ -0,0 +1,203 @@
+/* Test and measure strdup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define UCHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define TCS TEST_COMPARE_STRING_WIDE
+#else
+# define CHAR char
+# define UCHAR unsigned char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+# define TCS TEST_COMPARE_STRING
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strdup"
+# else
+#  define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define STRDUP strdup
+# else
+#  define STRDUP wcsdup
+# endif
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+  CHAR src[1] = { '\0' };
+  CHAR *dst = STRDUP (src);
+
+  TCS (dst, src);
+  free (dst);
+}
+
+static void
+do_one_test (const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  CHAR *dst = STRDUP (src);
+
+  if (STRCMP (dst, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     TEST_NAME, dst, src);
+      ret = 1;
+      free (dst);
+      return;
+    }
+  free (dst);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  do_one_test (s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
+     char test, and thus it will be equal to align times wchar_t size.
+
+     For non wide version we need to check all alignments from 0 to 63
+     since some assembly implementations have separate prolog for alignments
+     more 48.  */
+
+      align1 = random () & (63 / sizeof (CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof (CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      res = (UCHAR *) STRDUP((CHAR *) p1 + align1);
+      TCS ((CHAR *) res, (CHAR *) (p1 + align1));
+      free (res);
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  printf ("\t%s", TEST_NAME);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_zero_len_test ();
+  do_random_tests ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 3/4] string: Add tests for strndup (BZ #30266)
  2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  2023-04-11 19:05   ` [PATCH v5 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
  2023-04-11 19:05   ` [PATCH v5 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-11 19:05   ` Joe Simmons-Talbott
  2023-04-20 15:51     ` Adhemerval Zanella Netto
  2023-04-11 19:05   ` [PATCH v5 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
  2023-04-19 14:24   ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  4 siblings, 1 reply; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-11 19:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strncpy tests for strndup.  Covers some basic testcases with random
strings.  Remove tests that set the destination's bytes and checked the
resulting buffer's bytes.  Remove wide character test support since
wcsndup() doesn't exist.
---
 string/Makefile       |   1 +
 string/test-strndup.c | 200 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 201 insertions(+)
 create mode 100644 string/test-strndup.c

diff --git a/string/Makefile b/string/Makefile
index 472e318aea..2eef6f1dfc 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -163,6 +163,7 @@ tests := \
   test-strncat \
   test-strncmp \
   test-strncpy \
+  test-strndup \
   test-strnlen \
   test-strpbrk \
   test-strrchr \
diff --git a/string/test-strndup.c b/string/test-strndup.c
new file mode 100644
index 0000000000..841145dc92
--- /dev/null
+++ b/string/test-strndup.c
@@ -0,0 +1,200 @@
+/* Test strndup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#define TEST_MAIN
+#include "test-string.h"
+
+static void
+do_one_test (const char *src, size_t len, size_t n)
+{
+  char *dst = strndup(src, n);
+  size_t s = (len > n ? n: len) * sizeof (char);
+
+  TEST_COMPARE_BLOB(dst, s, src, s);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  char *s1;
+
+  align1 &= 7;
+  if ((align1 + len) * sizeof (char) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (char) >= page_size)
+    return;
+
+  s1 = (char *) (buf1) + align1;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (char) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  do_one_test (s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+  char *s1;
+  const size_t maxoffset = 64;
+
+  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
+  s1 = (char *) buf1 + BUF1PAGES * page_size / sizeof (char) - maxoffset;
+  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
+     (maxoffset - 1).  */
+
+  memset (s1, 'a', maxoffset - 1);
+  s1[maxoffset - 1] = '\0';
+
+  /* Both strings are bounded to a page with read/write access and the next
+     page is protected with PROT_NONE (meaning that any access outside of the
+     page regions will trigger an invalid memory access).
+
+     The loop copies the string s1 for all possible offsets up to maxoffset
+     for both inputs with a size larger than s1 (so memory access outside the
+     expected memory regions might trigger invalid access).  */
+
+  for (size_t off1 = 0; off1 < maxoffset; off1++)
+    for (size_t off2 = 0; off2 < maxoffset; off2++)
+      do_one_test (s1 + off1, maxoffset - off1 - 1,
+		   maxoffset + (maxoffset - off2));
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  unsigned char *p1 = (unsigned char *) (buf1 + page_size) - 512;
+  unsigned char *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & CHAR_MAX;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & 127) + 3;
+	    }
+	}
+
+	res = (unsigned char *) strndup ((char *) (p1 + align1), size);
+	j = len + 1;
+	if (size < j)
+	  j = size;
+	TEST_COMPARE_BLOB (res, j, (char *) (p1 + align1), j);
+	free (res);
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  printf ("\t%s", "strndup");
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, 127);
+      do_test (i, i, 16, 16, CHAR_MAX);
+      do_test (i, 2 * i, 16, 16, 127);
+      do_test (2 * i, i, 16, 16, CHAR_MAX);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, CHAR_MAX);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, CHAR_MAX);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, 127);
+      do_test (0, 0, 16 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 4/4] wcsmbs: Add wcsdup() tests. (BZ #30266)
  2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
                     ` (2 preceding siblings ...)
  2023-04-11 19:05   ` [PATCH v5 3/4] string: Add tests for strndup " Joe Simmons-Talbott
@ 2023-04-11 19:05   ` Joe Simmons-Talbott
  2023-04-19 14:24   ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  4 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-11 19:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Enable wide character testcases for wcsdup().

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 wcsmbs/Makefile      | 2 +-
 wcsmbs/test-wcsdup.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 wcsmbs/test-wcsdup.c

diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index b12a3b0750..bd39335b0e 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -49,7 +49,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
-		wcscspn wmemchr wmemset
+		wcscspn wmemchr wmemset wcsdup
 tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
 	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
 	 tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
diff --git a/wcsmbs/test-wcsdup.c b/wcsmbs/test-wcsdup.c
new file mode 100644
index 0000000000..e39e063d0b
--- /dev/null
+++ b/wcsmbs/test-wcsdup.c
@@ -0,0 +1,2 @@
+#define WIDE 1
+#include "../string/test-strdup.c"
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v5 0/4] string: Add tests for strdup and strndup (BZ #30266)
  2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
                     ` (3 preceding siblings ...)
  2023-04-11 19:05   ` [PATCH v5 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
@ 2023-04-19 14:24   ` Joe Simmons-Talbott
  4 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-19 14:24 UTC (permalink / raw)
  To: libc-alpha

On Tue, Apr 11, 2023 at 03:05:22PM -0400, Joe Simmons-Talbott wrote:

Gentle ping.

Thanks,
Joe
> Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
> tests that checked the surrounding bytes of the result as they are not needed.
> 
> Changes to v4:
>   * string/test-strndup.c - Remove no longer needed defines.  Remove
>     unneeded comments.  Minor style cleanup.
> 
> Changes to v3:
>   * string/test-strdup.c - Style cleanup.  Make sure we're using CHAR
>     rather than char for wide character support.
>   * string/test-strndup.c - Remove unneeded wide character support since
>     there is no wcsndup().  Use TEST_COMPARE_BLOB rather than memcmp().
>   * wcsmbs - Enable wcsdup() testcases.
> 
> Changes to v2: Remove the rest of the ifunc bits.  Mark two variables as
> unused so that we can use string/test-string.h for functions that aren't
> ifuncs.
> 
> Changes to v1: Since strdup and strndup are not ifuncs and likely won't
> be, call them directly.  Use TEST_COMPARE_BLOB() rather than memcmp().
> Clear up wording in a comment.
> 
> 
> Joe Simmons-Talbott (4):
>   string: Allow use of test-string.h for non-ifunc implementations.
>   string: Add tests for strdup (BZ #30266)
>   string: Add tests for strndup (BZ #30266)
>   wcsmbs: Add wcsdup() tests. (BZ #30266)
> 
>  string/Makefile       |   2 +
>  string/test-strdup.c  | 203 ++++++++++++++++++++++++++++++++++++++++++
>  string/test-string.h  |   4 +-
>  string/test-strndup.c | 200 +++++++++++++++++++++++++++++++++++++++++
>  wcsmbs/Makefile       |   2 +-
>  wcsmbs/test-wcsdup.c  |   2 +
>  6 files changed, 410 insertions(+), 3 deletions(-)
>  create mode 100644 string/test-strdup.c
>  create mode 100644 string/test-strndup.c
>  create mode 100644 wcsmbs/test-wcsdup.c
> 
> -- 
> 2.39.2
> 


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v5 3/4] string: Add tests for strndup (BZ #30266)
  2023-04-11 19:05   ` [PATCH v5 3/4] string: Add tests for strndup " Joe Simmons-Talbott
@ 2023-04-20 15:51     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-20 15:51 UTC (permalink / raw)
  To: libc-alpha



On 11/04/23 16:05, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strncpy tests for strndup.  Covers some basic testcases with random
> strings.  Remove tests that set the destination's bytes and checked the
> resulting buffer's bytes.  Remove wide character test support since
> wcsndup() doesn't exist.
> ---
>  string/Makefile       |   1 +
>  string/test-strndup.c | 200 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 201 insertions(+)
>  create mode 100644 string/test-strndup.c
> 
> diff --git a/string/Makefile b/string/Makefile
> index 472e318aea..2eef6f1dfc 100644
> --- a/string/Makefile
> +++ b/string/Makefile
> @@ -163,6 +163,7 @@ tests := \
>    test-strncat \
>    test-strncmp \
>    test-strncpy \
> +  test-strndup \
>    test-strnlen \
>    test-strpbrk \
>    test-strrchr \
> diff --git a/string/test-strndup.c b/string/test-strndup.c
> new file mode 100644
> index 0000000000..841145dc92
> --- /dev/null
> +++ b/string/test-strndup.c
> @@ -0,0 +1,200 @@
> +/* Test strndup functions.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <support/check.h>
> +
> +#define TEST_MAIN
> +#include "test-string.h"
> +
> +static void
> +do_one_test (const char *src, size_t len, size_t n)
> +{
> +  char *dst = strndup(src, n);
> +  size_t s = (len > n ? n: len) * sizeof (char);
> +
> +  TEST_COMPARE_BLOB(dst, s, src, s);

Missing space before '(' and also call free on the obtained result.

> +}
> +
> +static void
> +do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
> +{
> +  size_t i;
> +  char *s1;
> +
> +  align1 &= 7;
> +  if ((align1 + len) * sizeof (char) >= page_size)
> +    return;
> +
> +  align2 &= 7;
> +  if ((align2 + len) * sizeof (char) >= page_size)
> +    return;
> +
> +  s1 = (char *) (buf1) + align1;
> +
> +  for (i = 0; i < len; ++i)
> +    s1[i] = 32 + 23 * i % (max_char - 32);
> +  s1[len] = 0;
> +  for (i = len + 1; (i + align1) * sizeof (char) < page_size && i < len + 64;
> +       ++i)
> +    s1[i] = 32 + 32 * i % (max_char - 32);
> +
> +  do_one_test (s1, len, n);
> +}
> +
> +static void
> +do_page_tests (void)
> +{
> +  char *s1;
> +  const size_t maxoffset = 64;
> +
> +  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
> +  s1 = (char *) buf1 + BUF1PAGES * page_size / sizeof (char) - maxoffset;

> +  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
> +     (maxoffset - 1).  */

This comment does not apply on this test.

> +
> +  memset (s1, 'a', maxoffset - 1);
> +  s1[maxoffset - 1] = '\0';
> +
> +  /* Both strings are bounded to a page with read/write access and the next
> +     page is protected with PROT_NONE (meaning that any access outside of the
> +     page regions will trigger an invalid memory access).
> +
> +     The loop copies the string s1 for all possible offsets up to maxoffset
> +     for both inputs with a size larger than s1 (so memory access outside the
> +     expected memory regions might trigger invalid access).  */
> +
> +  for (size_t off1 = 0; off1 < maxoffset; off1++)
> +    for (size_t off2 = 0; off2 < maxoffset; off2++)
> +      do_one_test (s1 + off1, maxoffset - off1 - 1,
> +		   maxoffset + (maxoffset - off2));
> +}
> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len, size, mode;
> +  unsigned char *p1 = (unsigned char *) (buf1 + page_size) - 512;
> +  unsigned char *res;

Use 'char *' here, so you don't need to cast ...

> +
> +	res = (unsigned char *) strndup ((char *) (p1 + align1), size);

... here.

> +	j = len + 1;
> +	if (size < j)
> +	  j = size;
> +	TEST_COMPARE_BLOB (res, j, (char *) (p1 + align1), j);
> +	free (res);
> +    }
> +}
> +
> +int
> +test_main (void)
> +{
> +  size_t i;
> +
> +  test_init ();
> +
> +  printf ("%28s", "");
> +  printf ("\t%s", "strndup");
> +  putchar ('\n');
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (i, i, 16, 16, 127);
> +      do_test (i, i, 16, 16, CHAR_MAX);
> +      do_test (i, 2 * i, 16, 16, 127);
> +      do_test (2 * i, i, 16, 16, CHAR_MAX);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
> +      do_test (8 - i, 2 * i, 1 << i, 2 << i, CHAR_MAX);
> +      do_test (2 * i, 8 - i, 2 << i, 1 << i, CHAR_MAX);
> +    }
> +
> +  for (i = 1; i < 8; ++i)
> +    {
> +      do_test (0, 0, 4 << i, 8 << i, 127);
> +      do_test (0, 0, 16 << i, 8 << i, 127);
> +      do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
> +      do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
> +    }
> +
> +  do_random_tests ();
> +  do_page_tests ();
> +  return ret;
> +}
> +
> +#include <support/test-driver.c>

The rest looks ok.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v5 2/4] string: Add tests for strdup (BZ #30266)
  2023-04-11 19:05   ` [PATCH v5 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-20 15:51     ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-20 15:51 UTC (permalink / raw)
  To: Joe Simmons-Talbott, libc-alpha



On 11/04/23 16:05, Joe Simmons-Talbott wrote:
> Copy strcpy tests for strdup.  Covers some basic testcases with random
> strings.  Add a zero-length string testcase.
> 
> Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

Just minor nits I saw it on a second look.

> +
> +static void
> +do_random_tests (void)
> +{
> +  size_t i, j, n, align1, align2, len;
> +  UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512;
> +  UCHAR *res;

Use CHAR here, so there is no need to cast ...

> +
> +      res = (UCHAR *) STRDUP((CHAR *) p1 + align1);
> +      TCS ((CHAR *) res, (CHAR *) (p1 + align1));

... here.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 0/4] string: Add tests for strdup and strndup (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
                   ` (5 preceding siblings ...)
  2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
@ 2023-04-20 16:54 ` Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
                     ` (3 more replies)
  2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  7 siblings, 4 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-20 16:54 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
tests that checked the surrounding bytes of the result as they are not needed.

Changes to v5:
  * string/test-strdup.c - Don't use UCHAR and avoid the casts.
  * string/test-strndup.c - Don't use unsigned char and avoid the casts.
    Minor style cleanup.

Changes to v4:
  * string/test-strndup.c - Remove no longer needed defines.  Remove
    unneeded comments.  Minor style cleanup.

Changes to v3:
  * string/test-strdup.c - Style cleanup.  Make sure we're using CHAR
    rather than char for wide character support.
  * string/test-strndup.c - Remove unneeded wide character support since
    there is no wcsndup().  Use TEST_COMPARE_BLOB rather than memcmp().
  * wcsmbs - Enable wcsdup() testcases.

Changes to v2: Remove the rest of the ifunc bits.  Mark two variables as
unused so that we can use string/test-string.h for functions that aren't
ifuncs.

Changes to v1: Since strdup and strndup are not ifuncs and likely won't
be, call them directly.  Use TEST_COMPARE_BLOB() rather than memcmp().
Clear up wording in a comment.

Joe Simmons-Talbott (4):
  string: Allow use of test-string.h for non-ifunc implementations.
  string: Add tests for strdup (BZ #30266)
  string: Add tests for strndup (BZ #30266)
  wcsmbs: Add wcsdup() tests. (BZ #30266)

 string/Makefile       |   2 +
 string/test-strdup.c  | 201 ++++++++++++++++++++++++++++++++++++++++++
 string/test-string.h  |   4 +-
 string/test-strndup.c | 200 +++++++++++++++++++++++++++++++++++++++++
 wcsmbs/Makefile       |   2 +-
 wcsmbs/test-wcsdup.c  |   2 +
 6 files changed, 408 insertions(+), 3 deletions(-)
 create mode 100644 string/test-strdup.c
 create mode 100644 string/test-strndup.c
 create mode 100644 wcsmbs/test-wcsdup.c

-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 1/4] string: Allow use of test-string.h for non-ifunc implementations.
  2023-04-20 16:54 ` [PATCH v6 " Joe Simmons-Talbott
@ 2023-04-20 16:54   ` Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-20 16:54 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Mark two variables as unused to silence warning when using
test-string.h for non-ifunc implementations.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 string/test-string.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/string/test-string.h b/string/test-string.h
index 41de973479..8bcb8afd0a 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -130,8 +130,8 @@ cmdline_process_function (int c)
 /* Increase size of FUNC_LIST if assert is triggered at run-time.  */
 static struct libc_ifunc_impl func_list[32];
 static int func_count;
-static int impl_count = -1;
-static impl_t *impl_array;
+static int impl_count __attribute__ ((unused)) = -1;
+static impl_t *impl_array __attribute__ ((unused));
 
 # define FOR_EACH_IMPL(impl, notall) \
   impl_t *impl;								\
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 2/4] string: Add tests for strdup (BZ #30266)
  2023-04-20 16:54 ` [PATCH v6 " Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
@ 2023-04-20 16:54   ` Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 3/4] string: Add tests for strndup " Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
  3 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-20 16:54 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Copy strcpy tests for strdup.  Covers some basic testcases with random
strings.  Add a zero-length string testcase.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 string/Makefile      |   1 +
 string/test-strdup.c | 201 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 202 insertions(+)
 create mode 100644 string/test-strdup.c

diff --git a/string/Makefile b/string/Makefile
index c84b49aaa5..472e318aea 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -157,6 +157,7 @@ tests := \
   test-strcmp \
   test-strcpy \
   test-strcspn \
+  test-strdup \
   test-strlen \
   test-strncasecmp \
   test-strncat \
diff --git a/string/test-strdup.c b/string/test-strdup.c
new file mode 100644
index 0000000000..9378c7eaf0
--- /dev/null
+++ b/string/test-strdup.c
@@ -0,0 +1,201 @@
+/* Test and measure strdup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define TCS TEST_COMPARE_STRING_WIDE
+#else
+# define CHAR char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+# define TCS TEST_COMPARE_STRING
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strdup"
+# else
+#  define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define STRDUP strdup
+# else
+#  define STRDUP wcsdup
+# endif
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+  CHAR src[1] = { '\0' };
+  CHAR *dst = STRDUP (src);
+
+  TCS (dst, src);
+  free (dst);
+}
+
+static void
+do_one_test (const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  CHAR *dst = STRDUP (src);
+
+  if (STRCMP (dst, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     TEST_NAME, dst, src);
+      ret = 1;
+      free (dst);
+      return;
+    }
+  free (dst);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  do_one_test (s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  CHAR *p1 = (CHAR *)(buf1 + page_size) - 512;
+  CHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
+     char test, and thus it will be equal to align times wchar_t size.
+
+     For non wide version we need to check all alignments from 0 to 63
+     since some assembly implementations have separate prolog for alignments
+     more 48.  */
+
+      align1 = random () & (63 / sizeof (CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof (CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      res =  STRDUP(p1 + align1);
+      TCS (res, (p1 + align1));
+      free (res);
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  printf ("\t%s", TEST_NAME);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_zero_len_test ();
+  do_random_tests ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 3/4] string: Add tests for strndup (BZ #30266)
  2023-04-20 16:54 ` [PATCH v6 " Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-20 16:54   ` Joe Simmons-Talbott
  2023-04-20 16:54   ` [PATCH v6 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
  3 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-20 16:54 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strncpy tests for strndup.  Covers some basic testcases with random
strings.  Remove tests that set the destination's bytes and checked the
resulting buffer's bytes.  Remove wide character test support since
wcsndup() doesn't exist.
---
 string/Makefile       |   1 +
 string/test-strndup.c | 200 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 201 insertions(+)
 create mode 100644 string/test-strndup.c

diff --git a/string/Makefile b/string/Makefile
index 472e318aea..2eef6f1dfc 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -163,6 +163,7 @@ tests := \
   test-strncat \
   test-strncmp \
   test-strncpy \
+  test-strndup \
   test-strnlen \
   test-strpbrk \
   test-strrchr \
diff --git a/string/test-strndup.c b/string/test-strndup.c
new file mode 100644
index 0000000000..841145dc92
--- /dev/null
+++ b/string/test-strndup.c
@@ -0,0 +1,200 @@
+/* Test strndup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#define TEST_MAIN
+#include "test-string.h"
+
+static void
+do_one_test (const char *src, size_t len, size_t n)
+{
+  char *dst = strndup(src, n);
+  size_t s = (len > n ? n: len) * sizeof (char);
+
+  TEST_COMPARE_BLOB(dst, s, src, s);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  char *s1;
+
+  align1 &= 7;
+  if ((align1 + len) * sizeof (char) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (char) >= page_size)
+    return;
+
+  s1 = (char *) (buf1) + align1;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (char) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  do_one_test (s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+  char *s1;
+  const size_t maxoffset = 64;
+
+  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
+  s1 = (char *) buf1 + BUF1PAGES * page_size / sizeof (char) - maxoffset;
+  /* s2 needs room to put a string with size of maxoffset + 1 at s2 +
+     (maxoffset - 1).  */
+
+  memset (s1, 'a', maxoffset - 1);
+  s1[maxoffset - 1] = '\0';
+
+  /* Both strings are bounded to a page with read/write access and the next
+     page is protected with PROT_NONE (meaning that any access outside of the
+     page regions will trigger an invalid memory access).
+
+     The loop copies the string s1 for all possible offsets up to maxoffset
+     for both inputs with a size larger than s1 (so memory access outside the
+     expected memory regions might trigger invalid access).  */
+
+  for (size_t off1 = 0; off1 < maxoffset; off1++)
+    for (size_t off2 = 0; off2 < maxoffset; off2++)
+      do_one_test (s1 + off1, maxoffset - off1 - 1,
+		   maxoffset + (maxoffset - off2));
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  unsigned char *p1 = (unsigned char *) (buf1 + page_size) - 512;
+  unsigned char *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & CHAR_MAX;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & 127) + 3;
+	    }
+	}
+
+	res = (unsigned char *) strndup ((char *) (p1 + align1), size);
+	j = len + 1;
+	if (size < j)
+	  j = size;
+	TEST_COMPARE_BLOB (res, j, (char *) (p1 + align1), j);
+	free (res);
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  printf ("\t%s", "strndup");
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, 127);
+      do_test (i, i, 16, 16, CHAR_MAX);
+      do_test (i, 2 * i, 16, 16, 127);
+      do_test (2 * i, i, 16, 16, CHAR_MAX);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, CHAR_MAX);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, CHAR_MAX);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, 127);
+      do_test (0, 0, 16 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 4/4] wcsmbs: Add wcsdup() tests. (BZ #30266)
  2023-04-20 16:54 ` [PATCH v6 " Joe Simmons-Talbott
                     ` (2 preceding siblings ...)
  2023-04-20 16:54   ` [PATCH v6 3/4] string: Add tests for strndup " Joe Simmons-Talbott
@ 2023-04-20 16:54   ` Joe Simmons-Talbott
  3 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-20 16:54 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Enable wide character testcases for wcsdup().

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 wcsmbs/Makefile      | 2 +-
 wcsmbs/test-wcsdup.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 wcsmbs/test-wcsdup.c

diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index b12a3b0750..bd39335b0e 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -49,7 +49,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
-		wcscspn wmemchr wmemset
+		wcscspn wmemchr wmemset wcsdup
 tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
 	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
 	 tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
diff --git a/wcsmbs/test-wcsdup.c b/wcsmbs/test-wcsdup.c
new file mode 100644
index 0000000000..e39e063d0b
--- /dev/null
+++ b/wcsmbs/test-wcsdup.c
@@ -0,0 +1,2 @@
+#define WIDE 1
+#include "../string/test-strdup.c"
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 0/4] string: Add tests for strdup and strndup (BZ #30266)
  2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
                   ` (6 preceding siblings ...)
  2023-04-20 16:54 ` [PATCH v6 " Joe Simmons-Talbott
@ 2023-04-21 13:24 ` Joe Simmons-Talbott
  2023-04-21 13:24   ` [PATCH v7 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
                     ` (4 more replies)
  7 siblings, 5 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-21 13:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
tests that checked the surrounding bytes of the result as they are not needed.

Chnages to v6:
  * string/test-strndup.c - Include the changes for v6 which were
    inadvertently left out.

Changes to v5:
  * string/test-strdup.c - Don't use UCHAR and avoid the casts.
  * string/test-strndup.c - Don't use unsigned char and avoid the casts.
    Minor style cleanup.

Changes to v4:
  * string/test-strndup.c - Remove no longer needed defines.  Remove
    unneeded comments.  Minor style cleanup.

Changes to v3:
  * string/test-strdup.c - Style cleanup.  Make sure we're using CHAR
    rather than char for wide character support.
  * string/test-strndup.c - Remove unneeded wide character support since
    there is no wcsndup().  Use TEST_COMPARE_BLOB rather than memcmp().
  * wcsmbs - Enable wcsdup() testcases.

Changes to v2: Remove the rest of the ifunc bits.  Mark two variables as
unused so that we can use string/test-string.h for functions that aren't
ifuncs.

Changes to v1: Since strdup and strndup are not ifuncs and likely won't
be, call them directly.  Use TEST_COMPARE_BLOB() rather than memcmp().
Clear up wording in a comment.

Joe Simmons-Talbott (4):
  string: Allow use of test-string.h for non-ifunc implementations.
  string: Add tests for strdup (BZ #30266)
  string: Add tests for strndup (BZ #30266)
  wcsmbs: Add wcsdup() tests. (BZ #30266)

 string/Makefile       |   2 +
 string/test-strdup.c  | 201 ++++++++++++++++++++++++++++++++++++++++++
 string/test-string.h  |   4 +-
 string/test-strndup.c | 198 +++++++++++++++++++++++++++++++++++++++++
 wcsmbs/Makefile       |   2 +-
 wcsmbs/test-wcsdup.c  |   2 +
 6 files changed, 406 insertions(+), 3 deletions(-)
 create mode 100644 string/test-strdup.c
 create mode 100644 string/test-strndup.c
 create mode 100644 wcsmbs/test-wcsdup.c

-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 1/4] string: Allow use of test-string.h for non-ifunc implementations.
  2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
@ 2023-04-21 13:24   ` Joe Simmons-Talbott
  2023-04-21 13:24   ` [PATCH v7 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-21 13:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Mark two variables as unused to silence warning when using
test-string.h for non-ifunc implementations.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 string/test-string.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/string/test-string.h b/string/test-string.h
index 41de973479..8bcb8afd0a 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -130,8 +130,8 @@ cmdline_process_function (int c)
 /* Increase size of FUNC_LIST if assert is triggered at run-time.  */
 static struct libc_ifunc_impl func_list[32];
 static int func_count;
-static int impl_count = -1;
-static impl_t *impl_array;
+static int impl_count __attribute__ ((unused)) = -1;
+static impl_t *impl_array __attribute__ ((unused));
 
 # define FOR_EACH_IMPL(impl, notall) \
   impl_t *impl;								\
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 2/4] string: Add tests for strdup (BZ #30266)
  2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  2023-04-21 13:24   ` [PATCH v7 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
@ 2023-04-21 13:24   ` Joe Simmons-Talbott
  2023-04-21 13:24   ` [PATCH v7 3/4] string: Add tests for strndup " Joe Simmons-Talbott
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-21 13:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Copy strcpy tests for strdup.  Covers some basic testcases with random
strings.  Add a zero-length string testcase.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 string/Makefile      |   1 +
 string/test-strdup.c | 201 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 202 insertions(+)
 create mode 100644 string/test-strdup.c

diff --git a/string/Makefile b/string/Makefile
index c84b49aaa5..472e318aea 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -157,6 +157,7 @@ tests := \
   test-strcmp \
   test-strcpy \
   test-strcspn \
+  test-strdup \
   test-strlen \
   test-strncasecmp \
   test-strncat \
diff --git a/string/test-strdup.c b/string/test-strdup.c
new file mode 100644
index 0000000000..9378c7eaf0
--- /dev/null
+++ b/string/test-strdup.c
@@ -0,0 +1,201 @@
+/* Test and measure strdup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define TCS TEST_COMPARE_STRING_WIDE
+#else
+# define CHAR char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+# define TCS TEST_COMPARE_STRING
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+#  define TEST_NAME "strdup"
+# else
+#  define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+#  define STRDUP strdup
+# else
+#  define STRDUP wcsdup
+# endif
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+  CHAR src[1] = { '\0' };
+  CHAR *dst = STRDUP (src);
+
+  TCS (dst, src);
+  free (dst);
+}
+
+static void
+do_one_test (const CHAR *src,
+	     size_t len __attribute__((unused)))
+{
+  CHAR *dst = STRDUP (src);
+
+  if (STRCMP (dst, src) != 0)
+    {
+      error (0, 0,
+	     "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+	     TEST_NAME, dst, src);
+      ret = 1;
+      free (dst);
+      return;
+    }
+  free (dst);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+  size_t i;
+  CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+   but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+   len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
+  align1 &= 7;
+  if ((align1 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (CHAR) >= page_size)
+    return;
+
+  s1 = (CHAR *) (buf1) + align1;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  do_one_test (s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len;
+  CHAR *p1 = (CHAR *)(buf1 + page_size) - 512;
+  CHAR *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      /* align1 and align2 are expressed as wchar_t and not in bytes for wide
+     char test, and thus it will be equal to align times wchar_t size.
+
+     For non wide version we need to check all alignments from 0 to 63
+     since some assembly implementations have separate prolog for alignments
+     more 48.  */
+
+      align1 = random () & (63 / sizeof (CHAR));
+      if (random () & 1)
+	align2 = random () & (63 / sizeof (CHAR));
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & BIG_CHAR;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & SMALL_CHAR) + 3;
+	    }
+	}
+
+      res =  STRDUP(p1 + align1);
+      TCS (res, (p1 + align1));
+      free (res);
+    }
+}
+
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%23s", "");
+  printf ("\t%s", TEST_NAME);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, SMALL_CHAR);
+      do_test (0, 0, i, BIG_CHAR);
+      do_test (0, i, i, SMALL_CHAR);
+      do_test (i, 0, i, BIG_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, SMALL_CHAR);
+      do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+      do_test (2 * i, i, 8 << i, BIG_CHAR);
+      do_test (i, i, 8 << i, SMALL_CHAR);
+      do_test (i, i, 8 << i, BIG_CHAR);
+    }
+
+  do_zero_len_test ();
+  do_random_tests ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 3/4] string: Add tests for strndup (BZ #30266)
  2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
  2023-04-21 13:24   ` [PATCH v7 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
  2023-04-21 13:24   ` [PATCH v7 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
@ 2023-04-21 13:24   ` Joe Simmons-Talbott
  2023-04-21 13:24   ` [PATCH v7 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
  2023-04-21 14:07   ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Adhemerval Zanella Netto
  4 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-21 13:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Copy strncpy tests for strndup.  Covers some basic testcases with random
strings.  Remove tests that set the destination's bytes and checked the
resulting buffer's bytes.  Remove wide character test support since
wcsndup() doesn't exist.
---
 string/Makefile       |   1 +
 string/test-strndup.c | 198 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 199 insertions(+)
 create mode 100644 string/test-strndup.c

diff --git a/string/Makefile b/string/Makefile
index 472e318aea..2eef6f1dfc 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -163,6 +163,7 @@ tests := \
   test-strncat \
   test-strncmp \
   test-strncpy \
+  test-strndup \
   test-strnlen \
   test-strpbrk \
   test-strrchr \
diff --git a/string/test-strndup.c b/string/test-strndup.c
new file mode 100644
index 0000000000..4f5ccbe314
--- /dev/null
+++ b/string/test-strndup.c
@@ -0,0 +1,198 @@
+/* Test strndup functions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+#define TEST_MAIN
+#include "test-string.h"
+
+static void
+do_one_test (const char *src, size_t len, size_t n)
+{
+  char *dst = strndup(src, n);
+  size_t s = (len > n ? n: len) * sizeof (char);
+
+  TEST_COMPARE_BLOB (dst, s, src, s);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+  size_t i;
+  char *s1;
+
+  align1 &= 7;
+  if ((align1 + len) * sizeof (char) >= page_size)
+    return;
+
+  align2 &= 7;
+  if ((align2 + len) * sizeof (char) >= page_size)
+    return;
+
+  s1 = (char *) (buf1) + align1;
+
+  for (i = 0; i < len; ++i)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+  for (i = len + 1; (i + align1) * sizeof (char) < page_size && i < len + 64;
+       ++i)
+    s1[i] = 32 + 32 * i % (max_char - 32);
+
+  do_one_test (s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+  char *s1;
+  const size_t maxoffset = 64;
+
+  /* Put s1 at the maxoffset from the edge of buf1's last page.  */
+  s1 = (char *) buf1 + BUF1PAGES * page_size / sizeof (char) - maxoffset;
+
+  memset (s1, 'a', maxoffset - 1);
+  s1[maxoffset - 1] = '\0';
+
+  /* Both strings are bounded to a page with read/write access and the next
+     page is protected with PROT_NONE (meaning that any access outside of the
+     page regions will trigger an invalid memory access).
+
+     The loop copies the string s1 for all possible offsets up to maxoffset
+     for both inputs with a size larger than s1 (so memory access outside the
+     expected memory regions might trigger invalid access).  */
+
+  for (size_t off1 = 0; off1 < maxoffset; off1++)
+    for (size_t off2 = 0; off2 < maxoffset; off2++)
+      do_one_test (s1 + off1, maxoffset - off1 - 1,
+		   maxoffset + (maxoffset - off2));
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, size, mode;
+  char *p1 = (char *) (buf1 + page_size) - 512;
+  char *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      mode = random ();
+      if (mode & 1)
+	{
+	  size = random () & 255;
+	  align1 = 512 - size - (random () & 15);
+	  if (mode & 2)
+	    align2 = align1 - (random () & 24);
+	  else
+	    align2 = align1 - (random () & 31);
+	  if (mode & 4)
+	    {
+	      j = align1;
+	      align1 = align2;
+	      align2 = j;
+	    }
+	  if (mode & 8)
+	    len = size - (random () & 31);
+	  else
+	    len = 512;
+	  if (len >= 512)
+	    len = random () & 511;
+	}
+      else
+	{
+	  align1 = random () & 31;
+	  if (mode & 2)
+	    align2 = random () & 31;
+	  else
+	    align2 = align1 + (random () & 24);
+	  len = random () & 511;
+	  j = align1;
+	  if (align2 > j)
+	    j = align2;
+	  if (mode & 4)
+	    {
+	      size = random () & 511;
+	      if (size + j > 512)
+		size = 512 - j - (random () & 31);
+	    }
+	  else
+	    size = 512 - j;
+	  if ((mode & 8) && len + j >= 512)
+	    len = 512 - j - (random () & 7);
+	}
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & CHAR_MAX;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & 127) + 3;
+	    }
+	}
+
+	res = (char *) strndup ((char *) (p1 + align1), size);
+	j = len + 1;
+	if (size < j)
+	  j = size;
+	TEST_COMPARE_BLOB (res, j, (char *) (p1 + align1), j);
+	free (res);
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  test_init ();
+
+  printf ("%28s", "");
+  printf ("\t%s", "strndup");
+  putchar ('\n');
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, i, 16, 16, 127);
+      do_test (i, i, 16, 16, CHAR_MAX);
+      do_test (i, 2 * i, 16, 16, 127);
+      do_test (2 * i, i, 16, 16, CHAR_MAX);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
+      do_test (8 - i, 2 * i, 1 << i, 2 << i, CHAR_MAX);
+      do_test (2 * i, 8 - i, 2 << i, 1 << i, CHAR_MAX);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 4 << i, 8 << i, 127);
+      do_test (0, 0, 16 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
+      do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
+    }
+
+  do_random_tests ();
+  do_page_tests ();
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 4/4] wcsmbs: Add wcsdup() tests. (BZ #30266)
  2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
                     ` (2 preceding siblings ...)
  2023-04-21 13:24   ` [PATCH v7 3/4] string: Add tests for strndup " Joe Simmons-Talbott
@ 2023-04-21 13:24   ` Joe Simmons-Talbott
  2023-04-21 14:07   ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Adhemerval Zanella Netto
  4 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-21 13:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott, Adhemerval Zanella

Enable wide character testcases for wcsdup().

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 wcsmbs/Makefile      | 2 +-
 wcsmbs/test-wcsdup.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 wcsmbs/test-wcsdup.c

diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index b12a3b0750..bd39335b0e 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -49,7 +49,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 
 strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \
 		wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \
-		wcscspn wmemchr wmemset
+		wcscspn wmemchr wmemset wcsdup
 tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
 	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
 	 tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
diff --git a/wcsmbs/test-wcsdup.c b/wcsmbs/test-wcsdup.c
new file mode 100644
index 0000000000..e39e063d0b
--- /dev/null
+++ b/wcsmbs/test-wcsdup.c
@@ -0,0 +1,2 @@
+#define WIDE 1
+#include "../string/test-strdup.c"
-- 
2.39.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 0/4] string: Add tests for strdup and strndup (BZ #30266)
  2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
                     ` (3 preceding siblings ...)
  2023-04-21 13:24   ` [PATCH v7 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
@ 2023-04-21 14:07   ` Adhemerval Zanella Netto
  2023-04-21 14:43     ` Joe Simmons-Talbott
  4 siblings, 1 reply; 48+ messages in thread
From: Adhemerval Zanella Netto @ 2023-04-21 14:07 UTC (permalink / raw)
  To: Joe Simmons-Talbott, libc-alpha



On 21/04/23 10:24, Joe Simmons-Talbott via Libc-alpha wrote:
> Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
> tests that checked the surrounding bytes of the result as they are not needed.

Hi Joe,

I appreciate you are working on this and I am aware you are a new 
contributor. However, the way this thread is being unrolled is becoming 
confusing and time consuming.  So some tips:

  - Please use a proper tool to send patches.  For more than one patch, 
    just use git send-email (as suggested by 'Contribution Checklist' [1])
    with --cover-letter and --annotate options (so you can double-check if
    something is off with the patches).  This avoid messing with 
    'in-reply-to', as you seems to have done in v7.

  - Avoid replying to an old thread with a new version.  It leads to some
    confusion depending of the email reader on how to organize the reply.

  - Always rebase and check the patchset against master. Both you v6 and
    v7 do not fully apply [2] due a recent wcsmbs/Makefile change from
    Florian.

  - Also, always address all the comments before send a new version.  
    For instance, you forgot some remarks on my v5 review [3].
    
I have fixed both last two bullet points on a personal branch [4], just
to avoid dragging this thread with another version. If you are ok with
this I can install it.

[1] https://sourceware.org/glibc/wiki/Contribution%20checklist
[2] https://patchwork.sourceware.org/project/glibc/patch/20230421132425.2178020-5-josimmon@redhat.com/
[3] https://sourceware.org/pipermail/libc-alpha/2023-April/147474.html
[4] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/bz30266

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 0/4] string: Add tests for strdup and strndup (BZ #30266)
  2023-04-21 14:07   ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Adhemerval Zanella Netto
@ 2023-04-21 14:43     ` Joe Simmons-Talbott
  0 siblings, 0 replies; 48+ messages in thread
From: Joe Simmons-Talbott @ 2023-04-21 14:43 UTC (permalink / raw)
  To: Adhemerval Zanella Netto; +Cc: libc-alpha

On Fri, Apr 21, 2023 at 11:07:54AM -0300, Adhemerval Zanella Netto wrote:
> 
> 
> On 21/04/23 10:24, Joe Simmons-Talbott via Libc-alpha wrote:
> > Copy strcpy and strncpy tests to strdup and strndup repectively.  Remove
> > tests that checked the surrounding bytes of the result as they are not needed.
> 
> Hi Joe,
> 
> I appreciate you are working on this and I am aware you are a new 
> contributor. However, the way this thread is being unrolled is becoming 
> confusing and time consuming.  So some tips:

Hi Adhemerval,

Thank you for your thoughful reviews and feedback.  I'm sorry for making
this harder on you than needed.

> 
>   - Please use a proper tool to send patches.  For more than one patch, 
>     just use git send-email (as suggested by 'Contribution Checklist' [1])
>     with --cover-letter and --annotate options (so you can double-check if
>     something is off with the patches).  This avoid messing with 
>     'in-reply-to', as you seems to have done in v7.

I'm currently using 'git format-patch' to generate the patches and 'git
send-email' to send them.  I only pass '--cover-letter' to format-patch
and did indeed use --in-reply-to for subsequent versions.  I'll stop
doing that.

> 
>   - Avoid replying to an old thread with a new version.  It leads to some
>     confusion depending of the email reader on how to organize the reply.

Thanks for this tip.  I'll stop doing that.

> 
>   - Always rebase and check the patchset against master. Both you v6 and
>     v7 do not fully apply [2] due a recent wcsmbs/Makefile change from
>     Florian.

Sorry, I'll make sure to do this in the future.

> 
>   - Also, always address all the comments before send a new version.  
>     For instance, you forgot some remarks on my v5 review [3].

I neglected to 'git add' my changes before doing 'git commit --amend'
for v6 which was the reason for my v7.

>     
> I have fixed both last two bullet points on a personal branch [4], just
> to avoid dragging this thread with another version. If you are ok with
> this I can install it.

I'm okay with this.  Thank you again for all of your help on this
patchset.

Thanks,
Joe

> 
> [1] https://sourceware.org/glibc/wiki/Contribution%20checklist
> [2] https://patchwork.sourceware.org/project/glibc/patch/20230421132425.2178020-5-josimmon@redhat.com/
> [3] https://sourceware.org/pipermail/libc-alpha/2023-April/147474.html
> [4] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/bz30266
> 


^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2023-04-21 14:43 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-29 15:04 [PATCH 0/2] Add tests for strdup and strndup (BZ #30266) Joe Simmons-Talbott
2023-03-29 15:04 ` [PATCH 1/2] strdup: Add tests " Joe Simmons-Talbott
2023-03-30 11:16   ` Adhemerval Zanella Netto
2023-03-29 15:05 ` [PATCH 2/2] strndup: " Joe Simmons-Talbott
2023-03-30 11:19   ` Adhemerval Zanella Netto
2023-03-30 14:50 ` [PATCH v2 0/2] Add tests for strdup and strndup " Joe Simmons-Talbott
2023-03-30 14:50   ` [PATCH v2 1/2] strdup: Add tests " Joe Simmons-Talbott
2023-04-04 13:44     ` Adhemerval Zanella Netto
2023-03-30 14:50   ` [PATCH v2 2/2] strndup: " Joe Simmons-Talbott
2023-04-04 19:00 ` [PATCH v3 0/3] string: Add tests for strdup and strndup " Joe Simmons-Talbott
2023-04-04 19:00   ` [PATCH v3 1/3] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
2023-04-07 18:19     ` Adhemerval Zanella Netto
2023-04-04 19:00   ` [PATCH v3 2/3] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
2023-04-04 19:17     ` Noah Goldstein
2023-04-04 19:40       ` Adhemerval Zanella Netto
2023-04-07 18:19     ` Adhemerval Zanella Netto
2023-04-10 13:53       ` Joe Simmons-Talbott
2023-04-10 14:44         ` Adhemerval Zanella Netto
2023-04-04 19:00   ` [PATCH v3 3/3] string: Add tests for strndup " Joe Simmons-Talbott
2023-04-07 18:19     ` Adhemerval Zanella Netto
2023-04-10 15:59 ` [PATCH v4 0/4] string: Add tests for strdup and " Joe Simmons-Talbott
2023-04-10 15:59   ` [PATCH v4 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
2023-04-10 15:59   ` [PATCH v4 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
2023-04-11 16:57     ` Adhemerval Zanella Netto
2023-04-10 15:59   ` [PATCH v4 3/4] string: Add tests for strndup " Joe Simmons-Talbott
2023-04-11 17:29     ` Adhemerval Zanella Netto
2023-04-10 15:59   ` [PATCH v4 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
2023-04-11 17:30     ` Adhemerval Zanella Netto
2023-04-11 19:05 ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
2023-04-11 19:05   ` [PATCH v5 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
2023-04-11 19:05   ` [PATCH v5 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
2023-04-20 15:51     ` Adhemerval Zanella Netto
2023-04-11 19:05   ` [PATCH v5 3/4] string: Add tests for strndup " Joe Simmons-Talbott
2023-04-20 15:51     ` Adhemerval Zanella Netto
2023-04-11 19:05   ` [PATCH v5 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
2023-04-19 14:24   ` [PATCH v5 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
2023-04-20 16:54 ` [PATCH v6 " Joe Simmons-Talbott
2023-04-20 16:54   ` [PATCH v6 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
2023-04-20 16:54   ` [PATCH v6 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
2023-04-20 16:54   ` [PATCH v6 3/4] string: Add tests for strndup " Joe Simmons-Talbott
2023-04-20 16:54   ` [PATCH v6 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
2023-04-21 13:24 ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Joe Simmons-Talbott
2023-04-21 13:24   ` [PATCH v7 1/4] string: Allow use of test-string.h for non-ifunc implementations Joe Simmons-Talbott
2023-04-21 13:24   ` [PATCH v7 2/4] string: Add tests for strdup (BZ #30266) Joe Simmons-Talbott
2023-04-21 13:24   ` [PATCH v7 3/4] string: Add tests for strndup " Joe Simmons-Talbott
2023-04-21 13:24   ` [PATCH v7 4/4] wcsmbs: Add wcsdup() tests. " Joe Simmons-Talbott
2023-04-21 14:07   ` [PATCH v7 0/4] string: Add tests for strdup and strndup " Adhemerval Zanella Netto
2023-04-21 14:43     ` Joe Simmons-Talbott

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).