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"
37 struct test_trim_string_data
{
46 static const struct test_trim_string_data test_trim_string_data
[] = {
80 .desc
= "Trim front, non-matching",
88 .desc
= "Trim front, matches back",
96 .desc
= "Trim front, partial-match",
104 .desc
= "Trim front, too long",
112 .desc
= "Trim front, 1 char, 1x",
120 .desc
= "Trim front, 1 char, 2x",
128 .desc
= "Trim front, 1 char, 3x",
136 .desc
= "Trim front, 1 char, matches all",
144 .desc
= "Trim front, 2 chars, 1x",
152 .desc
= "Trim front, 2 chars, 2x",
160 .desc
= "Trim front, 3 chars, matches all",
168 .desc
= "Trim back, non-matching",
176 .desc
= "Trim back, matches front",
184 .desc
= "Trim back, partial-match",
192 .desc
= "Trim back, too long",
200 .desc
= "Trim back, 1 char, 1x",
208 .desc
= "Trim back, 1 char, 2x",
216 .desc
= "Trim back, 1 char, 3x",
224 .desc
= "Trim back, 1 char, matches all",
232 .desc
= "Trim back, 2 chars, 1x",
240 .desc
= "Trim back, 2 chars, 2x",
248 .desc
= "Trim back, 3 chars, matches all",
256 .desc
= "Trim both, non-matching",
264 .desc
= "Trim both, reversed",
272 .desc
= "Trim both, 1 char, 1x",
280 .desc
= "Trim both, 1 char, 2x",
288 .desc
= "Trim both, 1 char, 3x",
296 .desc
= "Trim both, 1 char, matches all",
304 .desc
= "Trim both, 2 chars, 1x",
312 .desc
= "Trim both, 2 chars, 2x",
320 .desc
= "Trim both, 2 chars, front matches, back doesn't",
328 .desc
= "Trim both, 2 chars, back matches, front doesn't",
336 .desc
= "Trim back, 3 chars, matches all",
345 static bool test_trim_string(struct torture_context
*tctx
)
348 for (j
= 0; j
< ARRAY_SIZE(test_trim_string_data
); j
++) {
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
,
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");
363 torture_assert(tctx
, str
!= NULL
, "Expected non-NULL");
364 torture_assert_str_equal(tctx
, str
, d
->out
,
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;
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");
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");
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;
435 /* select an error code which is not set by the smb_strtoul routines */
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 */
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");
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;
462 smb_strtoul(number
, NULL
, 0, &err
, SMB_STR_STANDARD
);
463 torture_assert(tctx
, err
== EINVAL
, "smb_strtoul: Expected EINVAL");
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.
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");
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");
487 static bool test_smb_strtoul_no_number(struct torture_context
*tctx
)
489 const char *number
= "ghijk";
490 const char *blank
= "";
494 smb_strtoul(number
, NULL
, 0, &err
, SMB_STR_STANDARD
);
495 torture_assert(tctx
, err
== EINVAL
, "smb_strtoul: Expected EINVAL");
498 smb_strtoull(number
, NULL
, 0, &err
, SMB_STR_STANDARD
);
499 torture_assert(tctx
, err
== EINVAL
, "smb_strtoull: Expected EINVAL");
502 smb_strtoul(blank
, NULL
, 0, &err
, SMB_STR_STANDARD
);
503 torture_assert(tctx
, err
== EINVAL
, "smb_strtoul: Expected EINVAL");
506 smb_strtoull(blank
, NULL
, 0, &err
, SMB_STR_STANDARD
);
507 torture_assert(tctx
, err
== EINVAL
, "smb_strtoull: Expected EINVAL");
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
;
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");
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");
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");
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");
544 static bool test_smb_strtoul_full_string(struct torture_context
*tctx
)
546 const char *number
= "123 ";
547 const char *number2
= "123";
551 smb_strtoul(number
, NULL
, 0, &err
, SMB_STR_FULL_STR_CONV
);
552 torture_assert(tctx
, err
== EINVAL
, "strtoul_err: Expected EINVAL");
555 smb_strtoull(number
, NULL
, 0, &err
, SMB_STR_FULL_STR_CONV
);
556 torture_assert(tctx
, err
== EINVAL
, "strtoull_err: Expected EINVAL");
559 smb_strtoul(number2
, NULL
, 0, &err
, SMB_STR_FULL_STR_CONV
);
560 torture_assert(tctx
, err
== 0, "strtoul_err: Unexpected error");
563 smb_strtoull(number2
, NULL
, 0, &err
, SMB_STR_FULL_STR_CONV
);
564 torture_assert(tctx
, err
== 0, "strtoull_err: Unexpected error");
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
,
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
);