Add some input validation code to various functions

darcs-hash:20060222154152-ac50b-608032284165f099beecd1cd4f7c6bb2b45df432.gz
This commit is contained in:
axel 2006-02-23 01:41:52 +10:00
parent 3afead1827
commit ca04fc745d
11 changed files with 225 additions and 84 deletions

View File

@ -212,8 +212,13 @@ wchar_t *str2wcs( const char *in )
size_t len = strlen(in);
out = malloc( sizeof(wchar_t)*(len+1) );
if( !out )
{
die_mem();
}
return str2wcs_internal( in, out );
}
wchar_t *str2wcs_internal( const char *in, wchar_t *out )
@ -226,11 +231,6 @@ wchar_t *str2wcs_internal( const char *in, wchar_t *out )
memset( &state, 0, sizeof(state) );
if( !out )
{
die_mem();
}
while( in[in_pos] )
{
res = mbrtowc( &out[out_pos], &in[in_pos], len-in_pos, &state );

View File

@ -481,8 +481,10 @@ void complete_remove( const wchar_t *cmd,
{
wchar_t *pos2 = pos+1;
while( *pos2 == L':' )
{
pos2++;
}
memmove( pos,
pos2,
sizeof(wchar_t)*wcslen(pos2) );
@ -500,7 +502,9 @@ void complete_remove( const wchar_t *cmd,
free( o );
}
else
{
oprev = o;
}
}
}
@ -523,7 +527,9 @@ void complete_remove( const wchar_t *cmd,
}
if( e )
{
eprev = e;
}
}
}
@ -541,8 +547,14 @@ static void parse_cmd_string( const wchar_t *str,
/* Get the path of the command */
path = get_filename( str );
if( path == 0 )
{
/**
Use the empty string as the 'path' for commands that can
not be found.
*/
path = wcsdup(L"");
}
/* Make sure the path is not included in the command */
cmd = wcsrchr( str, L'/' );
if( cmd != 0 )
@ -611,11 +623,11 @@ int complete_is_valid_option( const wchar_t *str,
return 0;
}
if( !(short_validated = malloc( wcslen( opt ) )))
{
die_mem();
}
memset( short_validated, 0, wcslen( opt ) );
hash_init( &gnu_match_hash,
@ -649,8 +661,10 @@ int complete_is_valid_option( const wchar_t *str,
const wchar_t *a;
if( !wildcard_match( match, i->cmd ) )
{
continue;
}
found_match = 1;
if( !i->authorative )
@ -666,15 +680,19 @@ int complete_is_valid_option( const wchar_t *str,
for( o = i->first_option; o; o=o->next )
{
if( o->old_mode )
{
continue;
}
if( wcsncmp( &opt[2], o->long_opt, gnu_opt_len )==0)
{
hash_put( &gnu_match_hash, o->long_opt, L"" );
if( (wcsncmp( &opt[2],
o->long_opt,
wcslen( o->long_opt) )==0) )
{
is_gnu_exact=1;
}
}
}
}
@ -926,24 +944,30 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
switch( errno )
{
case ENOENT:
{
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_ROTTEN_SYMLINK_DESC );
break;
}
case EACCES:
{
break;
}
default:
{
if( errno == ELOOP )
{
sb_printf( get_desc_buff, L"%lc%ls", COMPLETE_SEP, COMPLETE_LOOP_SYMLINK_DESC );
}
/*
Some kind of broken symlink. We ignore it
here, and it will get a 'file' description,
or one based on suffix.
Some kind of unknown broken symlink. We
ignore it here, and it will get a 'file'
description, or one based on suffix.
*/
break;
}
}
}
@ -1013,19 +1037,14 @@ static void copy_strings_with_prefix( array_list_t *comp_out,
if(!tmp)
return;
if( tmp[0] == L'~' )
{
tmp=expand_tilde(wc);
}
wc = parse_util_unescape_wildcards( tmp );
free(tmp);
for( i=0; i<al_get_count( possible_comp ); i++ )
{
wchar_t *next_str = (wchar_t *)al_get( possible_comp, i );
wildcard_complete( next_str, wc, desc, desc_func, comp_out );
if( next_str )
wildcard_complete( next_str, wc, desc, desc_func, comp_out );
}
free( wc );
@ -1358,10 +1377,26 @@ static void complete_from_args( const wchar_t *str,
for( i=0; i< al_get_count( &possible_comp ); i++ )
{
wchar_t *next = (wchar_t *)al_get( &possible_comp, i );
al_set( &possible_comp , i, unescape( next, 0 ) );
free( next );
wchar_t *next_unescaped;
if( next )
{
next_unescaped = unescape( next, 0 );
if( next_unescaped )
{
al_set( &possible_comp , i, next_unescaped );
}
else
{
debug( 2, L"Could not expand string %ls on line %d of file %s", next, __LINE__, __FILE__ );
}
free( next );
}
else
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
}
}
copy_strings_with_prefix( comp_out, str, desc, 0, &possible_comp );
al_foreach( &possible_comp, (void (*)(const void *))&free );
@ -1674,11 +1709,11 @@ static void complete_param_expand( wchar_t *str,
comp_str = str;
}
debug( 2,
debug( 3,
L"expand_string( \"%ls\", comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | %ls );",
comp_str,
do_file?L"0":L"EXPAND_SKIP_WILDCARDS" );
expand_string( 0,
wcsdup(comp_str),
comp_out,
@ -1753,10 +1788,8 @@ static int try_complete_variable( const wchar_t *cmd,
{
return 0;
}
}
return 0;
}
/**

View File

@ -214,7 +214,7 @@ void env_universal_init( wchar_t * p,
void (*sf)(),
void (*cb)( int type, const wchar_t *name, const wchar_t *val ))
{
debug( 2, L"env_universal_init()" );
debug( 3, L"env_universal_init()" );
path=p;
user=u;
start_fishd=sf;
@ -233,7 +233,7 @@ void env_universal_init( wchar_t * p,
{
env_universal_barrier();
}
debug( 2, L"end env_universal_init()" );
debug( 3, L"end env_universal_init()" );
}
void env_universal_destroy()

View File

@ -105,7 +105,7 @@ static int get_names_show_unexported;
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
{
debug( 2, L"Init env_universal_common" );
debug( 3, L"Init env_universal_common" );
callback = cb;
hash_init( &env_universal_var, &hash_wcs_func, &hash_wcs_cmp );
}
@ -229,7 +229,7 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
static void parse_message( wchar_t *msg,
connection_t *src )
{
debug( 2, L"parse_message( %ls );", msg );
debug( 3, L"parse_message( %ls );", msg );
if( msg[0] == L'#' )
return;

17
exec.c
View File

@ -1260,10 +1260,16 @@ int exec_subshell( const wchar_t *cmd,
{
wchar_t *el = str2wcs( begin );
if( el )
{
al_push( l, el );
}
else
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
}
}
io_buffer_destroy( io_buffer );
return status;
case '\n':
@ -1271,7 +1277,14 @@ int exec_subshell( const wchar_t *cmd,
wchar_t *el;
*end=0;
el = str2wcs( begin );
al_push( l, el );
if( el )
{
al_push( l, el );
}
else
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
}
begin = end+1;
break;
}

View File

@ -1189,6 +1189,18 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
int i, j;
const wchar_t *item_begin;
if( !in )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
return 0;
}
if( !out )
{
debug( 2, L"Got null pointer on line %d of file %s", __LINE__, __FILE__ );
return 0;
}
switch( parse_util_locate_cmdsubst(in,
&paran_begin,
&paran_end,
@ -1205,7 +1217,6 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
case 1:
break;
}
len1 = (paran_begin-in);
@ -1254,10 +1265,10 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
sb_append_substring( &whole_item, sub_item2, item_len );
sb_append_char( &whole_item, INTERNAL_SEPARATOR );
sb_append( &whole_item, tail_item );
al_push( out, whole_item.buff );
al_push( out, whole_item.buff );
}
free( sub_item2 );
}
free(in);
@ -1438,23 +1449,18 @@ int expand_string( void *context,
if( EXPAND_SKIP_SUBSHELL & flags )
{
wchar_t *pos = str;
while( 1 )
const wchar_t *begin, *end;
if( parse_util_locate_cmdsubst( str,
&begin,
&end,
1 ) != 0 )
{
pos = wcschr( pos, L'(' );
if( pos == 0 )
break;
if( (pos == str) || ( *(pos-1) != L'\\' ) )
{
error( SUBSHELL_ERROR, -1, L"Subshells not allowed" );
free( str );
al_destroy( &list1 );
al_destroy( &list2 );
return EXPAND_ERROR;
}
pos++;
error( SUBSHELL_ERROR, -1, L"Subshells not allowed" );
free( str );
al_destroy( &list1 );
al_destroy( &list2 );
return EXPAND_ERROR;
}
al_push( &list1, str );
}
@ -1483,7 +1489,10 @@ int expand_string( void *context,
free( (void *)al_get( in, i ) );
if( !next )
continue;
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
continue;
}
if( EXPAND_SKIP_VARIABLES & flags )
{
@ -1492,7 +1501,6 @@ int expand_string( void *context,
if( *tmp == VARIABLE_EXPAND )
*tmp = L'$';
al_push( out, next );
}
else
{
@ -1513,6 +1521,13 @@ int expand_string( void *context,
for( i=0; i<al_get_count( in ); i++ )
{
wchar_t *next = (wchar_t *)al_get( in, i );
if( !next )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
continue;
}
if( !expand_brackets( next, flags, out ))
{
al_destroy( in );
@ -1528,6 +1543,13 @@ int expand_string( void *context,
for( i=0; i<al_get_count( in ); i++ )
{
wchar_t *next = (wchar_t *)al_get( in, i );
if( !next )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
continue;
}
if( !(next=expand_tilde_internal( next ) ) )
{
al_destroy( in );
@ -1572,6 +1594,12 @@ int expand_string( void *context,
wchar_t *next = (wchar_t *)al_get( in, i );
int wc_res;
if( !next )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
continue;
}
remove_internal_separator( next, EXPAND_SKIP_WILDCARDS & flags );
if( ((flags & ACCEPT_INCOMPLETE) && (!(flags & EXPAND_SKIP_WILDCARDS))) ||
@ -1590,27 +1618,46 @@ int expand_string( void *context,
switch( wc_res )
{
case 0:
{
if( !(flags & ACCEPT_INCOMPLETE) )
{
if( res == EXPAND_OK )
res = EXPAND_WILDCARD_NO_MATCH;
break;
}
}
case 1:
{
int j;
res = EXPAND_WILDCARD_MATCH;
sort_list( out );
al_push_all( end_out, out );
for( j=0; j<al_get_count( out ); j++ )
{
wchar_t *next = (wchar_t *)al_get( out, j );
if( !next )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
continue;
}
al_push( end_out, next );
}
al_truncate( out, 0 );
break;
}
}
}
else
{
if( flags & ACCEPT_INCOMPLETE)
{
free( next );
}
else
{
al_push( end_out, next );
}
}
}
al_destroy( in );

26
main.c
View File

@ -122,6 +122,10 @@ int main( int argc, char **argv )
"command", required_argument, 0, 'c'
}
,
{
"debug-level", required_argument, 0, 'd'
}
,
{
"interactive", no_argument, 0, 'i'
}
@ -152,14 +156,14 @@ int main( int argc, char **argv )
int opt = getopt_long( argc,
argv,
"hilvc:p:",
"hilvc:p:d:",
long_options,
&opt_index );
#else
int opt = getopt( argc,
argv,
"hilvc:p:" );
"hilvc:p:d:" );
#endif
if( opt == -1 )
break;
@ -174,6 +178,22 @@ int main( int argc, char **argv )
is_interactive_session = 0;
break;
case 'd':
{
char *end;
int tmp = strtol(optarg, &end, 10);
if( tmp >= 0 && tmp <=10 && !*end )
{
debug_level=tmp;
}
else
{
debug( 0, _(L"Invalid value '%s' for debug level switch"), optarg );
exit(1);
}
break;
}
case 'h':
cmd = "help";
break;
@ -233,7 +253,7 @@ int main( int argc, char **argv )
wchar_t *cmd_wcs = str2wcs( cmd );
res = eval( cmd_wcs, 0, TOP );
free(cmd_wcs);
reader_exit(0);
reader_exit(0);
}
else
{

View File

@ -155,16 +155,12 @@ int parse_util_locate_cmdsubst( const wchar_t *in,
return 0;
}
*begin = paran_begin;
*end = paran_count?in+wcslen(in):paran_end;
if( begin )
*begin = paran_begin;
if( end )
*end = paran_count?in+wcslen(in):paran_end;
/* assert( *begin >= in );
assert( *begin < (in+wcslen(in) ) );
assert( *end >= *begin );
assert( *end < (in+wcslen(in) ) );
*/
return 1;
}

View File

@ -708,7 +708,7 @@ wchar_t *get_filename( const wchar_t *cmd )
{
wchar_t *path;
debug( 2, L"get_filename( '%ls' )", cmd );
debug( 3, L"get_filename( '%ls' )", cmd );
if(wcschr( cmd, L'/' ) != 0 )
{
@ -948,7 +948,14 @@ int eval_args( const wchar_t *line, array_list_t *args )
{
case TOK_STRING:
{
if( expand_string( 0, wcsdup(tok_last( &tok )), args, 0 ) == EXPAND_ERROR )
wchar_t *tmp = wcsdup(tok_last( &tok ));
if( !tmp )
{
die_mem();
}
if( expand_string( 0, tmp, args, 0 ) == EXPAND_ERROR )
{
err_pos=tok_get_pos( &tok );
do_loop=0;

View File

@ -567,11 +567,12 @@ static void remove_duplicates( array_list_t *l )
prev = (wchar_t *)al_get( l, 0 );
for( in=1, out=1; in < al_get_count( l ); in++ )
{
{
wchar_t *curr = (wchar_t *)al_get( l, in );
if( fldcmp( prev, curr )==0 )
{
free( curr );
free( curr );
}
else
{
@ -2036,7 +2037,6 @@ void reader_set_buffer( wchar_t *b, int p )
else
{
data->buff_pos=l;
// fwprintf( stderr, L"Pos %d\n", l );
}
reader_super_highlight_me_plenty( data->buff,

View File

@ -151,13 +151,32 @@ static int wildcard_complete_internal( const wchar_t *orig,
const wchar_t *(*desc_func)(const wchar_t *),
array_list_t *out )
{
if( !wc )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
return 0;
}
if( !str )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
return 0;
}
if( !orig )
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
return 0;
}
if( *wc == 0 &&
( ( *str != L'.') || (!is_first)) )
{
if( !out )
return 1;
wchar_t *new;
if( !out )
{
return 1;
}
if( wcschr( str, PROG_COMPLETE_SEP ) )
{
@ -165,7 +184,7 @@ static int wildcard_complete_internal( const wchar_t *orig,
This completion has an embedded description, du not use the generic description
*/
wchar_t *sep;
new = wcsdup( str );
sep = wcschr(new, PROG_COMPLETE_SEP );
*sep = COMPLETE_SEP;
@ -661,15 +680,19 @@ int wildcard_expand( const wchar_t *wc,
if( wc_end )
{
new_wc=wc_end+1;
/*
Accept multiple '/' as a single direcotry separator
*/
while(*new_wc==L'/')
{
new_wc++;
}
}
res |= wildcard_expand( new_wc,
new_dir,
flags,
out );
}
/*
@ -694,8 +717,10 @@ int wildcard_expand( const wchar_t *wc,
closedir( dir );
if( flags & ACCEPT_INCOMPLETE )
{
sb_destroy( &sb_desc );
}
return res;
}