hush: fix bkslash+newline handling and number validation in ${NN} and ${#NN}
Entering "${1a}" into interactive shell was making it exit. function old new delta parse_dollar 824 958 +134 i_getch_and_eat_bkslash_nl - 44 +44 parse_expr 917 938 +21 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/0 up/down: 199/0) Total: 199 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
fd217c1cbf
commit
97c3b5e3ff
4
shell/ash_test/ash-parsing/bkslash_newline4.right
Normal file
4
shell/ash_test/ash-parsing/bkslash_newline4.right
Normal file
@ -0,0 +1,4 @@
|
||||
1:1
|
||||
22:22
|
||||
3:3
|
||||
Ok:0
|
14
shell/ash_test/ash-parsing/bkslash_newline4.tests
Executable file
14
shell/ash_test/ash-parsing/bkslash_newline4.tests
Executable file
@ -0,0 +1,14 @@
|
||||
set -- 1 22 333
|
||||
echo 1:$\
|
||||
1
|
||||
echo 22:$\
|
||||
{\
|
||||
2\
|
||||
}
|
||||
echo 3:$\
|
||||
{\
|
||||
#\
|
||||
3\
|
||||
}
|
||||
echo Ok:$\
|
||||
?
|
28
shell/hush.c
28
shell/hush.c
@ -4998,6 +4998,32 @@ static int parse_dollar(o_string *as_string,
|
||||
* which check invalid constructs like ${%}.
|
||||
* Oh well... let's check that the var name part is fine... */
|
||||
|
||||
if (isdigit(len_single_ch)
|
||||
|| (len_single_ch == '#' && isdigit(i_peek_and_eat_bkslash_nl(input)))
|
||||
) {
|
||||
/* Execution engine uses plain xatoi_positive()
|
||||
* to interpret ${NNN} and {#NNN},
|
||||
* check syntax here in the parser.
|
||||
* (bash does not support expressions in ${#NN},
|
||||
* e.g. ${#$var} and {#1:+WORD} are not supported).
|
||||
*/
|
||||
unsigned cnt = 9; /* max 9 digits for ${NN} and 8 for {#NN} */
|
||||
while (1) {
|
||||
o_addchr(dest, ch);
|
||||
debug_printf_parse(": '%c'\n", ch);
|
||||
ch = i_getch_and_eat_bkslash_nl(input);
|
||||
nommu_addchr(as_string, ch);
|
||||
if (ch == '}')
|
||||
break;
|
||||
if (--cnt == 0)
|
||||
goto bad_dollar_syntax;
|
||||
if (len_single_ch != '#' && strchr(VAR_SUBST_OPS, ch))
|
||||
/* ${NN<op>...} is valid */
|
||||
goto eat_until_closing;
|
||||
if (!isdigit(ch))
|
||||
goto bad_dollar_syntax;
|
||||
}
|
||||
} else
|
||||
while (1) {
|
||||
unsigned pos;
|
||||
|
||||
@ -5008,7 +5034,6 @@ static int parse_dollar(o_string *as_string,
|
||||
nommu_addchr(as_string, ch);
|
||||
if (ch == '}')
|
||||
break;
|
||||
|
||||
if (!isalnum(ch) && ch != '_') {
|
||||
unsigned end_ch;
|
||||
unsigned char last_ch;
|
||||
@ -5027,6 +5052,7 @@ static int parse_dollar(o_string *as_string,
|
||||
* special var name, e.g. ${#!}.
|
||||
*/
|
||||
}
|
||||
eat_until_closing:
|
||||
/* Eat everything until closing '}' (or ':') */
|
||||
end_ch = '}';
|
||||
if (BASH_SUBSTR
|
||||
|
4
shell/hush_test/hush-parsing/bkslash_newline4.right
Normal file
4
shell/hush_test/hush-parsing/bkslash_newline4.right
Normal file
@ -0,0 +1,4 @@
|
||||
1:1
|
||||
22:22
|
||||
3:3
|
||||
Ok:0
|
14
shell/hush_test/hush-parsing/bkslash_newline4.tests
Executable file
14
shell/hush_test/hush-parsing/bkslash_newline4.tests
Executable file
@ -0,0 +1,14 @@
|
||||
set -- 1 22 333
|
||||
echo 1:$\
|
||||
1
|
||||
echo 22:$\
|
||||
{\
|
||||
2\
|
||||
}
|
||||
echo 3:$\
|
||||
{\
|
||||
#\
|
||||
3\
|
||||
}
|
||||
echo Ok:$\
|
||||
?
|
@ -1,2 +1,2 @@
|
||||
hush: invalid number '1q'
|
||||
hush: syntax error: unterminated ${name}
|
||||
hush: syntax error: unterminated ${name}
|
||||
|
Loading…
Reference in New Issue
Block a user