test: Add test for strlcat

This test is adapted from glibc, which is very concerned about alignment.
It also tests strlcpy by dependency.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Sean Anderson 2021-03-11 00:15:43 -05:00 committed by Tom Rini
parent 9af869c414
commit c4ac52f55d
2 changed files with 127 additions and 0 deletions

View file

@ -11,6 +11,7 @@ obj-y += longjmp.o
obj-$(CONFIG_CONSOLE_RECORD) += test_print.o
obj-$(CONFIG_SSCANF) += sscanf.o
obj-y += string.o
obj-y += strlcat.o
obj-$(CONFIG_ERRNO_STR) += test_errno_str.o
obj-$(CONFIG_UT_LIB_ASN1) += asn1.o
obj-$(CONFIG_UT_LIB_RSA) += rsa.o

126
test/lib/strlcat.c Normal file
View file

@ -0,0 +1,126 @@
// SPDX-License-Identifier: GPL-2.1+
/*
* Copyright (C) 2021 Sean Anderson <seanga2@gmail.com>
* Copyright (C) 2011-2021 Free Software Foundation, Inc.
*
* These tests adapted from glibc's string/test-strncat.c
*/
#include <common.h>
#include <test/lib.h>
#include <test/test.h>
#include <test/ut.h>
#define BUF_SIZE 4096
char buf1[BUF_SIZE], buf2[BUF_SIZE];
static int do_test_strlcat(struct unit_test_state *uts, int line, size_t align1,
size_t align2, size_t len1, size_t len2, size_t n)
{
char *s1, *s2;
size_t i, len, expected, actual;
align1 &= 7;
if (align1 + len1 >= BUF_SIZE)
return 0;
if (align1 + n > BUF_SIZE)
return 0;
align2 &= 7;
if (align2 + len1 + len2 >= BUF_SIZE)
return 0;
if (align2 + len1 + n > BUF_SIZE)
return 0;
s1 = buf1 + align1;
s2 = buf2 + align2;
for (i = 0; i < len1 - 1; i++)
s1[i] = 32 + 23 * i % (127 - 32);
s1[len1 - 1] = '\0';
for (i = 0; i < len2 - 1; i++)
s2[i] = 32 + 23 * i % (127 - 32);
s2[len2 - 1] = '\0';
expected = len2 < n ? min(len1 + len2 - 1, n) : n;
actual = strlcat(s2, s1, n);
if (expected != actual) {
ut_failf(uts, __FILE__, line, __func__,
"strlcat(s2, s1, 2) == len2 < n ? min(len1 + len2, n) : n",
"Expected %#lx (%ld), got %#lx (%ld)",
expected, expected, actual, actual);
return CMD_RET_FAILURE;
}
len = min3(len1, n - len2, (size_t)0);
if (memcmp(s2 + len2, s1, len)) {
ut_failf(uts, __FILE__, line, __func__,
"s2 + len1 == s1",
"Expected \"%.*s\", got \"%.*s\"",
(int)len, s1, (int)len, s2 + len2);
return CMD_RET_FAILURE;
}
i = min(n, len1 + len2 - 1) - 1;
if (len2 < n && s2[i] != '\0') {
ut_failf(uts, __FILE__, line, __func__,
"n < len1 && s2[len2 + n] == '\\0'",
"Expected s2[%ld] = '\\0', got %d ('%c')",
i, s2[i], s2[i]);
return CMD_RET_FAILURE;
}
return 0;
}
#define test_strlcat(align1, align2, len1, len2, n) do { \
int ret = do_test_strlcat(uts, __LINE__, align1, align2, len1, len2, \
n); \
if (ret) \
return ret; \
} while (0)
static int lib_test_strlcat(struct unit_test_state *uts)
{
size_t i, n;
test_strlcat(0, 2, 2, 2, SIZE_MAX);
test_strlcat(0, 0, 4, 4, SIZE_MAX);
test_strlcat(4, 0, 4, 4, SIZE_MAX);
test_strlcat(0, 0, 8, 8, SIZE_MAX);
test_strlcat(0, 8, 8, 8, SIZE_MAX);
for (i = 1; i < 8; i++) {
test_strlcat(0, 0, 8 << i, 8 << i, SIZE_MAX);
test_strlcat(8 - i, 2 * i, 8 << i, 8 << i, SIZE_MAX);
test_strlcat(0, 0, 8 << i, 2 << i, SIZE_MAX);
test_strlcat(8 - i, 2 * i, 8 << i, 2 << i, SIZE_MAX);
test_strlcat(i, 2 * i, 8 << i, 1, SIZE_MAX);
test_strlcat(2 * i, i, 8 << i, 1, SIZE_MAX);
test_strlcat(i, i, 8 << i, 10, SIZE_MAX);
}
for (n = 2; n <= 2048; n *= 4) {
test_strlcat(0, 2, 2, 2, n);
test_strlcat(0, 0, 4, 4, n);
test_strlcat(4, 0, 4, 4, n);
test_strlcat(0, 0, 8, 8, n);
test_strlcat(0, 8, 8, 8, n);
for (i = 1; i < 8; i++) {
test_strlcat(0, 0, 8 << i, 8 << i, n);
test_strlcat(8 - i, 2 * i, 8 << i, 8 << i, n);
test_strlcat(0, 0, 8 << i, 2 << i, n);
test_strlcat(8 - i, 2 * i, 8 << i, 2 << i, n);
test_strlcat(i, 2 * i, 8 << i, 1, n);
test_strlcat(2 * i, i, 8 << i, 1, n);
test_strlcat(i, i, 8 << i, 10, n);
}
}
return 0;
}
LIB_TEST(lib_test_strlcat, 0);