git: 438a1ff803a5 - stable/14 - lib/libc/tests/string/stpncpy_test.c: extend for upcoming SSE implementation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 24 Jan 2024 19:44:40 UTC
The branch stable/14 has been updated by fuz:
URL: https://cgit.FreeBSD.org/src/commit/?id=438a1ff803a5d033b80b16880b2718f1402d904f
commit 438a1ff803a5d033b80b16880b2718f1402d904f
Author: Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2023-11-05 04:02:00 +0000
Commit: Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2024-01-24 19:39:27 +0000
lib/libc/tests/string/stpncpy_test.c: extend for upcoming SSE implementation
This adds additional unit tests validating the function for
All possible alignment offsets of source and destination.
Also extend the test to allow testing of an external stpncpy
implementation, which greatly simplifies the development of
custom implementations.
Sponsored by: The FreeBSD Foundation
Tested by: developers@, exp-run
Approved by: mjg
MFC after: 1 month
MFC to: stable/14
PR: 275785
Differential Revision: https://reviews.freebsd.org/D42519
(cherry picked from commit 6fa9e7d8737548ef93c573387ce62402c368d486)
---
lib/libc/tests/string/stpncpy_test.c | 99 +++++++++++++++++++++++++++++++-----
1 file changed, 85 insertions(+), 14 deletions(-)
diff --git a/lib/libc/tests/string/stpncpy_test.c b/lib/libc/tests/string/stpncpy_test.c
index 8154237eb8c2..8574b2d591be 100644
--- a/lib/libc/tests/string/stpncpy_test.c
+++ b/lib/libc/tests/string/stpncpy_test.c
@@ -1,7 +1,11 @@
/*-
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+ * Copyright (c) 2023 The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed by Robert Clausecker
+ * <fuz@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -27,12 +31,15 @@
#include <sys/param.h>
#include <sys/mman.h>
#include <assert.h>
+#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atf-c.h>
+static char *(*stpncpy_fn)(char *restrict, const char *restrict, size_t);
+
static char *
makebuf(size_t len, int guard_at_end)
{
@@ -69,7 +76,7 @@ test_stpncpy(const char *s)
dst = makebuf(bufsize, j);
memset(dst, 'X', bufsize);
len = (bufsize < size) ? bufsize : size - 1;
- assert(stpncpy(dst, src, bufsize) == dst+len);
+ assert(stpncpy_fn(dst, src, bufsize) == dst+len);
assert(memcmp(src, dst, len) == 0);
for (x = len; x < bufsize; x++)
assert(dst[x] == '\0');
@@ -78,33 +85,97 @@ test_stpncpy(const char *s)
}
}
-ATF_TC_WITHOUT_HEAD(nul);
-ATF_TC_BODY(nul, tc)
+static void
+test_sentinel(char *dest, char *src, size_t destlen, size_t srclen)
{
+ size_t i;
+ const char *res, *wantres;
+ const char *fail = NULL;
+
+ for (i = 0; i < srclen; i++)
+ /* src will never include (){} */
+ src[i] = '0' + i;
+ src[srclen] = '\0';
+
+ /* source sentinels: not to be copied */
+ src[-1] = '(';
+ src[srclen+1] = ')';
+
+ memset(dest, 0xee, destlen);
+
+ /* destination sentinels: not to be touched */
+ dest[-1] = '{';
+ dest[destlen] = '}';
+
+ wantres = dest + (srclen > destlen ? destlen : srclen);
+ res = stpncpy_fn(dest, src, destlen);
+
+ if (dest[-1] != '{')
+ fail = "start sentinel overwritten";
+ else if (dest[destlen] != '}')
+ fail = "end sentinel overwritten";
+ else if (strncmp(src, dest, destlen) != 0)
+ fail = "string not copied correctly";
+ else if (res != wantres)
+ fail = "incorrect return value";
+ else for (i = srclen; i < destlen; i++)
+ if (dest[i] != '\0') {
+ fail = "incomplete NUL padding";
+ break;
+ }
- test_stpncpy("");
+ if (fail)
+ atf_tc_fail_nonfatal("%s\n"
+ "stpncpy(%p \"%s\", %p \"%s\", %zu) = %p (want %p)\n",
+ fail, dest, dest, src, src, destlen, res, wantres);
}
-ATF_TC_WITHOUT_HEAD(foo);
-ATF_TC_BODY(foo, tc)
+ATF_TC_WITHOUT_HEAD(null);
+ATF_TC_BODY(null, tc)
{
-
- test_stpncpy("foo");
+ ATF_CHECK_EQ(stpncpy_fn(NULL, NULL, 0), NULL);
}
-ATF_TC_WITHOUT_HEAD(glorp);
-ATF_TC_BODY(glorp, tc)
+ATF_TC_WITHOUT_HEAD(bounds);
+ATF_TC_BODY(bounds, tc)
{
+ size_t i;
+ char buf[64+1];
- test_stpncpy("glorp");
+ for (i = 0; i < sizeof(buf) - 1; i++) {
+ buf[i] = ' ' + i;
+ buf[i+1] = '\0';
+ test_stpncpy(buf);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(alignments);
+ATF_TC_BODY(alignments, tc)
+{
+ size_t srcalign, destalign, srclen, destlen;
+ char src[15+3+64]; /* 15 offsets + 64 max length + NUL + sentinels */
+ char dest[15+2+64]; /* 15 offsets + 64 max length + sentinels */
+
+ for (srcalign = 0; srcalign < 16; srcalign++)
+ for (destalign = 0; destalign < 16; destalign++)
+ for (srclen = 0; srclen < 64; srclen++)
+ for (destlen = 0; destlen < 64; destlen++)
+ test_sentinel(dest+destalign+1,
+ src+srcalign+1, destlen, srclen);
}
ATF_TP_ADD_TCS(tp)
{
+ void *dl_handle;
+
+ dl_handle = dlopen(NULL, RTLD_LAZY);
+ stpncpy_fn = dlsym(dl_handle, "test_stpncpy");
+ if (stpncpy_fn == NULL)
+ stpncpy_fn = stpncpy;
- ATF_TP_ADD_TC(tp, nul);
- ATF_TP_ADD_TC(tp, foo);
- ATF_TP_ADD_TC(tp, glorp);
+ ATF_TP_ADD_TC(tp, null);
+ ATF_TP_ADD_TC(tp, bounds);
+ ATF_TP_ADD_TC(tp, alignments);
return (atf_no_error());
}