diff --git a/builtin.c b/builtin.c index 3571493f9..fdf464cc1 100644 --- a/builtin.c +++ b/builtin.c @@ -2946,6 +2946,12 @@ void builtin_destroy() 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 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 (*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] ); 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 ) { + if( !list ) + { + debug( 0, L"%s called with null input", __func__ ); + return; + } + hash_get_keys( &builtin, list ); } 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 ) { diff --git a/builtin_set.c b/builtin_set.c index bb52df1f2..6e93214f6 100644 --- a/builtin_set.c +++ b/builtin_set.c @@ -159,6 +159,13 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope ) retcode=1; break; } + + case ENV_INVALID: + { + sb_printf( sb_err, _(L"%ls: Unknown error"), L"set" ); + retcode=1; + break; + } } sb_destroy( &sb ); diff --git a/common.c b/common.c index f622deb11..f9bfdca84 100644 --- a/common.c +++ b/common.c @@ -336,7 +336,7 @@ char **wcsv2strv( const wchar_t **in ) 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, ... ) @@ -498,10 +498,10 @@ int contains_str( const wchar_t *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; } - + va_start( va, a ); 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 sb2; + if( !msg ) + { + debug( 0, L"%s called with null input", __func__ ); + return; + } + if( level > debug_level ) return; @@ -573,6 +579,12 @@ void write_screen( const wchar_t *msg, string_buffer_t *buff ) int tok_width = 0; int screen_width = common_get_width(); + if( !msg || !buff ) + { + debug( 0, L"%s called with null input", __func__ ); + return; + } + if( screen_width ) { 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, int escape_all ) { - wchar_t *out = malloc( sizeof(wchar_t)*(wcslen(in)*4 + 1)); - wchar_t *pos=out; + wchar_t *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 ) die_mem(); @@ -764,11 +786,22 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special ) { int mode = 0; - int in_pos, out_pos, len = wcslen( orig ); + int in_pos, out_pos, len; int c; int bracket_count=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 ) die_mem(); diff --git a/env.c b/env.c index d501576c1..ab31b56a6 100644 --- a/env.c +++ b/env.c @@ -623,6 +623,12 @@ int env_set( const wchar_t *key, event_t ev; int is_universal = 0; + if( !key ) + { + debug( 0, L"%s called with null input", __func__ ); + return ENV_INVALID; + } + if( (var_mode & ENV_USER ) && 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; int erased = 0; + if( !key ) + { + debug( 0, L"%s called with null input", __func__ ); + return 1; + } + if( (var_mode & ENV_USER ) && hash_get( &env_read_only, key ) ) { @@ -925,6 +937,12 @@ wchar_t *env_get( const wchar_t *key ) env_node_t *env = top; wchar_t *item; + if( !key ) + { + debug( 0, L"%s called with null input", __func__ ); + return 0; + } + if( wcscmp( key, L"history" ) == 0 ) { wchar_t *current; @@ -1023,9 +1041,15 @@ int env_exist( const wchar_t *key, int mode ) env_node_t *env; 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 - varion can not exist. + version can not exist. */ if( ! (mode & ENV_LOCAL) && ! (mode & ENV_UNIVERSAL) ) { diff --git a/env.h b/env.h index 27a7bbfba..405b9c1ed 100644 --- a/env.h +++ b/env.h @@ -44,7 +44,12 @@ /** Error code for trying to alter read-only variable */ -#define ENV_PERM 1 +enum{ + ENV_PERM = 1, + ENV_INVALID +} +; + /** Initialize environment variable data @@ -71,7 +76,7 @@ void env_destroy(); 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_INVALID, the variable name or mode was invalid */ int env_set( const wchar_t *key, diff --git a/exec.c b/exec.c index 7d6b64308..66f7e1d57 100644 --- a/exec.c +++ b/exec.c @@ -652,6 +652,12 @@ void exec( job_t *j ) */ int exec_error=0; + if( !j ) + { + debug( 0, L"%s called with null input", __func__ ); + return; + } + if( no_exec ) return; diff --git a/fallback.h b/fallback.h index 42bc3b377..d54477e58 100644 --- a/fallback.h +++ b/fallback.h @@ -17,9 +17,9 @@ #endif /** - Make sure __func__ is defined to some string. This should be the - currently compiled function, but not all compilers support this - feature. + Make sure __func__ is defined to some string. In C99, this should + be the currently compiled function. If we aren't using C99 or + later, older versions of GCC had __FUNCTION__. */ #if __STDC_VERSION__ < 199901L # if __GNUC__ >= 2 diff --git a/parser.c b/parser.c index 349a09baf..275150c16 100644 --- a/parser.c +++ b/parser.c @@ -711,6 +711,12 @@ wchar_t *get_filename( const wchar_t *cmd ) { wchar_t *path; + if( !cmd ) + { + debug( 0, L"%s called with null input", __func__ ); + return 0; + } + debug( 3, L"get_filename( '%ls' )", cmd ); 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 do_loop=1; + if( !line || !args ) + { + debug( 0, L"%s called with null input", __func__ ); + return 1; + } + proc_push_interactive(0); current_tokenizer = &tok; 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) { + + /* + Validate input + */ + if( !buff ) + { + debug( 0, L"%s called with null input", __func__ ); + return; + } + + /* + Check if we should end the recursion + */ if( !b ) return; - + if( b->type==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; const wchar_t *paran_begin, *paran_end; - wchar_t *arg_cpy = wcsdup( arg ); + wchar_t *arg_cpy; int do_loop = 1; + if( !arg ) + { + debug( 0, L"%s called with null input", __func__ ); + return 1; + } + + arg_cpy = wcsdup( arg ); + while( do_loop ) { switch( parse_util_locate_cmdsubst(arg_cpy, @@ -2747,6 +2780,12 @@ int parser_test_args(const wchar_t * buff, int do_loop = 1; int err = 0; + if( !buff ) + { + debug( 0, L"%s called with null input", __func__ ); + return 1; + } + current_tokenizer = &tok; 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 */ int needs_cmd=0; - void *context = halloc( 0, 0 ); + void *context; int arg_count=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; for( tok_init( &tok, buff, 0 );