tests-util: Adding test to verify "full-string-conversion" flag
[samba.git] / lib / util / tests / util.c
blob4741f466b35c01f3e94be18d33585dbba84fcabf
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"
34 #include "limits.h"
35 #include "string.h"
37 struct test_trim_string_data {
38 const char *desc;
39 const char *in;
40 const char *front;
41 const char *back;
42 const char *out;
43 bool ret;
46 static const struct test_trim_string_data test_trim_string_data[] = {
48 .desc = "All NULL",
49 .in = NULL,
50 .front = NULL,
51 .back = NULL,
52 .out = NULL,
53 .ret = false,
56 .desc = "Input NULL",
57 .in = NULL,
58 .front = "abc",
59 .back = "123",
60 .out = NULL,
61 .ret = false,
64 .desc = "Trim NULL",
65 .in = "abc",
66 .front = NULL,
67 .back = NULL,
68 .out = "abc",
69 .ret = false,
72 .desc = "Trim empty",
73 .in = "abc",
74 .front = "",
75 .back = "",
76 .out = "abc",
77 .ret = false,
80 .desc = "Trim front, non-matching",
81 .in = "abc",
82 .front = "x",
83 .back = "",
84 .out = "abc",
85 .ret = false,
88 .desc = "Trim front, matches back",
89 .in = "abc",
90 .front = "c",
91 .back = "",
92 .out = "abc",
93 .ret = false,
96 .desc = "Trim front, partial-match",
97 .in = "abc",
98 .front = "ac",
99 .back = "",
100 .out = "abc",
101 .ret = false,
104 .desc = "Trim front, too long",
105 .in = "aaa",
106 .front = "aaaa",
107 .back = "",
108 .out = "aaa",
109 .ret = false,
112 .desc = "Trim front, 1 char, 1x",
113 .in = "abc",
114 .front = "a",
115 .back = "",
116 .out = "bc",
117 .ret = true,
120 .desc = "Trim front, 1 char, 2x",
121 .in = "aabc",
122 .front = "a",
123 .back = "",
124 .out = "bc",
125 .ret = true,
128 .desc = "Trim front, 1 char, 3x",
129 .in = "aaabc",
130 .front = "a",
131 .back = "",
132 .out = "bc",
133 .ret = true,
136 .desc = "Trim front, 1 char, matches all",
137 .in = "aaa",
138 .front = "a",
139 .back = "",
140 .out = "",
141 .ret = true,
144 .desc = "Trim front, 2 chars, 1x",
145 .in = "abc",
146 .front = "ab",
147 .back = "",
148 .out = "c",
149 .ret = true,
152 .desc = "Trim front, 2 chars, 2x",
153 .in = "ababc",
154 .front = "ab",
155 .back = "",
156 .out = "c",
157 .ret = true,
160 .desc = "Trim front, 3 chars, matches all",
161 .in = "abc",
162 .front = "abc",
163 .back = "",
164 .out = "",
165 .ret = true,
168 .desc = "Trim back, non-matching",
169 .in = "abc",
170 .front = "",
171 .back = "x",
172 .out = "abc",
173 .ret = false,
176 .desc = "Trim back, matches front",
177 .in = "abc",
178 .front = "",
179 .back = "a",
180 .out = "abc",
181 .ret = false,
184 .desc = "Trim back, partial-match",
185 .in = "abc",
186 .front = "",
187 .back = "xc",
188 .out = "abc",
189 .ret = false,
192 .desc = "Trim back, too long",
193 .in = "aaa",
194 .front = "",
195 .back = "aaaa",
196 .out = "aaa",
197 .ret = false,
200 .desc = "Trim back, 1 char, 1x",
201 .in = "abc",
202 .front = "",
203 .back = "c",
204 .out = "ab",
205 .ret = true,
208 .desc = "Trim back, 1 char, 2x",
209 .in = "abcc",
210 .front = "",
211 .back = "c",
212 .out = "ab",
213 .ret = true,
216 .desc = "Trim back, 1 char, 3x",
217 .in = "abccc",
218 .front = "",
219 .back = "c",
220 .out = "ab",
221 .ret = true,
224 .desc = "Trim back, 1 char, matches all",
225 .in = "aaa",
226 .front = "",
227 .back = "a",
228 .out = "",
229 .ret = true,
232 .desc = "Trim back, 2 chars, 1x",
233 .in = "abc",
234 .front = "",
235 .back = "bc",
236 .out = "a",
237 .ret = true,
240 .desc = "Trim back, 2 chars, 2x",
241 .in = "abcbc",
242 .front = "",
243 .back = "bc",
244 .out = "a",
245 .ret = true,
248 .desc = "Trim back, 3 chars, matches all",
249 .in = "abc",
250 .front = "",
251 .back = "abc",
252 .out = "",
253 .ret = true,
256 .desc = "Trim both, non-matching",
257 .in = "abc",
258 .front = "x",
259 .back = "y",
260 .out = "abc",
261 .ret = false,
264 .desc = "Trim both, reversed",
265 .in = "abc",
266 .front = "c",
267 .back = "a",
268 .out = "abc",
269 .ret = false,
272 .desc = "Trim both, 1 char, 1x",
273 .in = "abc",
274 .front = "a",
275 .back = "c",
276 .out = "b",
277 .ret = true,
280 .desc = "Trim both, 1 char, 2x",
281 .in = "aabcc",
282 .front = "a",
283 .back = "c",
284 .out = "b",
285 .ret = true,
288 .desc = "Trim both, 1 char, 3x",
289 .in = "aaabccc",
290 .front = "a",
291 .back = "c",
292 .out = "b",
293 .ret = true,
296 .desc = "Trim both, 1 char, matches all",
297 .in = "aaabbb",
298 .front = "a",
299 .back = "b",
300 .out = "",
301 .ret = true,
304 .desc = "Trim both, 2 chars, 1x",
305 .in = "abxbc",
306 .front = "ab",
307 .back = "bc",
308 .out = "x",
309 .ret = true,
312 .desc = "Trim both, 2 chars, 2x",
313 .in = "ababxyzbcbc",
314 .front = "ab",
315 .back = "bc",
316 .out = "xyz",
317 .ret = true,
320 .desc = "Trim both, 2 chars, front matches, back doesn't",
321 .in = "abcde",
322 .front = "ab",
323 .back = "xy",
324 .out = "cde",
325 .ret = true,
328 .desc = "Trim both, 2 chars, back matches, front doesn't",
329 .in = "abcde",
330 .front = "xy",
331 .back = "de",
332 .out = "abc",
333 .ret = true,
336 .desc = "Trim back, 3 chars, matches all",
337 .in = "abcxyz",
338 .front = "abc",
339 .back = "xyz",
340 .out = "",
341 .ret = true,
345 static bool test_trim_string(struct torture_context *tctx)
347 int j;
348 for (j = 0; j < ARRAY_SIZE(test_trim_string_data); j++) {
349 bool ret;
350 const struct test_trim_string_data *d =
351 &test_trim_string_data[j];
352 char *str = talloc_strdup(tctx, d->in);
353 torture_assert(tctx, d->in == NULL || str != NULL,
354 "Out of memory");
356 torture_comment(tctx, "%s\n", d->desc);
357 ret = trim_string(str, d->front, d->back);
358 torture_assert(tctx, ret == d->ret,
359 "Incorrect return from trim_string()");
360 if (d->out == NULL) {
361 torture_assert(tctx, str == NULL, "Expected NULL");
362 } else {
363 torture_assert(tctx, str != NULL, "Expected non-NULL");
364 torture_assert_str_equal(tctx, str, d->out,
365 "Incorrect output");
367 TALLOC_FREE(str);
370 return true;
373 static bool test_directory_create_or_exist(struct torture_context *tctx)
375 char *path = NULL, *new_path = NULL, *file_path = NULL;
376 bool ret = true, b = true;
377 int fd;
378 NTSTATUS status;
379 const mode_t perms = 0741;
381 status = torture_temp_dir(tctx, "util_dir", &path);;
382 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
383 "Creating test directory failed.\n");
385 b = directory_create_or_exist(path, perms);
386 torture_assert_goto(tctx, b == true, ret, done,
387 "directory_create_or_exist on "
388 "existing directory failed.\n");
390 new_path = talloc_asprintf(tctx, "%s/%s", path, "dir");
391 torture_assert_goto(tctx, new_path != NULL, ret, done,
392 "Could not allocate memory for directory path\n");
394 b = directory_exist(new_path);
395 torture_assert_goto(tctx, b == false, ret, done,
396 "Check for non-existing directory failed.\n");
398 b = directory_create_or_exist(new_path, perms);
399 torture_assert_goto(tctx, b == true, ret, done,
400 "directory_create_or_exist for "
401 "new directory failed.\n");
403 b = directory_exist(new_path);
404 torture_assert_goto(tctx, b == true, ret, done,
405 "Check for existing directory failed.\n");
407 b = file_check_permissions(new_path, geteuid(), perms, NULL);
408 torture_assert_goto(tctx, b == true, ret, done,
409 "Permission check for directory failed.\n");
411 file_path = talloc_asprintf(tctx, "%s/%s", path, "file");
412 torture_assert_goto(tctx, file_path != NULL, ret, done,
413 "Could not allocate memory for file path\n");
414 fd = creat(file_path, perms);
415 torture_assert_goto(tctx, fd != -1, ret, done,
416 "Creating file failed.\n");
417 close(fd);
419 b = directory_create_or_exist(file_path, perms);
420 torture_assert_goto(tctx, b == false, ret, done,
421 "directory_create_or_exist for "
422 "existing file failed.\n");
424 done:
425 return ret;
428 static bool test_smb_strtoul_errno_check(struct torture_context *tctx)
430 const char *number = "123";
431 unsigned long int val = 0;
432 unsigned long long int vall = 0;
433 int err;
435 /* select an error code which is not set by the smb_strtoul routines */
436 errno = EAGAIN;
437 err = EAGAIN;
438 val = smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
439 torture_assert(tctx, errno == EAGAIN, "smb_strtoul: Expected EAGAIN");
440 torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
441 torture_assert(tctx, val == 123, "smb_strtoul: Expected value 123");
443 /* set err to an impossible value again before continuing */
444 err = EAGAIN;
445 vall = smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
446 torture_assert(tctx, errno == EAGAIN, "smb_strtoull: Expected EAGAIN");
447 torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
448 torture_assert(tctx, vall == 123, "smb_strtoul: Expected value 123");
450 return true;
453 static bool test_smb_strtoul_negative(struct torture_context *tctx)
455 const char *number = "-132";
456 const char *number2 = "132-";
457 unsigned long int val = 0;
458 unsigned long long int vall = 0;
459 int err;
461 err = 0;
462 smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
463 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
465 err = 0;
466 smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
467 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
469 /* it is allowed to have a "-" sign after a number,
470 * e.g. as part of a formular, however, it is not supposed to
471 * have an effect on the converted value.
474 err = 0;
475 val = smb_strtoul(number2, NULL, 0, &err, SMB_STR_STANDARD);
476 torture_assert(tctx, err == 0, "smb_strtoul: Expected no error");
477 torture_assert(tctx, val == 132, "smb_strtoul: Wrong value");
479 err = 0;
480 vall = smb_strtoull(number2, NULL, 0, &err, SMB_STR_STANDARD);
481 torture_assert(tctx, err == 0, "smb_strtoull: Expected no error");
482 torture_assert(tctx, vall == 132, "smb_strtoull: Wrong value");
484 return true;
487 static bool test_smb_strtoul_no_number(struct torture_context *tctx)
489 const char *number = "ghijk";
490 const char *blank = "";
491 int err;
493 err = 0;
494 smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
495 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
497 err = 0;
498 smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
499 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
501 err = 0;
502 smb_strtoul(blank, NULL, 0, &err, SMB_STR_STANDARD);
503 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
505 err = 0;
506 smb_strtoull(blank, NULL, 0, &err, SMB_STR_STANDARD);
507 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
509 return true;
512 static bool test_smb_strtoul_allow_negative(struct torture_context *tctx)
514 const char *number = "-1";
515 const char *number2 = "-1-1";
516 unsigned long res = 0;
517 unsigned long long res2 = 0;
518 char *end_ptr = NULL;
519 int err;
521 err = 0;
522 res = smb_strtoul(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
523 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
524 torture_assert(tctx, res == ULONG_MAX, "strtoul_err: Unexpected value");
526 err = 0;
527 res2 = smb_strtoull(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
528 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
529 torture_assert(tctx, res2 == ULLONG_MAX, "strtoull_err: Unexpected value");
531 err = 0;
532 smb_strtoul(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
533 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
534 torture_assert(tctx, end_ptr[0] == '-', "strtoul_err: Unexpected end pointer");
536 err = 0;
537 smb_strtoull(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
538 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
539 torture_assert(tctx, end_ptr[0] == '-', "strtoull_err: Unexpected end pointer");
541 return true;
544 static bool test_smb_strtoul_full_string(struct torture_context *tctx)
546 const char *number = "123 ";
547 const char *number2 = "123";
548 int err;
550 err = 0;
551 smb_strtoul(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
552 torture_assert(tctx, err == EINVAL, "strtoul_err: Expected EINVAL");
554 err = 0;
555 smb_strtoull(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
556 torture_assert(tctx, err == EINVAL, "strtoull_err: Expected EINVAL");
558 err = 0;
559 smb_strtoul(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
560 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
562 err = 0;
563 smb_strtoull(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
564 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
566 return true;
569 struct torture_suite *torture_local_util(TALLOC_CTX *mem_ctx)
571 struct torture_suite *suite =
572 torture_suite_create(mem_ctx, "util");
574 torture_suite_add_simple_test(suite,
575 "trim_string",
576 test_trim_string);
577 torture_suite_add_simple_test(suite,
578 "directory_create_or_exist",
579 test_directory_create_or_exist);
580 torture_suite_add_simple_test(suite,
581 "smb_strtoul(l) errno",
582 test_smb_strtoul_errno_check);
583 torture_suite_add_simple_test(suite,
584 "smb_strtoul(l) negative",
585 test_smb_strtoul_negative);
586 torture_suite_add_simple_test(suite,
587 "smb_strtoul(l) no number",
588 test_smb_strtoul_no_number);
589 torture_suite_add_simple_test(suite,
590 "smb_strtoul(l) allow_negative",
591 test_smb_strtoul_allow_negative);
592 torture_suite_add_simple_test(suite,
593 "smb_strtoul(l) full string conversion",
594 test_smb_strtoul_full_string);
595 return suite;