xref: /illumos-gate/usr/src/test/libc-tests/tests/wcslcat.c (revision 71f3ceb939e47627273608fb7ea4b3aa1c3b37e7)
1*71f3ceb9SRobert Mustacchi /*
2*71f3ceb9SRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*71f3ceb9SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*71f3ceb9SRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*71f3ceb9SRobert Mustacchi  * 1.0 of the CDDL.
6*71f3ceb9SRobert Mustacchi  *
7*71f3ceb9SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*71f3ceb9SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*71f3ceb9SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*71f3ceb9SRobert Mustacchi  */
11*71f3ceb9SRobert Mustacchi 
12*71f3ceb9SRobert Mustacchi /*
13*71f3ceb9SRobert Mustacchi  * Copyright 2025 Oxide Computer Company
14*71f3ceb9SRobert Mustacchi  */
15*71f3ceb9SRobert Mustacchi 
16*71f3ceb9SRobert Mustacchi /*
17*71f3ceb9SRobert Mustacchi  * Test various aspects of wcslcat.
18*71f3ceb9SRobert Mustacchi  */
19*71f3ceb9SRobert Mustacchi 
20*71f3ceb9SRobert Mustacchi #include <wchar.h>
21*71f3ceb9SRobert Mustacchi #include <err.h>
22*71f3ceb9SRobert Mustacchi #include <stdlib.h>
23*71f3ceb9SRobert Mustacchi #include <stdbool.h>
24*71f3ceb9SRobert Mustacchi #include <stdio.h>
25*71f3ceb9SRobert Mustacchi #include <sys/sysmacros.h>
26*71f3ceb9SRobert Mustacchi 
27*71f3ceb9SRobert Mustacchi #define	WCSLCAT_BUFLEN	16
28*71f3ceb9SRobert Mustacchi 
29*71f3ceb9SRobert Mustacchi typedef struct wcslcat_test {
30*71f3ceb9SRobert Mustacchi 	const char *wt_desc;
31*71f3ceb9SRobert Mustacchi 	wchar_t *wt_src;
32*71f3ceb9SRobert Mustacchi 	size_t wt_rval;
33*71f3ceb9SRobert Mustacchi 	size_t wt_dstlen;
34*71f3ceb9SRobert Mustacchi 	wchar_t wt_buf[WCSLCAT_BUFLEN];
35*71f3ceb9SRobert Mustacchi 	wchar_t wt_res[WCSLCAT_BUFLEN];
36*71f3ceb9SRobert Mustacchi } wcslcat_test_t;
37*71f3ceb9SRobert Mustacchi 
38*71f3ceb9SRobert Mustacchi static const wcslcat_test_t wcslcat_tests[] = { {
39*71f3ceb9SRobert Mustacchi 	.wt_desc = "Zero-sized Destination Buffer (1)",
40*71f3ceb9SRobert Mustacchi 	.wt_src = L"Hello, World!",
41*71f3ceb9SRobert Mustacchi 	.wt_rval = 13,
42*71f3ceb9SRobert Mustacchi 	.wt_dstlen = 0,
43*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
44*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
45*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
46*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' }
47*71f3ceb9SRobert Mustacchi }, {
48*71f3ceb9SRobert Mustacchi 	.wt_desc = "Zero-sized Destination Buffer (2)",
49*71f3ceb9SRobert Mustacchi 	.wt_src = L"å…‰",
50*71f3ceb9SRobert Mustacchi 	.wt_rval = 1,
51*71f3ceb9SRobert Mustacchi 	.wt_dstlen = 0,
52*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
53*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
54*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
55*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' }
56*71f3ceb9SRobert Mustacchi }, {
57*71f3ceb9SRobert Mustacchi 	.wt_desc = "Append at start, empty src",
58*71f3ceb9SRobert Mustacchi 	.wt_src = L"",
59*71f3ceb9SRobert Mustacchi 	.wt_rval = 0,
60*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
61*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'\0', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
62*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
63*71f3ceb9SRobert Mustacchi 	.wt_res = { L'\0', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
64*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' }
65*71f3ceb9SRobert Mustacchi }, {
66*71f3ceb9SRobert Mustacchi 	.wt_desc = "Append at start, don't fill dest",
67*71f3ceb9SRobert Mustacchi 	.wt_src = L"It's a trap?!",
68*71f3ceb9SRobert Mustacchi 	.wt_rval = 13,
69*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
70*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'\0', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
71*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
72*71f3ceb9SRobert Mustacchi 	.wt_res = { L'I', L't', L'\'', L's', L' ', L'a', L' ', L't',
73*71f3ceb9SRobert Mustacchi 		    L'r', L'a', L'p', L'?', L'!', L'\0', L'-', L'-' }
74*71f3ceb9SRobert Mustacchi 
75*71f3ceb9SRobert Mustacchi }, {
76*71f3ceb9SRobert Mustacchi 	.wt_desc = "Append at start, truncate src",
77*71f3ceb9SRobert Mustacchi 	.wt_src = L"This little string went to the market",
78*71f3ceb9SRobert Mustacchi 	.wt_rval = 37,
79*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
80*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'\0', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
81*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
82*71f3ceb9SRobert Mustacchi 	.wt_res = { L'T', L'h', L'i', L's', L' ', L'l', L'i', L't',
83*71f3ceb9SRobert Mustacchi 		    L't', L'l', L'e', L' ', L's', L't', L'r', L'\0' }
84*71f3ceb9SRobert Mustacchi 
85*71f3ceb9SRobert Mustacchi }, {
86*71f3ceb9SRobert Mustacchi 	.wt_desc = "Full buffer (no NUL), empty src",
87*71f3ceb9SRobert Mustacchi 	.wt_src = L"",
88*71f3ceb9SRobert Mustacchi 	.wt_rval = WCSLCAT_BUFLEN,
89*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
90*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
91*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
92*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
93*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' }
94*71f3ceb9SRobert Mustacchi }, {
95*71f3ceb9SRobert Mustacchi 	.wt_desc = "Full buffer (no NUL), non-empty src (1)",
96*71f3ceb9SRobert Mustacchi 	.wt_src = L"å…‰",
97*71f3ceb9SRobert Mustacchi 	.wt_rval = WCSLCAT_BUFLEN + 1,
98*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
99*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
100*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
101*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
102*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' }
103*71f3ceb9SRobert Mustacchi }, {
104*71f3ceb9SRobert Mustacchi 	.wt_desc = "Full buffer (no NUL), non-empty src (2)",
105*71f3ceb9SRobert Mustacchi 	.wt_src = L"Link? Zelda!",
106*71f3ceb9SRobert Mustacchi 	.wt_rval = WCSLCAT_BUFLEN + 12,
107*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
108*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
109*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
110*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
111*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' }
112*71f3ceb9SRobert Mustacchi }, {
113*71f3ceb9SRobert Mustacchi 	.wt_desc = "Full buffer (w/ NUL), empty src",
114*71f3ceb9SRobert Mustacchi 	.wt_src = L"",
115*71f3ceb9SRobert Mustacchi 	.wt_rval = WCSLCAT_BUFLEN - 1,
116*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
117*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
118*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'\0' },
119*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
120*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'\0' }
121*71f3ceb9SRobert Mustacchi }, {
122*71f3ceb9SRobert Mustacchi 	.wt_desc = "Full buffer (w/ NUL), non-empty src (1)",
123*71f3ceb9SRobert Mustacchi 	.wt_src = L"å…‰",
124*71f3ceb9SRobert Mustacchi 	.wt_rval = WCSLCAT_BUFLEN,
125*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
126*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
127*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'\0' },
128*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
129*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'\0' }
130*71f3ceb9SRobert Mustacchi }, {
131*71f3ceb9SRobert Mustacchi 	.wt_desc = "Full buffer (w/ NUL), non-empty src (2)",
132*71f3ceb9SRobert Mustacchi 	.wt_src = L"Link? Zelda!",
133*71f3ceb9SRobert Mustacchi 	.wt_rval = WCSLCAT_BUFLEN + 11,
134*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
135*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
136*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'\0' },
137*71f3ceb9SRobert Mustacchi 	.wt_res = { L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-',
138*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'\0' }
139*71f3ceb9SRobert Mustacchi }, {
140*71f3ceb9SRobert Mustacchi 	.wt_desc = "Partial buffer (1)",
141*71f3ceb9SRobert Mustacchi 	.wt_src = L"",
142*71f3ceb9SRobert Mustacchi 	.wt_rval = 5,
143*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
144*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'H', L'e', L'l', L'l', L'o', L'\0', L'-', L'-',
145*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
146*71f3ceb9SRobert Mustacchi 	.wt_res = { L'H', L'e', L'l', L'l', L'o', L'\0', L'-', L'-',
147*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
148*71f3ceb9SRobert Mustacchi }, {
149*71f3ceb9SRobert Mustacchi 	.wt_desc = "Partial buffer (2)",
150*71f3ceb9SRobert Mustacchi 	.wt_src = L", world!",
151*71f3ceb9SRobert Mustacchi 	.wt_rval = 13,
152*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
153*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'H', L'e', L'l', L'l', L'o', L'\0', L'-', L'-',
154*71f3ceb9SRobert Mustacchi 		    L'-', L'-', L'-', L'-', L'-', L'-', L'-', L'-' },
155*71f3ceb9SRobert Mustacchi 	.wt_res = { L'H', L'e', L'l', L'l', L'o', L',', L' ', L'w',
156*71f3ceb9SRobert Mustacchi 		    L'o', L'r', L'l', L'd', L'!', L'\0', L'-', L'-' },
157*71f3ceb9SRobert Mustacchi }, {
158*71f3ceb9SRobert Mustacchi 	.wt_desc = "Partial buffer truncation",
159*71f3ceb9SRobert Mustacchi 	.wt_src = L"7777 Aerith lives?",
160*71f3ceb9SRobert Mustacchi 	.wt_rval = 27,
161*71f3ceb9SRobert Mustacchi 	.wt_dstlen = WCSLCAT_BUFLEN,
162*71f3ceb9SRobert Mustacchi 	.wt_buf = { L'S', L'e', L'p', L'h', L'i', L'r', L'o', L't',
163*71f3ceb9SRobert Mustacchi 		    L'h', L'\0', L'-', L'-', L'-', L'-', L'-', L'-' },
164*71f3ceb9SRobert Mustacchi 	.wt_res = { L'S', L'e', L'p', L'h', L'i', L'r', L'o', L't',
165*71f3ceb9SRobert Mustacchi 		    L'h', L'7', L'7', L'7', L'7', L' ', L'A', L'\0' }
166*71f3ceb9SRobert Mustacchi }  };
167*71f3ceb9SRobert Mustacchi 
168*71f3ceb9SRobert Mustacchi static bool
wcslcat_test_one(const wcslcat_test_t * test)169*71f3ceb9SRobert Mustacchi wcslcat_test_one(const wcslcat_test_t *test)
170*71f3ceb9SRobert Mustacchi {
171*71f3ceb9SRobert Mustacchi 	wchar_t buf[WCSLCAT_BUFLEN];
172*71f3ceb9SRobert Mustacchi 	size_t wcret;
173*71f3ceb9SRobert Mustacchi 	bool ret = true;
174*71f3ceb9SRobert Mustacchi 
175*71f3ceb9SRobert Mustacchi 	(void) wmemcpy(buf, test->wt_buf, ARRAY_SIZE(test->wt_buf));
176*71f3ceb9SRobert Mustacchi 	wcret = wcslcat(buf, test->wt_src, test->wt_dstlen);
177*71f3ceb9SRobert Mustacchi 
178*71f3ceb9SRobert Mustacchi 	if (wcret != test->wt_rval) {
179*71f3ceb9SRobert Mustacchi 		warnx("TEST FAILED: %s: wcslcat() returned %zu, expected %zu",
180*71f3ceb9SRobert Mustacchi 		    test->wt_desc, wcret, test->wt_rval);
181*71f3ceb9SRobert Mustacchi 		ret = false;
182*71f3ceb9SRobert Mustacchi 	}
183*71f3ceb9SRobert Mustacchi 
184*71f3ceb9SRobert Mustacchi 	if (wmemcmp(buf, test->wt_res, ARRAY_SIZE(buf)) != 0) {
185*71f3ceb9SRobert Mustacchi 		warnx("TEST FAILED: %s: resulting buffer mismatch: found vs. "
186*71f3ceb9SRobert Mustacchi 		    "expected", test->wt_desc);
187*71f3ceb9SRobert Mustacchi 		for (size_t i = 0; i < ARRAY_SIZE(buf); i++) {
188*71f3ceb9SRobert Mustacchi 			(void) printf("\t[%zu] = [0x%x] vs [0x%x]\n", i, buf[i],
189*71f3ceb9SRobert Mustacchi 			    test->wt_res[i]);
190*71f3ceb9SRobert Mustacchi 		}
191*71f3ceb9SRobert Mustacchi 		ret = false;
192*71f3ceb9SRobert Mustacchi 	}
193*71f3ceb9SRobert Mustacchi 
194*71f3ceb9SRobert Mustacchi 	if (ret) {
195*71f3ceb9SRobert Mustacchi 		(void) printf("TEST PASSED: %s\n", test->wt_desc);
196*71f3ceb9SRobert Mustacchi 	}
197*71f3ceb9SRobert Mustacchi 
198*71f3ceb9SRobert Mustacchi 	return (ret);
199*71f3ceb9SRobert Mustacchi }
200*71f3ceb9SRobert Mustacchi 
201*71f3ceb9SRobert Mustacchi int
main(void)202*71f3ceb9SRobert Mustacchi main(void)
203*71f3ceb9SRobert Mustacchi {
204*71f3ceb9SRobert Mustacchi 	int ret = EXIT_SUCCESS;
205*71f3ceb9SRobert Mustacchi 
206*71f3ceb9SRobert Mustacchi 	for (size_t i = 0; i < ARRAY_SIZE(wcslcat_tests); i++) {
207*71f3ceb9SRobert Mustacchi 		if (!wcslcat_test_one(&wcslcat_tests[i]))
208*71f3ceb9SRobert Mustacchi 			ret = EXIT_FAILURE;
209*71f3ceb9SRobert Mustacchi 	}
210*71f3ceb9SRobert Mustacchi 
211*71f3ceb9SRobert Mustacchi 	if (ret == EXIT_SUCCESS) {
212*71f3ceb9SRobert Mustacchi 		(void) printf("All tests passed successfully!\n");
213*71f3ceb9SRobert Mustacchi 	}
214*71f3ceb9SRobert Mustacchi 
215*71f3ceb9SRobert Mustacchi 	return (ret);
216*71f3ceb9SRobert Mustacchi }
217