mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Add validator check to make sure the second argument to 'for' is 'in'
darcs-hash:20060521221604-ac50b-5bc4ce217a08304f68b97b20e908ea1279fe26e9.gz
This commit is contained in:
parent
07e14ed7a8
commit
b746a803a9
5 changed files with 70 additions and 27 deletions
|
@ -2590,7 +2590,7 @@ static int builtin_for( wchar_t **argv )
|
||||||
else if (wcscmp( argv[2], L"in") != 0 )
|
else if (wcscmp( argv[2], L"in") != 0 )
|
||||||
{
|
{
|
||||||
sb_printf( sb_err,
|
sb_printf( sb_err,
|
||||||
_( L"%ls: Second argument must be 'in'\n" ),
|
BUILTIN_FOR_ERR_IN,
|
||||||
argv[0] );
|
argv[0] );
|
||||||
builtin_print_help( argv[0], sb_err );
|
builtin_print_help( argv[0], sb_err );
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,11 @@ enum
|
||||||
*/
|
*/
|
||||||
#define BUILTIN_ERR_VARNAME_ZERO _( L"%ls: Variable name can not be the empty string\n" )
|
#define BUILTIN_ERR_VARNAME_ZERO _( L"%ls: Variable name can not be the empty string\n" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
Error message when second argument to for isn't 'in'
|
||||||
|
*/
|
||||||
|
#define BUILTIN_FOR_ERR_IN _( L"%ls: Second argument must be 'in'\n" )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Stringbuffer used to represent standard output
|
Stringbuffer used to represent standard output
|
||||||
*/
|
*/
|
||||||
|
|
17
expand.c
17
expand.c
|
@ -96,15 +96,7 @@ parameter expansion.
|
||||||
*/
|
*/
|
||||||
#define UNCLEAN L"$*?\\\"'({})"
|
#define UNCLEAN L"$*?\\\"'({})"
|
||||||
|
|
||||||
/**
|
int expand_is_clean( const wchar_t *in )
|
||||||
Test if the specified argument is clean, i.e. it does not contain
|
|
||||||
any tokens which need to be expanded or otherwise altered. Clean
|
|
||||||
strings can be passed through expand_string and expand_one without
|
|
||||||
changing them. About 90% of all strings are clean, so skipping
|
|
||||||
expansion on them actually does save a small amount of time, since
|
|
||||||
it avoids multiple memory allocations during the expansion process.
|
|
||||||
*/
|
|
||||||
static int is_clean( const wchar_t *in )
|
|
||||||
{
|
{
|
||||||
|
|
||||||
const wchar_t * str = in;
|
const wchar_t * str = in;
|
||||||
|
@ -1372,7 +1364,6 @@ static void remove_internal_separator( const void *s, int conv )
|
||||||
*out=0;
|
*out=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The real expansion function. expand_one is just a wrapper around this one.
|
The real expansion function. expand_one is just a wrapper around this one.
|
||||||
*/
|
*/
|
||||||
|
@ -1389,9 +1380,7 @@ int expand_string( void *context,
|
||||||
int res = EXPAND_OK;
|
int res = EXPAND_OK;
|
||||||
int start_count = al_get_count( end_out );
|
int start_count = al_get_count( end_out );
|
||||||
|
|
||||||
// debug( 1, L"Expand %ls", str );
|
if( (!(flags & ACCEPT_INCOMPLETE)) && expand_is_clean( str ) )
|
||||||
|
|
||||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
|
|
||||||
{
|
{
|
||||||
halloc_register( context, str );
|
halloc_register( context, str );
|
||||||
al_push( end_out, str );
|
al_push( end_out, str );
|
||||||
|
@ -1637,7 +1626,7 @@ wchar_t *expand_one( void *context, wchar_t *string, int flags )
|
||||||
int res;
|
int res;
|
||||||
wchar_t *one;
|
wchar_t *one;
|
||||||
|
|
||||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( string ) )
|
if( (!(flags & ACCEPT_INCOMPLETE)) && expand_is_clean( string ) )
|
||||||
{
|
{
|
||||||
halloc_register( context, string );
|
halloc_register( context, string );
|
||||||
return string;
|
return string;
|
||||||
|
|
11
expand.h
11
expand.h
|
@ -188,4 +188,15 @@ wchar_t *expand_tilde(wchar_t *in);
|
||||||
*/
|
*/
|
||||||
void expand_variable_array( const wchar_t *val, array_list_t *out );
|
void expand_variable_array( const wchar_t *val, array_list_t *out );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Test if the specified argument is clean, i.e. it does not contain
|
||||||
|
any tokens which need to be expanded or otherwise altered. Clean
|
||||||
|
strings can be passed through expand_string and expand_one without
|
||||||
|
changing them. About two thirds of all strings are clean, so
|
||||||
|
skipping expansion on them actually does save a small amount of
|
||||||
|
time, since it avoids multiple memory allocations during the
|
||||||
|
expansion process.
|
||||||
|
*/
|
||||||
|
int expand_is_clean( const wchar_t *in );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
52
parser.c
52
parser.c
|
@ -2790,6 +2790,8 @@ int parser_test( const wchar_t * buff,
|
||||||
*/
|
*/
|
||||||
int needs_cmd=0;
|
int needs_cmd=0;
|
||||||
void *context = halloc( 0, 0 );
|
void *context = halloc( 0, 0 );
|
||||||
|
int arg_count=0;
|
||||||
|
wchar_t *cmd;
|
||||||
|
|
||||||
current_tokenizer = &tok;
|
current_tokenizer = &tok;
|
||||||
|
|
||||||
|
@ -2808,10 +2810,11 @@ int parser_test( const wchar_t * buff,
|
||||||
{
|
{
|
||||||
int mark = tok_get_pos( &tok );
|
int mark = tok_get_pos( &tok );
|
||||||
had_cmd = 1;
|
had_cmd = 1;
|
||||||
|
arg_count=0;
|
||||||
|
|
||||||
if( !expand_one( context,
|
if( !(cmd = expand_one( context,
|
||||||
wcsdup( tok_last( &tok ) ),
|
wcsdup( tok_last( &tok ) ),
|
||||||
EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES ) )
|
EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES ) ) )
|
||||||
{
|
{
|
||||||
err=1;
|
err=1;
|
||||||
if( babble )
|
if( babble )
|
||||||
|
@ -2827,7 +2830,7 @@ int parser_test( const wchar_t * buff,
|
||||||
|
|
||||||
if( needs_cmd )
|
if( needs_cmd )
|
||||||
{
|
{
|
||||||
if( contains_str( tok_last(&tok),
|
if( contains_str( cmd,
|
||||||
L"end",
|
L"end",
|
||||||
0 ) )
|
0 ) )
|
||||||
{
|
{
|
||||||
|
@ -2848,7 +2851,7 @@ int parser_test( const wchar_t * buff,
|
||||||
/*
|
/*
|
||||||
Decrement block count on end command
|
Decrement block count on end command
|
||||||
*/
|
*/
|
||||||
if( wcscmp(tok_last(&tok), L"end")==0)
|
if( wcscmp(cmd, L"end")==0)
|
||||||
{
|
{
|
||||||
tok_next( &tok );
|
tok_next( &tok );
|
||||||
count--;
|
count--;
|
||||||
|
@ -2858,7 +2861,7 @@ int parser_test( const wchar_t * buff,
|
||||||
/*
|
/*
|
||||||
Handle block commands
|
Handle block commands
|
||||||
*/
|
*/
|
||||||
if( parser_is_block( tok_last(&tok) ) )
|
if( parser_is_block( cmd ) )
|
||||||
{
|
{
|
||||||
if( count >= BLOCK_MAX_COUNT )
|
if( count >= BLOCK_MAX_COUNT )
|
||||||
{
|
{
|
||||||
|
@ -3041,7 +3044,42 @@ int parser_test( const wchar_t * buff,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err = parser_test_argument( tok_last( &tok ), babble );
|
err |= parser_test_argument( tok_last( &tok ), babble );
|
||||||
|
|
||||||
|
if( arg_count >= 0 && expand_is_clean( tok_last( &tok ) ) )
|
||||||
|
{
|
||||||
|
arg_count++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arg_count = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Try to make sure the second argument to 'for' is 'in'
|
||||||
|
*/
|
||||||
|
if( wcscmp( cmd, L"for" ) == 0 )
|
||||||
|
{
|
||||||
|
if( arg_count == 2 )
|
||||||
|
{
|
||||||
|
if( wcscmp( tok_last( &tok ), L"in" ) != 0 )
|
||||||
|
{
|
||||||
|
err = 1;
|
||||||
|
|
||||||
|
if( babble )
|
||||||
|
{
|
||||||
|
error( SYNTAX_ERROR,
|
||||||
|
tok_get_pos( &tok ),
|
||||||
|
BUILTIN_FOR_ERR_IN,
|
||||||
|
L"for" );
|
||||||
|
|
||||||
|
print_errors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue