s4:torture: Initialize param arrays
[Samba.git] / lib / util / tests / util.c
blob0b69e215f820667a683b239e2e28ea7918850ebd
1 /*
2 * Tests for strv_util
4 * Copyright Martin Schwenke <martin@meltin.net> 2016
5 * Copyright Christof Schmitt <cs@samba.org> 2018
6 * Copyright Swen Schillig <swen@linux.ibm.com> 2019
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <talloc.h>
24 #include "replace.h"
25 #include "system/filesys.h"
27 #include "libcli/util/ntstatus.h"
28 #include "torture/torture.h"
29 #include "lib/util/data_blob.h"
30 #include "torture/local/proto.h"
32 #include "lib/util/samba_util.h"
33 #include "lib/util/smb_strtox.h"
35 #include "limits.h"
36 #include "string.h"
38 struct test_trim_string_data {
39 const char *desc;
40 const char *in;
41 const char *front;
42 const char *back;
43 const char *out;
44 bool ret;
47 static const struct test_trim_string_data test_trim_string_data[] = {
49 .desc = "All NULL",
50 .in = NULL,
51 .front = NULL,
52 .back = NULL,
53 .out = NULL,
54 .ret = false,
57 .desc = "Input NULL",
58 .in = NULL,
59 .front = "abc",
60 .back = "123",
61 .out = NULL,
62 .ret = false,
65 .desc = "Trim NULL",
66 .in = "abc",
67 .front = NULL,
68 .back = NULL,
69 .out = "abc",
70 .ret = false,
73 .desc = "Trim empty",
74 .in = "abc",
75 .front = "",
76 .back = "",
77 .out = "abc",
78 .ret = false,
81 .desc = "Trim front, non-matching",
82 .in = "abc",
83 .front = "x",
84 .back = "",
85 .out = "abc",
86 .ret = false,
89 .desc = "Trim front, matches back",
90 .in = "abc",
91 .front = "c",
92 .back = "",
93 .out = "abc",
94 .ret = false,
97 .desc = "Trim front, partial-match",
98 .in = "abc",
99 .front = "ac",
100 .back = "",
101 .out = "abc",
102 .ret = false,
105 .desc = "Trim front, too long",
106 .in = "aaa",
107 .front = "aaaa",
108 .back = "",
109 .out = "aaa",
110 .ret = false,
113 .desc = "Trim front, 1 char, 1x",
114 .in = "abc",
115 .front = "a",
116 .back = "",
117 .out = "bc",
118 .ret = true,
121 .desc = "Trim front, 1 char, 2x",
122 .in = "aabc",
123 .front = "a",
124 .back = "",
125 .out = "bc",
126 .ret = true,
129 .desc = "Trim front, 1 char, 3x",
130 .in = "aaabc",
131 .front = "a",
132 .back = "",
133 .out = "bc",
134 .ret = true,
137 .desc = "Trim front, 1 char, matches all",
138 .in = "aaa",
139 .front = "a",
140 .back = "",
141 .out = "",
142 .ret = true,
145 .desc = "Trim front, 2 chars, 1x",
146 .in = "abc",
147 .front = "ab",
148 .back = "",
149 .out = "c",
150 .ret = true,
153 .desc = "Trim front, 2 chars, 2x",
154 .in = "ababc",
155 .front = "ab",
156 .back = "",
157 .out = "c",
158 .ret = true,
161 .desc = "Trim front, 3 chars, matches all",
162 .in = "abc",
163 .front = "abc",
164 .back = "",
165 .out = "",
166 .ret = true,
169 .desc = "Trim back, non-matching",
170 .in = "abc",
171 .front = "",
172 .back = "x",
173 .out = "abc",
174 .ret = false,
177 .desc = "Trim back, matches front",
178 .in = "abc",
179 .front = "",
180 .back = "a",
181 .out = "abc",
182 .ret = false,
185 .desc = "Trim back, partial-match",
186 .in = "abc",
187 .front = "",
188 .back = "xc",
189 .out = "abc",
190 .ret = false,
193 .desc = "Trim back, too long",
194 .in = "aaa",
195 .front = "",
196 .back = "aaaa",
197 .out = "aaa",
198 .ret = false,
201 .desc = "Trim back, 1 char, 1x",
202 .in = "abc",
203 .front = "",
204 .back = "c",
205 .out = "ab",
206 .ret = true,
209 .desc = "Trim back, 1 char, 2x",
210 .in = "abcc",
211 .front = "",
212 .back = "c",
213 .out = "ab",
214 .ret = true,
217 .desc = "Trim back, 1 char, 3x",
218 .in = "abccc",
219 .front = "",
220 .back = "c",
221 .out = "ab",
222 .ret = true,
225 .desc = "Trim back, 1 char, matches all",
226 .in = "aaa",
227 .front = "",
228 .back = "a",
229 .out = "",
230 .ret = true,
233 .desc = "Trim back, 2 chars, 1x",
234 .in = "abc",
235 .front = "",
236 .back = "bc",
237 .out = "a",
238 .ret = true,
241 .desc = "Trim back, 2 chars, 2x",
242 .in = "abcbc",
243 .front = "",
244 .back = "bc",
245 .out = "a",
246 .ret = true,
249 .desc = "Trim back, 3 chars, matches all",
250 .in = "abc",
251 .front = "",
252 .back = "abc",
253 .out = "",
254 .ret = true,
257 .desc = "Trim both, non-matching",
258 .in = "abc",
259 .front = "x",
260 .back = "y",
261 .out = "abc",
262 .ret = false,
265 .desc = "Trim both, reversed",
266 .in = "abc",
267 .front = "c",
268 .back = "a",
269 .out = "abc",
270 .ret = false,
273 .desc = "Trim both, 1 char, 1x",
274 .in = "abc",
275 .front = "a",
276 .back = "c",
277 .out = "b",
278 .ret = true,
281 .desc = "Trim both, 1 char, 2x",
282 .in = "aabcc",
283 .front = "a",
284 .back = "c",
285 .out = "b",
286 .ret = true,
289 .desc = "Trim both, 1 char, 3x",
290 .in = "aaabccc",
291 .front = "a",
292 .back = "c",
293 .out = "b",
294 .ret = true,
297 .desc = "Trim both, 1 char, matches all",
298 .in = "aaabbb",
299 .front = "a",
300 .back = "b",
301 .out = "",
302 .ret = true,
305 .desc = "Trim both, 2 chars, 1x",
306 .in = "abxbc",
307 .front = "ab",
308 .back = "bc",
309 .out = "x",
310 .ret = true,
313 .desc = "Trim both, 2 chars, 2x",
314 .in = "ababxyzbcbc",
315 .front = "ab",
316 .back = "bc",
317 .out = "xyz",
318 .ret = true,
321 .desc = "Trim both, 2 chars, front matches, back doesn't",
322 .in = "abcde",
323 .front = "ab",
324 .back = "xy",
325 .out = "cde",
326 .ret = true,
329 .desc = "Trim both, 2 chars, back matches, front doesn't",
330 .in = "abcde",
331 .front = "xy",
332 .back = "de",
333 .out = "abc",
334 .ret = true,
337 .desc = "Trim back, 3 chars, matches all",
338 .in = "abcxyz",
339 .front = "abc",
340 .back = "xyz",
341 .out = "",
342 .ret = true,
346 static bool test_trim_string(struct torture_context *tctx)
348 int j;
349 for (j = 0; j < ARRAY_SIZE(test_trim_string_data); j++) {
350 bool ret;
351 const struct test_trim_string_data *d =
352 &test_trim_string_data[j];
353 char *str = talloc_strdup(tctx, d->in);
354 torture_assert(tctx, d->in == NULL || str != NULL,
355 "Out of memory");
357 torture_comment(tctx, "%s\n", d->desc);
358 ret = trim_string(str, d->front, d->back);
359 torture_assert(tctx, ret == d->ret,
360 "Incorrect return from trim_string()");
361 if (d->out == NULL) {
362 torture_assert(tctx, str == NULL, "Expected NULL");
363 } else {
364 torture_assert(tctx, str != NULL, "Expected non-NULL");
365 torture_assert_str_equal(tctx, str, d->out,
366 "Incorrect output");
368 TALLOC_FREE(str);
371 return true;
374 static bool test_directory_create_or_exist(struct torture_context *tctx)
376 char *path = NULL, *new_path = NULL, *file_path = NULL;
377 bool ret = true, b = true;
378 int fd;
379 NTSTATUS status;
380 const mode_t perms = 0741;
382 status = torture_temp_dir(tctx, "util_dir", &path);;
383 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
384 "Creating test directory failed.\n");
386 b = directory_create_or_exist(path, perms);
387 torture_assert_goto(tctx, b == true, ret, done,
388 "directory_create_or_exist on "
389 "existing directory failed.\n");
391 new_path = talloc_asprintf(tctx, "%s/%s", path, "dir");
392 torture_assert_goto(tctx, new_path != NULL, ret, done,
393 "Could not allocate memory for directory path\n");
395 b = directory_exist(new_path);
396 torture_assert_goto(tctx, b == false, ret, done,
397 "Check for non-existing directory failed.\n");
399 b = directory_create_or_exist(new_path, perms);
400 torture_assert_goto(tctx, b == true, ret, done,
401 "directory_create_or_exist for "
402 "new directory failed.\n");
404 b = directory_exist(new_path);
405 torture_assert_goto(tctx, b == true, ret, done,
406 "Check for existing directory failed.\n");
408 b = file_check_permissions(new_path, geteuid(), perms, NULL);
409 torture_assert_goto(tctx, b == true, ret, done,
410 "Permission check for directory failed.\n");
412 file_path = talloc_asprintf(tctx, "%s/%s", path, "file");
413 torture_assert_goto(tctx, file_path != NULL, ret, done,
414 "Could not allocate memory for file path\n");
415 fd = creat(file_path, perms);
416 torture_assert_goto(tctx, fd != -1, ret, done,
417 "Creating file failed.\n");
418 close(fd);
420 b = directory_create_or_exist(file_path, perms);
421 torture_assert_goto(tctx, b == false, ret, done,
422 "directory_create_or_exist for "
423 "existing file failed.\n");
425 done:
426 return ret;
429 static bool test_mem_equal_const_time(struct torture_context *tctx)
431 const char *test_string = "abcdabcd";
433 torture_assert(tctx, mem_equal_const_time("", "", 0),
434 "zero-length comparison failed");
436 torture_assert(tctx, mem_equal_const_time(test_string, test_string, 8),
437 "comparison with equal pointers failed");
439 torture_assert(tctx, mem_equal_const_time(test_string, test_string + 4, 4),
440 "comparison with non-equal pointers failed");
442 torture_assert(tctx, !mem_equal_const_time("abcd", "efgh", 4),
443 "comparison with different values failed");
445 return true;
448 static bool test_smb_strtoul_errno_check(struct torture_context *tctx)
450 const char *number = "123";
451 unsigned long int val = 0;
452 unsigned long long int vall = 0;
453 int err;
455 /* select an error code which is not set by the smb_strtoul routines */
456 errno = EAGAIN;
457 err = EAGAIN;
458 val = smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
459 torture_assert(tctx, errno == EAGAIN, "smb_strtoul: Expected EAGAIN");
460 torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
461 torture_assert(tctx, val == 123, "smb_strtoul: Expected value 123");
463 /* set err to an impossible value again before continuing */
464 err = EAGAIN;
465 vall = smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
466 torture_assert(tctx, errno == EAGAIN, "smb_strtoull: Expected EAGAIN");
467 torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
468 torture_assert(tctx, vall == 123, "smb_strtoul: Expected value 123");
470 return true;
473 static bool test_smb_strtoul_negative(struct torture_context *tctx)
475 const char *number = "-132";
476 const char *number2 = "132-";
477 unsigned long int val = 0;
478 unsigned long long int vall = 0;
479 int err;
481 err = 0;
482 smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
483 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
485 err = 0;
486 smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
487 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
489 /* it is allowed to have a "-" sign after a number,
490 * e.g. as part of a formular, however, it is not supposed to
491 * have an effect on the converted value.
494 err = 0;
495 val = smb_strtoul(number2, NULL, 0, &err, SMB_STR_STANDARD);
496 torture_assert(tctx, err == 0, "smb_strtoul: Expected no error");
497 torture_assert(tctx, val == 132, "smb_strtoul: Wrong value");
499 err = 0;
500 vall = smb_strtoull(number2, NULL, 0, &err, SMB_STR_STANDARD);
501 torture_assert(tctx, err == 0, "smb_strtoull: Expected no error");
502 torture_assert(tctx, vall == 132, "smb_strtoull: Wrong value");
504 return true;
507 static bool test_smb_strtoul_no_number(struct torture_context *tctx)
509 const char *number = "ghijk";
510 const char *blank = "";
511 int err;
513 err = 0;
514 smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
515 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
517 err = 0;
518 smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
519 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
521 err = 0;
522 smb_strtoul(blank, NULL, 0, &err, SMB_STR_STANDARD);
523 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
525 err = 0;
526 smb_strtoull(blank, NULL, 0, &err, SMB_STR_STANDARD);
527 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
529 return true;
532 static bool test_smb_strtoul_allow_negative(struct torture_context *tctx)
534 const char *number = "-1";
535 const char *number2 = "-1-1";
536 unsigned long res = 0;
537 unsigned long long res2 = 0;
538 char *end_ptr = NULL;
539 int err;
541 err = 0;
542 res = smb_strtoul(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
543 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
544 torture_assert(tctx, res == ULONG_MAX, "strtoul_err: Unexpected value");
546 err = 0;
547 res2 = smb_strtoull(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
548 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
549 torture_assert(tctx, res2 == ULLONG_MAX, "strtoull_err: Unexpected value");
551 err = 0;
552 smb_strtoul(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
553 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
554 torture_assert(tctx, end_ptr[0] == '-', "strtoul_err: Unexpected end pointer");
556 err = 0;
557 smb_strtoull(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
558 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
559 torture_assert(tctx, end_ptr[0] == '-', "strtoull_err: Unexpected end pointer");
561 return true;
564 static bool test_smb_strtoul_full_string(struct torture_context *tctx)
566 const char *number = "123 ";
567 const char *number2 = "123";
568 int err;
570 err = 0;
571 smb_strtoul(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
572 torture_assert(tctx, err == EINVAL, "strtoul_err: Expected EINVAL");
574 err = 0;
575 smb_strtoull(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
576 torture_assert(tctx, err == EINVAL, "strtoull_err: Expected EINVAL");
578 err = 0;
579 smb_strtoul(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
580 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
582 err = 0;
583 smb_strtoull(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
584 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
586 return true;
589 static bool test_smb_strtoul_allow_no_conversion(struct torture_context *tctx)
591 const char *number = "";
592 const char *number2 = "xyz";
593 unsigned long int n1 = 0;
594 unsigned long long int n2 = 0;
595 int err;
597 err = 0;
598 smb_strtoul(number, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
599 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
600 torture_assert(tctx, n1 == 0, "strtoul_err: Unexpected value");
602 err = 0;
603 smb_strtoull(number, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
604 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
605 torture_assert(tctx, n2 == 0, "strtoull_err: Unexpected value");
607 err = 0;
608 smb_strtoul(number2, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
609 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
610 torture_assert(tctx, n1 == 0, "strtoul_err: Unexpected value");
612 err = 0;
613 smb_strtoull(number2, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
614 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
615 torture_assert(tctx, n2 == 0, "strtoull_err: Unexpected value");
617 return true;
619 struct torture_suite *torture_local_util(TALLOC_CTX *mem_ctx)
621 struct torture_suite *suite =
622 torture_suite_create(mem_ctx, "util");
624 torture_suite_add_simple_test(suite,
625 "trim_string",
626 test_trim_string);
627 torture_suite_add_simple_test(suite,
628 "directory_create_or_exist",
629 test_directory_create_or_exist);
630 torture_suite_add_simple_test(suite,
631 "mem_equal_const_time",
632 test_mem_equal_const_time);
633 torture_suite_add_simple_test(suite,
634 "smb_strtoul(l) errno",
635 test_smb_strtoul_errno_check);
636 torture_suite_add_simple_test(suite,
637 "smb_strtoul(l) negative",
638 test_smb_strtoul_negative);
639 torture_suite_add_simple_test(suite,
640 "smb_strtoul(l) no number",
641 test_smb_strtoul_no_number);
642 torture_suite_add_simple_test(suite,
643 "smb_strtoul(l) allow_negative",
644 test_smb_strtoul_allow_negative);
645 torture_suite_add_simple_test(suite,
646 "smb_strtoul(l) full string conversion",
647 test_smb_strtoul_full_string);
648 torture_suite_add_simple_test(suite,
649 "smb_strtoul(l) allow no conversion",
650 test_smb_strtoul_allow_no_conversion);
651 return suite;