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/>.
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"
38 struct test_trim_string_data {
47 static const struct test_trim_string_data test_trim_string_data[] = {
81 .desc = "Trim front, non-matching",
89 .desc = "Trim front, matches back",
97 .desc = "Trim front, partial-match",
105 .desc = "Trim front, too long",
113 .desc = "Trim front, 1 char, 1x",
121 .desc = "Trim front, 1 char, 2x",
129 .desc = "Trim front, 1 char, 3x",
137 .desc = "Trim front, 1 char, matches all",
145 .desc = "Trim front, 2 chars, 1x",
153 .desc = "Trim front, 2 chars, 2x",
161 .desc = "Trim front, 3 chars, matches all",
169 .desc = "Trim back, non-matching",
177 .desc = "Trim back, matches front",
185 .desc = "Trim back, partial-match",
193 .desc = "Trim back, too long",
201 .desc = "Trim back, 1 char, 1x",
209 .desc = "Trim back, 1 char, 2x",
217 .desc = "Trim back, 1 char, 3x",
225 .desc = "Trim back, 1 char, matches all",
233 .desc = "Trim back, 2 chars, 1x",
241 .desc = "Trim back, 2 chars, 2x",
249 .desc = "Trim back, 3 chars, matches all",
257 .desc = "Trim both, non-matching",
265 .desc = "Trim both, reversed",
273 .desc = "Trim both, 1 char, 1x",
281 .desc = "Trim both, 1 char, 2x",
289 .desc = "Trim both, 1 char, 3x",
297 .desc = "Trim both, 1 char, matches all",
305 .desc = "Trim both, 2 chars, 1x",
313 .desc = "Trim both, 2 chars, 2x",
321 .desc = "Trim both, 2 chars, front matches, back doesn't",
329 .desc = "Trim both, 2 chars, back matches, front doesn't",
337 .desc = "Trim back, 3 chars, matches all",
346 static bool test_trim_string(struct torture_context *tctx)
349 for (j = 0; j < ARRAY_SIZE(test_trim_string_data); j++) {
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,
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");
364 torture_assert(tctx, str != NULL, "Expected non-NULL");
365 torture_assert_str_equal(tctx, str, d->out,
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;
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");
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");
429 static bool test_smb_strtoul_errno_check(struct torture_context *tctx)
431 const char *number = "123";
432 unsigned long int val = 0;
433 unsigned long long int vall = 0;
436 /* select an error code which is not set by the smb_strtoul routines */
439 val = smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
440 torture_assert(tctx, errno == EAGAIN, "smb_strtoul: Expected EAGAIN");
441 torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
442 torture_assert(tctx, val == 123, "smb_strtoul: Expected value 123");
444 /* set err to an impossible value again before continuing */
446 vall = smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
447 torture_assert(tctx, errno == EAGAIN, "smb_strtoull: Expected EAGAIN");
448 torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
449 torture_assert(tctx, vall == 123, "smb_strtoul: Expected value 123");
454 static bool test_smb_strtoul_negative(struct torture_context *tctx)
456 const char *number = "-132";
457 const char *number2 = "132-";
458 unsigned long int val = 0;
459 unsigned long long int vall = 0;
463 smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
464 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
467 smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
468 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
470 /* it is allowed to have a "-" sign after a number,
471 * e.g. as part of a formular, however, it is not supposed to
472 * have an effect on the converted value.
476 val = smb_strtoul(number2, NULL, 0, &err, SMB_STR_STANDARD);
477 torture_assert(tctx, err == 0, "smb_strtoul: Expected no error");
478 torture_assert(tctx, val == 132, "smb_strtoul: Wrong value");
481 vall = smb_strtoull(number2, NULL, 0, &err, SMB_STR_STANDARD);
482 torture_assert(tctx, err == 0, "smb_strtoull: Expected no error");
483 torture_assert(tctx, vall == 132, "smb_strtoull: Wrong value");
488 static bool test_smb_strtoul_no_number(struct torture_context *tctx)
490 const char *number = "ghijk";
491 const char *blank = "";
495 smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
496 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
499 smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
500 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
503 smb_strtoul(blank, NULL, 0, &err, SMB_STR_STANDARD);
504 torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
507 smb_strtoull(blank, NULL, 0, &err, SMB_STR_STANDARD);
508 torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
513 static bool test_smb_strtoul_allow_negative(struct torture_context *tctx)
515 const char *number = "-1";
516 const char *number2 = "-1-1";
517 unsigned long res = 0;
518 unsigned long long res2 = 0;
519 char *end_ptr = NULL;
523 res = smb_strtoul(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
524 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
525 torture_assert(tctx, res == ULONG_MAX, "strtoul_err: Unexpected value");
528 res2 = smb_strtoull(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
529 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
530 torture_assert(tctx, res2 == ULLONG_MAX, "strtoull_err: Unexpected value");
533 smb_strtoul(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
534 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
535 torture_assert(tctx, end_ptr[0] == '-', "strtoul_err: Unexpected end pointer");
538 smb_strtoull(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
539 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
540 torture_assert(tctx, end_ptr[0] == '-', "strtoull_err: Unexpected end pointer");
545 static bool test_smb_strtoul_full_string(struct torture_context *tctx)
547 const char *number = "123 ";
548 const char *number2 = "123";
552 smb_strtoul(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
553 torture_assert(tctx, err == EINVAL, "strtoul_err: Expected EINVAL");
556 smb_strtoull(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
557 torture_assert(tctx, err == EINVAL, "strtoull_err: Expected EINVAL");
560 smb_strtoul(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
561 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
564 smb_strtoull(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
565 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
570 static bool test_smb_strtoul_allow_no_conversion(struct torture_context *tctx)
572 const char *number = "";
573 const char *number2 = "xyz";
574 unsigned long int n1 = 0;
575 unsigned long long int n2 = 0;
579 smb_strtoul(number, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
580 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
581 torture_assert(tctx, n1 == 0, "strtoul_err: Unexpected value");
584 smb_strtoull(number, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
585 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
586 torture_assert(tctx, n2 == 0, "strtoull_err: Unexpected value");
589 smb_strtoul(number2, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
590 torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
591 torture_assert(tctx, n1 == 0, "strtoul_err: Unexpected value");
594 smb_strtoull(number2, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
595 torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
596 torture_assert(tctx, n2 == 0, "strtoull_err: Unexpected value");
600 struct torture_suite *torture_local_util(TALLOC_CTX *mem_ctx)
602 struct torture_suite *suite =
603 torture_suite_create(mem_ctx, "util");
605 torture_suite_add_simple_test(suite,
608 torture_suite_add_simple_test(suite,
609 "directory_create_or_exist",
610 test_directory_create_or_exist);
611 torture_suite_add_simple_test(suite,
612 "smb_strtoul(l) errno",
613 test_smb_strtoul_errno_check);
614 torture_suite_add_simple_test(suite,
615 "smb_strtoul(l) negative",
616 test_smb_strtoul_negative);
617 torture_suite_add_simple_test(suite,
618 "smb_strtoul(l) no number",
619 test_smb_strtoul_no_number);
620 torture_suite_add_simple_test(suite,
621 "smb_strtoul(l) allow_negative",
622 test_smb_strtoul_allow_negative);
623 torture_suite_add_simple_test(suite,
624 "smb_strtoul(l) full string conversion",
625 test_smb_strtoul_full_string);
626 torture_suite_add_simple_test(suite,
627 "smb_strtoul(l) allow no conversion",
628 test_smb_strtoul_allow_no_conversion);