blob: d1a0293271b030cd5a53a003e8ca7bbe396769a1 [file] [log] [blame]
Sean Anderson33512d02021-03-11 00:15:43 -05001// SPDX-License-Identifier: GPL-2.1+
2/*
3 * Copyright (C) 2021 Sean Anderson <seanga2@gmail.com>
4 * Copyright (C) 2011-2021 Free Software Foundation, Inc.
5 *
6 * These tests adapted from glibc's string/test-strncat.c
7 */
8
Sean Anderson33512d02021-03-11 00:15:43 -05009#include <test/lib.h>
10#include <test/test.h>
11#include <test/ut.h>
12
13#define BUF_SIZE 4096
14char buf1[BUF_SIZE], buf2[BUF_SIZE];
15
16static int do_test_strlcat(struct unit_test_state *uts, int line, size_t align1,
17 size_t align2, size_t len1, size_t len2, size_t n)
18{
19 char *s1, *s2;
20 size_t i, len, expected, actual;
21
22 align1 &= 7;
23 if (align1 + len1 >= BUF_SIZE)
24 return 0;
25 if (align1 + n > BUF_SIZE)
26 return 0;
27
28 align2 &= 7;
29 if (align2 + len1 + len2 >= BUF_SIZE)
30 return 0;
31 if (align2 + len1 + n > BUF_SIZE)
32 return 0;
33
34 s1 = buf1 + align1;
35 s2 = buf2 + align2;
36
37 for (i = 0; i < len1 - 1; i++)
38 s1[i] = 32 + 23 * i % (127 - 32);
39 s1[len1 - 1] = '\0';
40
41 for (i = 0; i < len2 - 1; i++)
42 s2[i] = 32 + 23 * i % (127 - 32);
43 s2[len2 - 1] = '\0';
44
Matthias Schiffer02482ee2023-07-14 13:24:50 +020045 expected = min(strlen(s2), n) + strlen(s1);
Sean Anderson33512d02021-03-11 00:15:43 -050046 actual = strlcat(s2, s1, n);
47 if (expected != actual) {
48 ut_failf(uts, __FILE__, line, __func__,
Matthias Schiffer02482ee2023-07-14 13:24:50 +020049 "strlcat(s2, s1, n) == min(len2, n) + len1",
Simon Glassd9082102021-07-18 19:02:41 -060050 "Expected %#zx (%zd), got %#zx (%zd)",
Sean Anderson33512d02021-03-11 00:15:43 -050051 expected, expected, actual, actual);
52 return CMD_RET_FAILURE;
53 }
54
55 len = min3(len1, n - len2, (size_t)0);
56 if (memcmp(s2 + len2, s1, len)) {
57 ut_failf(uts, __FILE__, line, __func__,
58 "s2 + len1 == s1",
59 "Expected \"%.*s\", got \"%.*s\"",
60 (int)len, s1, (int)len, s2 + len2);
61 return CMD_RET_FAILURE;
62 }
63
64 i = min(n, len1 + len2 - 1) - 1;
65 if (len2 < n && s2[i] != '\0') {
66 ut_failf(uts, __FILE__, line, __func__,
67 "n < len1 && s2[len2 + n] == '\\0'",
Simon Glassd9082102021-07-18 19:02:41 -060068 "Expected s2[%zd] = '\\0', got %d ('%c')",
Sean Anderson33512d02021-03-11 00:15:43 -050069 i, s2[i], s2[i]);
70 return CMD_RET_FAILURE;
71 }
72
73 return 0;
74}
75
76#define test_strlcat(align1, align2, len1, len2, n) do { \
77 int ret = do_test_strlcat(uts, __LINE__, align1, align2, len1, len2, \
78 n); \
79 if (ret) \
80 return ret; \
81} while (0)
82
83static int lib_test_strlcat(struct unit_test_state *uts)
84{
85 size_t i, n;
86
87 test_strlcat(0, 2, 2, 2, SIZE_MAX);
88 test_strlcat(0, 0, 4, 4, SIZE_MAX);
89 test_strlcat(4, 0, 4, 4, SIZE_MAX);
90 test_strlcat(0, 0, 8, 8, SIZE_MAX);
91 test_strlcat(0, 8, 8, 8, SIZE_MAX);
92
93 for (i = 1; i < 8; i++) {
94 test_strlcat(0, 0, 8 << i, 8 << i, SIZE_MAX);
95 test_strlcat(8 - i, 2 * i, 8 << i, 8 << i, SIZE_MAX);
96 test_strlcat(0, 0, 8 << i, 2 << i, SIZE_MAX);
97 test_strlcat(8 - i, 2 * i, 8 << i, 2 << i, SIZE_MAX);
98
99 test_strlcat(i, 2 * i, 8 << i, 1, SIZE_MAX);
100 test_strlcat(2 * i, i, 8 << i, 1, SIZE_MAX);
101 test_strlcat(i, i, 8 << i, 10, SIZE_MAX);
102 }
103
104 for (n = 2; n <= 2048; n *= 4) {
105 test_strlcat(0, 2, 2, 2, n);
106 test_strlcat(0, 0, 4, 4, n);
107 test_strlcat(4, 0, 4, 4, n);
108 test_strlcat(0, 0, 8, 8, n);
109 test_strlcat(0, 8, 8, 8, n);
110
111 for (i = 1; i < 8; i++) {
112 test_strlcat(0, 0, 8 << i, 8 << i, n);
113 test_strlcat(8 - i, 2 * i, 8 << i, 8 << i, n);
114 test_strlcat(0, 0, 8 << i, 2 << i, n);
115 test_strlcat(8 - i, 2 * i, 8 << i, 2 << i, n);
116
117 test_strlcat(i, 2 * i, 8 << i, 1, n);
118 test_strlcat(2 * i, i, 8 << i, 1, n);
119 test_strlcat(i, i, 8 << i, 10, n);
120 }
121 }
122
123 return 0;
124}
125LIB_TEST(lib_test_strlcat, 0);