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