mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 00:02:14 -04:00
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
This commit is contained in:
parent
75cb202698
commit
6fa9e7d873
1 changed files with 85 additions and 14 deletions
|
|
@ -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;
|
||||
|
||||
test_stpncpy("");
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ATF_TP_ADD_TC(tp, nul);
|
||||
ATF_TP_ADD_TC(tp, foo);
|
||||
ATF_TP_ADD_TC(tp, glorp);
|
||||
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, null);
|
||||
ATF_TP_ADD_TC(tp, bounds);
|
||||
ATF_TP_ADD_TC(tp, alignments);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue