Add more function input validation checks

darcs-hash:20060608235212-ac50b-25fd55f96356af65d4da1eec100cc954b4a9f81e.gz
This commit is contained in:
axel 2006-06-09 09:52:12 +10:00
parent 93ae00e8e5
commit f7118e769f
8 changed files with 162 additions and 16 deletions

View File

@ -2946,6 +2946,12 @@ void builtin_destroy()
int builtin_exists( wchar_t *cmd ) int builtin_exists( wchar_t *cmd )
{ {
if( !cmd )
{
debug( 0, L"%s called with null input", __func__ );
return 0;
}
/* /*
Count is not a builtin, but it's help is handled internally by Count is not a builtin, but it's help is handled internally by
fish, so it is in the hash_table_t. fish, so it is in the hash_table_t.
@ -2976,6 +2982,13 @@ static int internal_help( wchar_t *cmd )
int builtin_run( wchar_t **argv ) int builtin_run( wchar_t **argv )
{ {
int (*cmd)(wchar_t **argv)=0; int (*cmd)(wchar_t **argv)=0;
if( !argv || !argv[0] )
{
debug( 0, L"%s called with null input", __func__ );
return 1;
}
cmd = (int (*)(wchar_t **))hash_get( &builtin, argv[0] ); cmd = (int (*)(wchar_t **))hash_get( &builtin, argv[0] );
if( argv[1] != 0 && !internal_help(argv[0]) ) if( argv[1] != 0 && !internal_help(argv[0]) )
@ -3005,11 +3018,23 @@ int builtin_run( wchar_t **argv )
void builtin_get_names( array_list_t *list ) void builtin_get_names( array_list_t *list )
{ {
if( !list )
{
debug( 0, L"%s called with null input", __func__ );
return;
}
hash_get_keys( &builtin, list ); hash_get_keys( &builtin, list );
} }
const wchar_t *builtin_get_desc( const wchar_t *b ) const wchar_t *builtin_get_desc( const wchar_t *b )
{ {
if( !b )
{
debug( 0, L"%s called with null input", __func__ );
return 0;
}
if( !desc ) if( !desc )
{ {

View File

@ -159,6 +159,13 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
retcode=1; retcode=1;
break; break;
} }
case ENV_INVALID:
{
sb_printf( sb_err, _(L"%ls: Unknown error"), L"set" );
retcode=1;
break;
}
} }
sb_destroy( &sb ); sb_destroy( &sb );

View File

@ -336,7 +336,7 @@ char **wcsv2strv( const wchar_t **in )
wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b ) wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b )
{ {
return wcsdupcat2( a, b, 0 ); return wcsdupcat2( a, b, (void *)0 );
} }
wchar_t *wcsdupcat2( const wchar_t *a, ... ) wchar_t *wcsdupcat2( const wchar_t *a, ... )
@ -498,10 +498,10 @@ int contains_str( const wchar_t *a, ... )
if( !a ) if( !a )
{ {
debug( 1, L"Warning: Called contains_str with null argument. This is a bug." ); debug( 0, L"%s called with null input", __func__ );
return 0; return 0;
} }
va_start( va, a ); va_start( va, a );
while( (arg=va_arg(va, wchar_t *) )!= 0 ) while( (arg=va_arg(va, wchar_t *) )!= 0 )
{ {
@ -547,6 +547,12 @@ void debug( int level, const wchar_t *msg, ... )
string_buffer_t sb; string_buffer_t sb;
string_buffer_t sb2; string_buffer_t sb2;
if( !msg )
{
debug( 0, L"%s called with null input", __func__ );
return;
}
if( level > debug_level ) if( level > debug_level )
return; return;
@ -573,6 +579,12 @@ void write_screen( const wchar_t *msg, string_buffer_t *buff )
int tok_width = 0; int tok_width = 0;
int screen_width = common_get_width(); int screen_width = common_get_width();
if( !msg || !buff )
{
debug( 0, L"%s called with null input", __func__ );
return;
}
if( screen_width ) if( screen_width )
{ {
start = pos = msg; start = pos = msg;
@ -656,8 +668,18 @@ void write_screen( const wchar_t *msg, string_buffer_t *buff )
wchar_t *escape( const wchar_t *in, wchar_t *escape( const wchar_t *in,
int escape_all ) int escape_all )
{ {
wchar_t *out = malloc( sizeof(wchar_t)*(wcslen(in)*4 + 1)); wchar_t *out;
wchar_t *pos=out; wchar_t *pos;
if( !in )
{
debug( 0, L"%s called with null input", __func__ );
exit(1);
}
out = malloc( sizeof(wchar_t)*(wcslen(in)*4 + 1));
pos = out;
if( !out ) if( !out )
die_mem(); die_mem();
@ -764,11 +786,22 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
{ {
int mode = 0; int mode = 0;
int in_pos, out_pos, len = wcslen( orig ); int in_pos, out_pos, len;
int c; int c;
int bracket_count=0; int bracket_count=0;
wchar_t prev=0; wchar_t prev=0;
wchar_t *in = wcsdup(orig); wchar_t *in;
if( !orig )
{
debug( 0, L"%s called with null input", __func__ );
exit(1);
}
len = wcslen( orig );
in = wcsdup( orig );
if( !in ) if( !in )
die_mem(); die_mem();

26
env.c
View File

@ -623,6 +623,12 @@ int env_set( const wchar_t *key,
event_t ev; event_t ev;
int is_universal = 0; int is_universal = 0;
if( !key )
{
debug( 0, L"%s called with null input", __func__ );
return ENV_INVALID;
}
if( (var_mode & ENV_USER ) && if( (var_mode & ENV_USER ) &&
hash_get( &env_read_only, key ) ) hash_get( &env_read_only, key ) )
{ {
@ -867,6 +873,12 @@ int env_remove( const wchar_t *key, int var_mode )
env_node_t *first_node; env_node_t *first_node;
int erased = 0; int erased = 0;
if( !key )
{
debug( 0, L"%s called with null input", __func__ );
return 1;
}
if( (var_mode & ENV_USER ) && if( (var_mode & ENV_USER ) &&
hash_get( &env_read_only, key ) ) hash_get( &env_read_only, key ) )
{ {
@ -925,6 +937,12 @@ wchar_t *env_get( const wchar_t *key )
env_node_t *env = top; env_node_t *env = top;
wchar_t *item; wchar_t *item;
if( !key )
{
debug( 0, L"%s called with null input", __func__ );
return 0;
}
if( wcscmp( key, L"history" ) == 0 ) if( wcscmp( key, L"history" ) == 0 )
{ {
wchar_t *current; wchar_t *current;
@ -1023,9 +1041,15 @@ int env_exist( const wchar_t *key, int mode )
env_node_t *env; env_node_t *env;
wchar_t *item=0; wchar_t *item=0;
if( !key )
{
debug( 0, L"%s called with null input", __func__ );
return 0;
}
/* /*
Read only variables all exist, and they are all global. A local Read only variables all exist, and they are all global. A local
varion can not exist. version can not exist.
*/ */
if( ! (mode & ENV_LOCAL) && ! (mode & ENV_UNIVERSAL) ) if( ! (mode & ENV_LOCAL) && ! (mode & ENV_UNIVERSAL) )
{ {

9
env.h
View File

@ -44,7 +44,12 @@
/** /**
Error code for trying to alter read-only variable Error code for trying to alter read-only variable
*/ */
#define ENV_PERM 1 enum{
ENV_PERM = 1,
ENV_INVALID
}
;
/** /**
Initialize environment variable data Initialize environment variable data
@ -71,7 +76,7 @@ void env_destroy();
The current error codes are: The current error codes are:
* ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that the user tried to change a read-only variable. * ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that the user tried to change a read-only variable.
* ENV_INVALID, the variable name or mode was invalid
*/ */
int env_set( const wchar_t *key, int env_set( const wchar_t *key,

6
exec.c
View File

@ -652,6 +652,12 @@ void exec( job_t *j )
*/ */
int exec_error=0; int exec_error=0;
if( !j )
{
debug( 0, L"%s called with null input", __func__ );
return;
}
if( no_exec ) if( no_exec )
return; return;

View File

@ -17,9 +17,9 @@
#endif #endif
/** /**
Make sure __func__ is defined to some string. This should be the Make sure __func__ is defined to some string. In C99, this should
currently compiled function, but not all compilers support this be the currently compiled function. If we aren't using C99 or
feature. later, older versions of GCC had __FUNCTION__.
*/ */
#if __STDC_VERSION__ < 199901L #if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2 # if __GNUC__ >= 2

View File

@ -711,6 +711,12 @@ wchar_t *get_filename( const wchar_t *cmd )
{ {
wchar_t *path; wchar_t *path;
if( !cmd )
{
debug( 0, L"%s called with null input", __func__ );
return 0;
}
debug( 3, L"get_filename( '%ls' )", cmd ); debug( 3, L"get_filename( '%ls' )", cmd );
if(wcschr( cmd, L'/' ) != 0 ) if(wcschr( cmd, L'/' ) != 0 )
@ -964,6 +970,12 @@ int eval_args( const wchar_t *line, array_list_t *args )
int previous_pos=current_tokenizer_pos; int previous_pos=current_tokenizer_pos;
int do_loop=1; int do_loop=1;
if( !line || !args )
{
debug( 0, L"%s called with null input", __func__ );
return 1;
}
proc_push_interactive(0); proc_push_interactive(0);
current_tokenizer = &tok; current_tokenizer = &tok;
current_tokenizer_pos = 0; current_tokenizer_pos = 0;
@ -1035,9 +1047,22 @@ int eval_args( const wchar_t *line, array_list_t *args )
void parser_stack_trace( block_t *b, string_buffer_t *buff) void parser_stack_trace( block_t *b, string_buffer_t *buff)
{ {
/*
Validate input
*/
if( !buff )
{
debug( 0, L"%s called with null input", __func__ );
return;
}
/*
Check if we should end the recursion
*/
if( !b ) if( !b )
return; return;
if( b->type==EVENT ) if( b->type==EVENT )
{ {
sb_printf( buff, _(L"in event handler: %ls\n"), event_get_desc( b->param1.event )); sb_printf( buff, _(L"in event handler: %ls\n"), event_get_desc( b->param1.event ));
@ -2592,9 +2617,17 @@ static int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const
int err=0; int err=0;
const wchar_t *paran_begin, *paran_end; const wchar_t *paran_begin, *paran_end;
wchar_t *arg_cpy = wcsdup( arg ); wchar_t *arg_cpy;
int do_loop = 1; int do_loop = 1;
if( !arg )
{
debug( 0, L"%s called with null input", __func__ );
return 1;
}
arg_cpy = wcsdup( arg );
while( do_loop ) while( do_loop )
{ {
switch( parse_util_locate_cmdsubst(arg_cpy, switch( parse_util_locate_cmdsubst(arg_cpy,
@ -2747,6 +2780,12 @@ int parser_test_args(const wchar_t * buff,
int do_loop = 1; int do_loop = 1;
int err = 0; int err = 0;
if( !buff )
{
debug( 0, L"%s called with null input", __func__ );
return 1;
}
current_tokenizer = &tok; current_tokenizer = &tok;
for( tok_init( &tok, buff, 0 ); for( tok_init( &tok, buff, 0 );
@ -2835,10 +2874,17 @@ int parser_test( const wchar_t * buff,
Set to one if an additional process specification is needed Set to one if an additional process specification is needed
*/ */
int needs_cmd=0; int needs_cmd=0;
void *context = halloc( 0, 0 ); void *context;
int arg_count=0; int arg_count=0;
wchar_t *cmd=0; wchar_t *cmd=0;
if( !buff )
{
debug( 0, L"%s called with null input", __func__ );
return 1;
}
context = halloc( 0, 0 );
current_tokenizer = &tok; current_tokenizer = &tok;
for( tok_init( &tok, buff, 0 ); for( tok_init( &tok, buff, 0 );