2016-06-19 13:40:18 +10:00
/*
* Tests for strv_util
*
* Copyright Martin Schwenke < martin @ meltin . net > 2016
2018-08-29 12:07:42 -07:00
* Copyright Christof Schmitt < cs @ samba . org > 2018
2019-04-10 10:24:52 +02:00
* Copyright Swen Schillig < swen @ linux . ibm . com > 2019
2016-06-19 13:40:18 +10:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <talloc.h>
# include "replace.h"
2018-08-31 06:25:30 +02:00
# include "system/filesys.h"
2016-06-19 13:40:18 +10:00
# include "libcli/util/ntstatus.h"
# include "torture/torture.h"
# include "lib/util/data_blob.h"
# include "torture/local/proto.h"
# include "lib/util/samba_util.h"
2020-07-03 08:11:20 +02:00
# include "lib/util/smb_strtox.h"
2016-06-19 13:40:18 +10:00
2019-06-03 10:13:52 +02:00
# include "limits.h"
# include "string.h"
2016-06-19 13:40:18 +10:00
struct test_trim_string_data {
const char * desc ;
const char * in ;
const char * front ;
const char * back ;
const char * out ;
bool ret ;
} ;
static const struct test_trim_string_data test_trim_string_data [ ] = {
{
. desc = " All NULL " ,
. in = NULL ,
. front = NULL ,
. back = NULL ,
. out = NULL ,
. ret = false ,
} ,
{
. desc = " Input NULL " ,
. in = NULL ,
. front = " abc " ,
. back = " 123 " ,
. out = NULL ,
. ret = false ,
} ,
{
. desc = " Trim NULL " ,
. in = " abc " ,
. front = NULL ,
. back = NULL ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim empty " ,
. in = " abc " ,
. front = " " ,
. back = " " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim front, non-matching " ,
. in = " abc " ,
. front = " x " ,
. back = " " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim front, matches back " ,
. in = " abc " ,
. front = " c " ,
. back = " " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim front, partial-match " ,
. in = " abc " ,
. front = " ac " ,
. back = " " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim front, too long " ,
. in = " aaa " ,
. front = " aaaa " ,
. back = " " ,
. out = " aaa " ,
. ret = false ,
} ,
{
. desc = " Trim front, 1 char, 1x " ,
. in = " abc " ,
. front = " a " ,
. back = " " ,
. out = " bc " ,
. ret = true ,
} ,
{
. desc = " Trim front, 1 char, 2x " ,
. in = " aabc " ,
. front = " a " ,
. back = " " ,
. out = " bc " ,
. ret = true ,
} ,
{
. desc = " Trim front, 1 char, 3x " ,
. in = " aaabc " ,
. front = " a " ,
. back = " " ,
. out = " bc " ,
. ret = true ,
} ,
{
. desc = " Trim front, 1 char, matches all " ,
. in = " aaa " ,
. front = " a " ,
. back = " " ,
. out = " " ,
. ret = true ,
} ,
{
. desc = " Trim front, 2 chars, 1x " ,
. in = " abc " ,
. front = " ab " ,
. back = " " ,
. out = " c " ,
. ret = true ,
} ,
{
. desc = " Trim front, 2 chars, 2x " ,
. in = " ababc " ,
. front = " ab " ,
. back = " " ,
. out = " c " ,
. ret = true ,
} ,
{
. desc = " Trim front, 3 chars, matches all " ,
. in = " abc " ,
. front = " abc " ,
. back = " " ,
. out = " " ,
. ret = true ,
} ,
{
. desc = " Trim back, non-matching " ,
. in = " abc " ,
. front = " " ,
. back = " x " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim back, matches front " ,
. in = " abc " ,
. front = " " ,
. back = " a " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim back, partial-match " ,
. in = " abc " ,
. front = " " ,
. back = " xc " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim back, too long " ,
. in = " aaa " ,
. front = " " ,
. back = " aaaa " ,
. out = " aaa " ,
. ret = false ,
} ,
{
. desc = " Trim back, 1 char, 1x " ,
. in = " abc " ,
. front = " " ,
. back = " c " ,
. out = " ab " ,
. ret = true ,
} ,
{
. desc = " Trim back, 1 char, 2x " ,
. in = " abcc " ,
. front = " " ,
. back = " c " ,
. out = " ab " ,
. ret = true ,
} ,
{
. desc = " Trim back, 1 char, 3x " ,
. in = " abccc " ,
. front = " " ,
. back = " c " ,
. out = " ab " ,
. ret = true ,
} ,
{
. desc = " Trim back, 1 char, matches all " ,
. in = " aaa " ,
. front = " " ,
. back = " a " ,
. out = " " ,
. ret = true ,
} ,
{
. desc = " Trim back, 2 chars, 1x " ,
. in = " abc " ,
. front = " " ,
. back = " bc " ,
. out = " a " ,
. ret = true ,
} ,
{
. desc = " Trim back, 2 chars, 2x " ,
. in = " abcbc " ,
. front = " " ,
. back = " bc " ,
. out = " a " ,
. ret = true ,
} ,
{
. desc = " Trim back, 3 chars, matches all " ,
. in = " abc " ,
. front = " " ,
. back = " abc " ,
. out = " " ,
. ret = true ,
} ,
{
. desc = " Trim both, non-matching " ,
. in = " abc " ,
. front = " x " ,
. back = " y " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim both, reversed " ,
. in = " abc " ,
. front = " c " ,
. back = " a " ,
. out = " abc " ,
. ret = false ,
} ,
{
. desc = " Trim both, 1 char, 1x " ,
. in = " abc " ,
. front = " a " ,
. back = " c " ,
. out = " b " ,
. ret = true ,
} ,
{
. desc = " Trim both, 1 char, 2x " ,
. in = " aabcc " ,
. front = " a " ,
. back = " c " ,
. out = " b " ,
. ret = true ,
} ,
{
. desc = " Trim both, 1 char, 3x " ,
. in = " aaabccc " ,
. front = " a " ,
. back = " c " ,
. out = " b " ,
. ret = true ,
} ,
{
. desc = " Trim both, 1 char, matches all " ,
. in = " aaabbb " ,
. front = " a " ,
. back = " b " ,
. out = " " ,
. ret = true ,
} ,
{
. desc = " Trim both, 2 chars, 1x " ,
. in = " abxbc " ,
. front = " ab " ,
. back = " bc " ,
. out = " x " ,
. ret = true ,
} ,
{
. desc = " Trim both, 2 chars, 2x " ,
. in = " ababxyzbcbc " ,
. front = " ab " ,
. back = " bc " ,
. out = " xyz " ,
. ret = true ,
} ,
{
. desc = " Trim both, 2 chars, front matches, back doesn't " ,
. in = " abcde " ,
. front = " ab " ,
. back = " xy " ,
. out = " cde " ,
. ret = true ,
} ,
{
. desc = " Trim both, 2 chars, back matches, front doesn't " ,
. in = " abcde " ,
. front = " xy " ,
. back = " de " ,
. out = " abc " ,
. ret = true ,
} ,
{
. desc = " Trim back, 3 chars, matches all " ,
. in = " abcxyz " ,
. front = " abc " ,
. back = " xyz " ,
. out = " " ,
. ret = true ,
} ,
} ;
static bool test_trim_string ( struct torture_context * tctx )
{
int j ;
for ( j = 0 ; j < ARRAY_SIZE ( test_trim_string_data ) ; j + + ) {
bool ret ;
const struct test_trim_string_data * d =
& test_trim_string_data [ j ] ;
char * str = talloc_strdup ( tctx , d - > in ) ;
torture_assert ( tctx , d - > in = = NULL | | str ! = NULL ,
" Out of memory " ) ;
torture_comment ( tctx , " %s \n " , d - > desc ) ;
ret = trim_string ( str , d - > front , d - > back ) ;
torture_assert ( tctx , ret = = d - > ret ,
" Incorrect return from trim_string() " ) ;
if ( d - > out = = NULL ) {
torture_assert ( tctx , str = = NULL , " Expected NULL " ) ;
} else {
torture_assert ( tctx , str ! = NULL , " Expected non-NULL " ) ;
torture_assert_str_equal ( tctx , str , d - > out ,
" Incorrect output " ) ;
}
TALLOC_FREE ( str ) ;
}
return true ;
}
2018-08-29 12:07:42 -07:00
static bool test_directory_create_or_exist ( struct torture_context * tctx )
{
char * path = NULL , * new_path = NULL , * file_path = NULL ;
bool ret = true , b = true ;
int fd ;
NTSTATUS status ;
const mode_t perms = 0741 ;
status = torture_temp_dir ( tctx , " util_dir " , & path ) ; ;
torture_assert_ntstatus_ok_goto ( tctx , status , ret , done ,
" Creating test directory failed. \n " ) ;
b = directory_create_or_exist ( path , perms ) ;
torture_assert_goto ( tctx , b = = true , ret , done ,
" directory_create_or_exist on "
" existing directory failed. \n " ) ;
new_path = talloc_asprintf ( tctx , " %s/%s " , path , " dir " ) ;
torture_assert_goto ( tctx , new_path ! = NULL , ret , done ,
" Could not allocate memory for directory path \n " ) ;
b = directory_exist ( new_path ) ;
torture_assert_goto ( tctx , b = = false , ret , done ,
" Check for non-existing directory failed. \n " ) ;
b = directory_create_or_exist ( new_path , perms ) ;
torture_assert_goto ( tctx , b = = true , ret , done ,
" directory_create_or_exist for "
" new directory failed. \n " ) ;
b = directory_exist ( new_path ) ;
torture_assert_goto ( tctx , b = = true , ret , done ,
" Check for existing directory failed. \n " ) ;
b = file_check_permissions ( new_path , geteuid ( ) , perms , NULL ) ;
torture_assert_goto ( tctx , b = = true , ret , done ,
" Permission check for directory failed. \n " ) ;
file_path = talloc_asprintf ( tctx , " %s/%s " , path , " file " ) ;
torture_assert_goto ( tctx , file_path ! = NULL , ret , done ,
" Could not allocate memory for file path \n " ) ;
fd = creat ( file_path , perms ) ;
torture_assert_goto ( tctx , fd ! = - 1 , ret , done ,
" Creating file failed. \n " ) ;
close ( fd ) ;
b = directory_create_or_exist ( file_path , perms ) ;
torture_assert_goto ( tctx , b = = false , ret , done ,
" directory_create_or_exist for "
" existing file failed. \n " ) ;
done :
return ret ;
}
2019-06-04 08:57:03 +02:00
static bool test_smb_strtoul_errno_check ( struct torture_context * tctx )
2019-04-10 10:24:52 +02:00
{
const char * number = " 123 " ;
unsigned long int val = 0 ;
unsigned long long int vall = 0 ;
int err ;
2019-06-04 08:57:03 +02:00
/* select an error code which is not set by the smb_strtoul routines */
2019-04-10 10:24:52 +02:00
errno = EAGAIN ;
err = EAGAIN ;
2019-06-04 08:57:03 +02:00
val = smb_strtoul ( number , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , errno = = EAGAIN , " smb_strtoul: Expected EAGAIN " ) ;
torture_assert ( tctx , err = = 0 , " smb_strtoul: Expected err = 0 " ) ;
torture_assert ( tctx , val = = 123 , " smb_strtoul: Expected value 123 " ) ;
2019-04-10 10:24:52 +02:00
/* set err to an impossible value again before continuing */
err = EAGAIN ;
2019-06-04 08:57:03 +02:00
vall = smb_strtoull ( number , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , errno = = EAGAIN , " smb_strtoull: Expected EAGAIN " ) ;
torture_assert ( tctx , err = = 0 , " smb_strtoul: Expected err = 0 " ) ;
torture_assert ( tctx , vall = = 123 , " smb_strtoul: Expected value 123 " ) ;
2019-04-10 10:24:52 +02:00
return true ;
}
2019-06-04 08:57:03 +02:00
static bool test_smb_strtoul_negative ( struct torture_context * tctx )
2019-04-10 10:44:06 +02:00
{
const char * number = " -132 " ;
const char * number2 = " 132- " ;
unsigned long int val = 0 ;
unsigned long long int vall = 0 ;
int err ;
err = 0 ;
2019-06-04 08:57:03 +02:00
smb_strtoul ( number , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = EINVAL , " smb_strtoul: Expected EINVAL " ) ;
2019-04-10 10:44:06 +02:00
err = 0 ;
2019-06-04 08:57:03 +02:00
smb_strtoull ( number , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = EINVAL , " smb_strtoull: Expected EINVAL " ) ;
2019-04-10 10:44:06 +02:00
/* it is allowed to have a "-" sign after a number,
* e . g . as part of a formular , however , it is not supposed to
* have an effect on the converted value .
*/
err = 0 ;
2019-06-04 08:57:03 +02:00
val = smb_strtoul ( number2 , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = 0 , " smb_strtoul: Expected no error " ) ;
torture_assert ( tctx , val = = 132 , " smb_strtoul: Wrong value " ) ;
2019-04-10 10:44:06 +02:00
err = 0 ;
2019-06-04 08:57:03 +02:00
vall = smb_strtoull ( number2 , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = 0 , " smb_strtoull: Expected no error " ) ;
torture_assert ( tctx , vall = = 132 , " smb_strtoull: Wrong value " ) ;
2019-04-10 10:44:06 +02:00
return true ;
}
2019-06-04 08:57:03 +02:00
static bool test_smb_strtoul_no_number ( struct torture_context * tctx )
2019-04-10 10:52:35 +02:00
{
const char * number = " ghijk " ;
const char * blank = " " ;
int err ;
err = 0 ;
2019-06-04 08:57:03 +02:00
smb_strtoul ( number , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = EINVAL , " smb_strtoul: Expected EINVAL " ) ;
2019-04-10 10:52:35 +02:00
err = 0 ;
2019-06-04 08:57:03 +02:00
smb_strtoull ( number , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = EINVAL , " smb_strtoull: Expected EINVAL " ) ;
2019-04-10 10:52:35 +02:00
err = 0 ;
2019-06-04 08:57:03 +02:00
smb_strtoul ( blank , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = EINVAL , " smb_strtoul: Expected EINVAL " ) ;
2019-04-10 10:52:35 +02:00
err = 0 ;
2019-06-04 08:57:03 +02:00
smb_strtoull ( blank , NULL , 0 , & err , SMB_STR_STANDARD ) ;
torture_assert ( tctx , err = = EINVAL , " smb_strtoull: Expected EINVAL " ) ;
2019-04-10 10:52:35 +02:00
return true ;
}
2019-06-03 10:13:52 +02:00
static bool test_smb_strtoul_allow_negative ( struct torture_context * tctx )
{
const char * number = " -1 " ;
const char * number2 = " -1-1 " ;
unsigned long res = 0 ;
unsigned long long res2 = 0 ;
char * end_ptr = NULL ;
int err ;
err = 0 ;
res = smb_strtoul ( number , NULL , 0 , & err , SMB_STR_ALLOW_NEGATIVE ) ;
torture_assert ( tctx , err = = 0 , " strtoul_err: Unexpected error " ) ;
torture_assert ( tctx , res = = ULONG_MAX , " strtoul_err: Unexpected value " ) ;
err = 0 ;
res2 = smb_strtoull ( number , NULL , 0 , & err , SMB_STR_ALLOW_NEGATIVE ) ;
torture_assert ( tctx , err = = 0 , " strtoull_err: Unexpected error " ) ;
torture_assert ( tctx , res2 = = ULLONG_MAX , " strtoull_err: Unexpected value " ) ;
err = 0 ;
smb_strtoul ( number2 , & end_ptr , 0 , & err , SMB_STR_ALLOW_NEGATIVE ) ;
torture_assert ( tctx , err = = 0 , " strtoul_err: Unexpected error " ) ;
torture_assert ( tctx , end_ptr [ 0 ] = = ' - ' , " strtoul_err: Unexpected end pointer " ) ;
err = 0 ;
smb_strtoull ( number2 , & end_ptr , 0 , & err , SMB_STR_ALLOW_NEGATIVE ) ;
torture_assert ( tctx , err = = 0 , " strtoull_err: Unexpected error " ) ;
torture_assert ( tctx , end_ptr [ 0 ] = = ' - ' , " strtoull_err: Unexpected end pointer " ) ;
return true ;
}
2019-06-03 10:37:07 +02:00
static bool test_smb_strtoul_full_string ( struct torture_context * tctx )
{
const char * number = " 123 " ;
const char * number2 = " 123 " ;
int err ;
err = 0 ;
smb_strtoul ( number , NULL , 0 , & err , SMB_STR_FULL_STR_CONV ) ;
torture_assert ( tctx , err = = EINVAL , " strtoul_err: Expected EINVAL " ) ;
err = 0 ;
smb_strtoull ( number , NULL , 0 , & err , SMB_STR_FULL_STR_CONV ) ;
torture_assert ( tctx , err = = EINVAL , " strtoull_err: Expected EINVAL " ) ;
err = 0 ;
smb_strtoul ( number2 , NULL , 0 , & err , SMB_STR_FULL_STR_CONV ) ;
torture_assert ( tctx , err = = 0 , " strtoul_err: Unexpected error " ) ;
err = 0 ;
smb_strtoull ( number2 , NULL , 0 , & err , SMB_STR_FULL_STR_CONV ) ;
torture_assert ( tctx , err = = 0 , " strtoull_err: Unexpected error " ) ;
return true ;
}
2019-06-03 10:58:11 +02:00
static bool test_smb_strtoul_allow_no_conversion ( struct torture_context * tctx )
{
const char * number = " " ;
const char * number2 = " xyz " ;
unsigned long int n1 = 0 ;
unsigned long long int n2 = 0 ;
int err ;
err = 0 ;
smb_strtoul ( number , NULL , 0 , & err , SMB_STR_ALLOW_NO_CONVERSION ) ;
torture_assert ( tctx , err = = 0 , " strtoul_err: Unexpected error " ) ;
torture_assert ( tctx , n1 = = 0 , " strtoul_err: Unexpected value " ) ;
err = 0 ;
smb_strtoull ( number , NULL , 0 , & err , SMB_STR_ALLOW_NO_CONVERSION ) ;
torture_assert ( tctx , err = = 0 , " strtoull_err: Unexpected error " ) ;
torture_assert ( tctx , n2 = = 0 , " strtoull_err: Unexpected value " ) ;
err = 0 ;
smb_strtoul ( number2 , NULL , 0 , & err , SMB_STR_ALLOW_NO_CONVERSION ) ;
torture_assert ( tctx , err = = 0 , " strtoul_err: Unexpected error " ) ;
torture_assert ( tctx , n1 = = 0 , " strtoul_err: Unexpected value " ) ;
err = 0 ;
smb_strtoull ( number2 , NULL , 0 , & err , SMB_STR_ALLOW_NO_CONVERSION ) ;
torture_assert ( tctx , err = = 0 , " strtoull_err: Unexpected error " ) ;
torture_assert ( tctx , n2 = = 0 , " strtoull_err: Unexpected value " ) ;
return true ;
}
2016-06-19 13:40:18 +10:00
struct torture_suite * torture_local_util ( TALLOC_CTX * mem_ctx )
{
struct torture_suite * suite =
torture_suite_create ( mem_ctx , " util " ) ;
torture_suite_add_simple_test ( suite ,
" trim_string " ,
test_trim_string ) ;
2018-08-29 12:07:42 -07:00
torture_suite_add_simple_test ( suite ,
" directory_create_or_exist " ,
test_directory_create_or_exist ) ;
2019-04-10 10:24:52 +02:00
torture_suite_add_simple_test ( suite ,
2019-06-04 08:57:03 +02:00
" smb_strtoul(l) errno " ,
test_smb_strtoul_errno_check ) ;
2019-04-10 10:44:06 +02:00
torture_suite_add_simple_test ( suite ,
2019-06-04 08:57:03 +02:00
" smb_strtoul(l) negative " ,
test_smb_strtoul_negative ) ;
2019-04-10 10:52:35 +02:00
torture_suite_add_simple_test ( suite ,
2019-06-04 08:57:03 +02:00
" smb_strtoul(l) no number " ,
test_smb_strtoul_no_number ) ;
2019-06-03 10:13:52 +02:00
torture_suite_add_simple_test ( suite ,
" smb_strtoul(l) allow_negative " ,
test_smb_strtoul_allow_negative ) ;
2019-06-03 10:37:07 +02:00
torture_suite_add_simple_test ( suite ,
" smb_strtoul(l) full string conversion " ,
test_smb_strtoul_full_string ) ;
2019-06-03 10:58:11 +02:00
torture_suite_add_simple_test ( suite ,
" smb_strtoul(l) allow no conversion " ,
test_smb_strtoul_allow_no_conversion ) ;
2016-06-19 13:40:18 +10:00
return suite ;
}