xref: /freebsd/crypto/openssh/regress/unittests/misc/test_misc.c (revision 2574974648c68c738aec3ff96644d888d7913a37)
1 /*
2  * Regress test for misc helper functions.
3  *
4  * Placed in the public domain.
5  */
6 
7 #include "includes.h"
8 
9 #include <sys/types.h>
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <string.h>
14 
15 #include "../test_helper/test_helper.h"
16 
17 #include "log.h"
18 #include "misc.h"
19 #include "xmalloc.h"
20 
21 void test_misc(void);
22 
23 static void
test_chop(void)24 test_chop(void)
25 {
26 	char *s;
27 
28 	TEST_START("chop newline");
29 	s = xstrdup("hello\n");
30 	ASSERT_STRING_EQ(chop(s), "hello");
31 	free(s);
32 	TEST_DONE();
33 
34 	TEST_START("chop carriage return");
35 	s = xstrdup("hello\r");
36 	ASSERT_STRING_EQ(chop(s), "hello");
37 	free(s);
38 	TEST_DONE();
39 
40 	TEST_START("chop CRLF");
41 	s = xstrdup("hello\r\n");
42 	ASSERT_STRING_EQ(chop(s), "hello");
43 	free(s);
44 	TEST_DONE();
45 
46 	TEST_START("chop newline in middle");
47 	s = xstrdup("he\nllo");
48 	ASSERT_STRING_EQ(chop(s), "he");
49 	free(s);
50 	TEST_DONE();
51 
52 	TEST_START("chop no newline");
53 	s = xstrdup("hello");
54 	ASSERT_STRING_EQ(chop(s), "hello");
55 	free(s);
56 	TEST_DONE();
57 
58 	TEST_START("chop empty string");
59 	s = xstrdup("");
60 	ASSERT_STRING_EQ(chop(s), "");
61 	free(s);
62 	TEST_DONE();
63 
64 	TEST_START("chop only newline");
65 	s = xstrdup("\n");
66 	ASSERT_STRING_EQ(chop(s), "");
67 	free(s);
68 	TEST_DONE();
69 
70 	TEST_START("chop only CR");
71 	s = xstrdup("\r");
72 	ASSERT_STRING_EQ(chop(s), "");
73 	free(s);
74 	TEST_DONE();
75 
76 	TEST_START("chop only CRLF");
77 	s = xstrdup("\r\n");
78 	ASSERT_STRING_EQ(chop(s), "");
79 	free(s);
80 	TEST_DONE();
81 }
82 
83 static void
test_rtrim(void)84 test_rtrim(void)
85 {
86 	char *s;
87 
88 	TEST_START("rtrim trailing space");
89 	s = xstrdup("hello  ");
90 	rtrim(s);
91 	ASSERT_STRING_EQ(s, "hello");
92 	free(s);
93 	TEST_DONE();
94 
95 	TEST_START("rtrim trailing tab");
96 	s = xstrdup("hello\t\t");
97 	rtrim(s);
98 	ASSERT_STRING_EQ(s, "hello");
99 	free(s);
100 	TEST_DONE();
101 
102 	TEST_START("rtrim trailing mixed whitespace");
103 	s = xstrdup("hello \t ");
104 	rtrim(s);
105 	ASSERT_STRING_EQ(s, "hello");
106 	free(s);
107 	TEST_DONE();
108 
109 	TEST_START("rtrim no trailing whitespace");
110 	s = xstrdup("hello");
111 	rtrim(s);
112 	ASSERT_STRING_EQ(s, "hello");
113 	free(s);
114 	TEST_DONE();
115 
116 	TEST_START("rtrim whitespace in middle");
117 	s = xstrdup("he llo");
118 	rtrim(s);
119 	ASSERT_STRING_EQ(s, "he llo");
120 	free(s);
121 	TEST_DONE();
122 
123 	TEST_START("rtrim empty string");
124 	s = xstrdup("");
125 	rtrim(s);
126 	ASSERT_STRING_EQ(s, "");
127 	free(s);
128 	TEST_DONE();
129 
130 	TEST_START("rtrim only whitespace");
131 	s = xstrdup("   \t");
132 	rtrim(s);
133 	ASSERT_STRING_EQ(s, "");
134 	free(s);
135 	TEST_DONE();
136 }
137 
138 static void
test_strprefix(void)139 test_strprefix(void)
140 {
141 	const char *s;
142 
143 	TEST_START("strprefix basic match");
144 	s = strprefix("hello world", "hello", 0);
145 	ASSERT_PTR_NE(s, NULL);
146 	ASSERT_STRING_EQ(s, " world");
147 	TEST_DONE();
148 
149 	TEST_START("strprefix no match");
150 	s = strprefix("hello world", "world", 0);
151 	ASSERT_PTR_EQ(s, NULL);
152 	TEST_DONE();
153 
154 	TEST_START("strprefix full match");
155 	s = strprefix("hello", "hello", 0);
156 	ASSERT_PTR_NE(s, NULL);
157 	ASSERT_STRING_EQ(s, "");
158 	TEST_DONE();
159 
160 	TEST_START("strprefix empty string");
161 	s = strprefix("", "hello", 0);
162 	ASSERT_PTR_EQ(s, NULL);
163 	TEST_DONE();
164 
165 	TEST_START("strprefix empty prefix");
166 	s = strprefix("hello", "", 0);
167 	ASSERT_PTR_NE(s, NULL);
168 	ASSERT_STRING_EQ(s, "hello");
169 	TEST_DONE();
170 
171 	TEST_START("strprefix case sensitive no match");
172 	s = strprefix("Hello world", "hello", 0);
173 	ASSERT_PTR_EQ(s, NULL);
174 	TEST_DONE();
175 
176 	TEST_START("strprefix case insensitive match");
177 	s = strprefix("Hello world", "hello", 1);
178 	ASSERT_PTR_NE(s, NULL);
179 	ASSERT_STRING_EQ(s, " world");
180 	TEST_DONE();
181 
182 	TEST_START("strprefix case insensitive full match");
183 	s = strprefix("HELLO", "hello", 1);
184 	ASSERT_PTR_NE(s, NULL);
185 	ASSERT_STRING_EQ(s, "");
186 	TEST_DONE();
187 }
188 
189 static void
test_fmt_timeframe(void)190 test_fmt_timeframe(void)
191 {
192 	TEST_START("fmt_timeframe seconds");
193 	ASSERT_STRING_EQ(fmt_timeframe(0), "00:00:00");
194 	ASSERT_STRING_EQ(fmt_timeframe(59), "00:00:59");
195 	ASSERT_STRING_EQ(fmt_timeframe(60), "00:01:00");
196 	ASSERT_STRING_EQ(fmt_timeframe(3599), "00:59:59");
197 	ASSERT_STRING_EQ(fmt_timeframe(3600), "01:00:00");
198 	ASSERT_STRING_EQ(fmt_timeframe(86399), "23:59:59");
199 	TEST_DONE();
200 
201 	TEST_START("fmt_timeframe days");
202 	ASSERT_STRING_EQ(fmt_timeframe(86400), "1d00h00m");
203 	ASSERT_STRING_EQ(fmt_timeframe(90061), "1d01h01m");
204 	ASSERT_STRING_EQ(fmt_timeframe(604799), "6d23h59m");
205 	TEST_DONE();
206 
207 	TEST_START("fmt_timeframe weeks");
208 	ASSERT_STRING_EQ(fmt_timeframe(604800), "01w0d00h");
209 	ASSERT_STRING_EQ(fmt_timeframe(694861), "01w1d01h");
210 	TEST_DONE();
211 }
212 
213 static void
test_arglist(void)214 test_arglist(void)
215 {
216 	arglist args;
217 	u_int i;
218 
219 	memset(&args, 0, sizeof(args));
220 
221 	TEST_START("addargs initial");
222 	addargs(&args, "one");
223 	ASSERT_U_INT_EQ(args.num, 1);
224 	ASSERT_U_INT_EQ(args.nalloc, 32);
225 	ASSERT_PTR_NE(args.list, NULL);
226 	ASSERT_STRING_EQ(args.list[0], "one");
227 	ASSERT_PTR_EQ(args.list[1], NULL);
228 	TEST_DONE();
229 
230 	TEST_START("addargs second");
231 	addargs(&args, "two");
232 	ASSERT_U_INT_EQ(args.num, 2);
233 	ASSERT_U_INT_EQ(args.nalloc, 32);
234 	ASSERT_PTR_NE(args.list, NULL);
235 	ASSERT_STRING_EQ(args.list[0], "one");
236 	ASSERT_STRING_EQ(args.list[1], "two");
237 	ASSERT_PTR_EQ(args.list[2], NULL);
238 	TEST_DONE();
239 
240 	TEST_START("addargs with format");
241 	addargs(&args, "three=%d", 3);
242 	ASSERT_U_INT_EQ(args.num, 3);
243 	ASSERT_U_INT_EQ(args.nalloc, 32);
244 	ASSERT_PTR_NE(args.list, NULL);
245 	ASSERT_STRING_EQ(args.list[0], "one");
246 	ASSERT_STRING_EQ(args.list[1], "two");
247 	ASSERT_STRING_EQ(args.list[2], "three=3");
248 	ASSERT_PTR_EQ(args.list[3], NULL);
249 	TEST_DONE();
250 
251 	TEST_START("replacearg middle");
252 	replacearg(&args, 1, "TWO!");
253 	ASSERT_U_INT_EQ(args.num, 3);
254 	ASSERT_STRING_EQ(args.list[0], "one");
255 	ASSERT_STRING_EQ(args.list[1], "TWO!");
256 	ASSERT_STRING_EQ(args.list[2], "three=3");
257 	ASSERT_PTR_EQ(args.list[3], NULL);
258 	TEST_DONE();
259 
260 	TEST_START("replacearg first");
261 	replacearg(&args, 0, "ONE!");
262 	ASSERT_U_INT_EQ(args.num, 3);
263 	ASSERT_STRING_EQ(args.list[0], "ONE!");
264 	ASSERT_STRING_EQ(args.list[1], "TWO!");
265 	ASSERT_STRING_EQ(args.list[2], "three=3");
266 	ASSERT_PTR_EQ(args.list[3], NULL);
267 	TEST_DONE();
268 
269 	TEST_START("replacearg last");
270 	replacearg(&args, 2, "THREE=3!");
271 	ASSERT_U_INT_EQ(args.num, 3);
272 	ASSERT_STRING_EQ(args.list[0], "ONE!");
273 	ASSERT_STRING_EQ(args.list[1], "TWO!");
274 	ASSERT_STRING_EQ(args.list[2], "THREE=3!");
275 	ASSERT_PTR_EQ(args.list[3], NULL);
276 	TEST_DONE();
277 
278 	TEST_START("replacearg with format");
279 	replacearg(&args, 1, "two=%d", 2);
280 	ASSERT_U_INT_EQ(args.num, 3);
281 	ASSERT_STRING_EQ(args.list[0], "ONE!");
282 	ASSERT_STRING_EQ(args.list[1], "two=2");
283 	ASSERT_STRING_EQ(args.list[2], "THREE=3!");
284 	ASSERT_PTR_EQ(args.list[3], NULL);
285 	TEST_DONE();
286 
287 	TEST_START("addargs reallocation");
288 	for (i = args.num; i < 33; i++)
289 		addargs(&args, "pad-%d", i);
290 	ASSERT_U_INT_EQ(args.num, 33);
291 	ASSERT_U_INT_GE(args.nalloc, 33);
292 	ASSERT_STRING_EQ(args.list[32], "pad-32");
293 	ASSERT_PTR_EQ(args.list[33], NULL);
294 	TEST_DONE();
295 
296 	TEST_START("freeargs");
297 	freeargs(&args);
298 	ASSERT_U_INT_EQ(args.num, 0);
299 	ASSERT_U_INT_EQ(args.nalloc, 0);
300 	ASSERT_PTR_EQ(args.list, NULL);
301 	TEST_DONE();
302 
303 	TEST_START("freeargs on NULL");
304 	freeargs(NULL);
305 	TEST_DONE();
306 
307 	TEST_START("freeargs on empty");
308 	memset(&args, 0, sizeof(args));
309 	freeargs(&args);
310 	ASSERT_U_INT_EQ(args.num, 0);
311 	ASSERT_U_INT_EQ(args.nalloc, 0);
312 	ASSERT_PTR_EQ(args.list, NULL);
313 	TEST_DONE();
314 }
315 
316 static void
test_tohex(void)317 test_tohex(void)
318 {
319 	char *hex;
320 
321 	TEST_START("tohex simple");
322 	hex = tohex("foo", 3);
323 	ASSERT_STRING_EQ(hex, "666f6f");
324 	free(hex);
325 	TEST_DONE();
326 
327 	TEST_START("tohex with null");
328 	hex = tohex("a\0b", 3);
329 	ASSERT_STRING_EQ(hex, "610062");
330 	free(hex);
331 	TEST_DONE();
332 
333 	TEST_START("tohex empty");
334 	hex = tohex("", 0);
335 	ASSERT_STRING_EQ(hex, "");
336 	free(hex);
337 	TEST_DONE();
338 }
339 
340 static void
test_lowercase(void)341 test_lowercase(void)
342 {
343 	char *s;
344 
345 	TEST_START("lowercase mixed");
346 	s = xstrdup("HeLlO WoRlD 123");
347 	lowercase(s);
348 	ASSERT_STRING_EQ(s, "hello world 123");
349 	free(s);
350 	TEST_DONE();
351 
352 	TEST_START("lowercase empty");
353 	s = xstrdup("");
354 	lowercase(s);
355 	ASSERT_STRING_EQ(s, "");
356 	free(s);
357 	TEST_DONE();
358 }
359 
360 static void
test_path_absolute(void)361 test_path_absolute(void)
362 {
363 	TEST_START("path_absolute absolute");
364 	ASSERT_INT_EQ(path_absolute("/foo/bar"), 1);
365 	TEST_DONE();
366 
367 	TEST_START("path_absolute relative");
368 	ASSERT_INT_EQ(path_absolute("foo/bar"), 0);
369 	TEST_DONE();
370 
371 	TEST_START("path_absolute empty");
372 	ASSERT_INT_EQ(path_absolute(""), 0);
373 	TEST_DONE();
374 }
375 
376 static void
test_stringlist(void)377 test_stringlist(void)
378 {
379 	char **list = NULL;
380 
381 	TEST_START("stringlist_append initial");
382 	stringlist_append(&list, "one");
383 	ASSERT_PTR_NE(list, NULL);
384 	ASSERT_STRING_EQ(list[0], "one");
385 	ASSERT_PTR_EQ(list[1], NULL);
386 	TEST_DONE();
387 
388 	TEST_START("stringlist_append second");
389 	stringlist_append(&list, "two");
390 	ASSERT_PTR_NE(list, NULL);
391 	ASSERT_STRING_EQ(list[0], "one");
392 	ASSERT_STRING_EQ(list[1], "two");
393 	ASSERT_PTR_EQ(list[2], NULL);
394 	TEST_DONE();
395 
396 	TEST_START("stringlist_append third");
397 	stringlist_append(&list, "three");
398 	ASSERT_PTR_NE(list, NULL);
399 	ASSERT_STRING_EQ(list[0], "one");
400 	ASSERT_STRING_EQ(list[1], "two");
401 	ASSERT_STRING_EQ(list[2], "three");
402 	ASSERT_PTR_EQ(list[3], NULL);
403 	TEST_DONE();
404 
405 	TEST_START("stringlist_free");
406 	stringlist_free(list);
407 	TEST_DONE();
408 
409 	TEST_START("stringlist_free NULL");
410 	stringlist_free(NULL);
411 	TEST_DONE();
412 }
413 
414 static void
test_skip_space(void)415 test_skip_space(void)
416 {
417 	char *s, *p;
418 
419 	TEST_START("skip_space leading spaces");
420 	s = p = xstrdup("  hello");
421 	skip_space(&p);
422 	ASSERT_STRING_EQ(p, "hello");
423 	free(s);
424 	TEST_DONE();
425 
426 	TEST_START("skip_space leading tabs");
427 	s = p = xstrdup("\t\thello");
428 	skip_space(&p);
429 	ASSERT_STRING_EQ(p, "hello");
430 	free(s);
431 	TEST_DONE();
432 
433 	TEST_START("skip_space leading mixed whitespace");
434 	s = p = xstrdup(" \t hello");
435 	skip_space(&p);
436 	ASSERT_STRING_EQ(p, "hello");
437 	free(s);
438 	TEST_DONE();
439 
440 	TEST_START("skip_space no leading whitespace");
441 	s = p = xstrdup("hello");
442 	skip_space(&p);
443 	ASSERT_STRING_EQ(p, "hello");
444 	free(s);
445 	TEST_DONE();
446 
447 	TEST_START("skip_space empty string");
448 	s = p = xstrdup("");
449 	skip_space(&p);
450 	ASSERT_STRING_EQ(p, "");
451 	free(s);
452 	TEST_DONE();
453 
454 	TEST_START("skip_space only whitespace");
455 	s = p = xstrdup(" \t ");
456 	skip_space(&p);
457 	ASSERT_STRING_EQ(p, "");
458 	free(s);
459 	TEST_DONE();
460 }
461 
462 void
test_misc(void)463 test_misc(void)
464 {
465 	test_chop();
466 	test_rtrim();
467 	test_strprefix();
468 	test_fmt_timeframe();
469 	test_arglist();
470 	test_tohex();
471 	test_lowercase();
472 	test_path_absolute();
473 	test_stringlist();
474 	test_skip_space();
475 }
476