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 ${%}.
|
* which check invalid constructs like ${%}.
|
||||||
* Oh well... let's check that the var name part is fine... */
|
* 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) {
|
while (1) {
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
|
||||||
@ -5008,7 +5034,6 @@ static int parse_dollar(o_string *as_string,
|
|||||||
nommu_addchr(as_string, ch);
|
nommu_addchr(as_string, ch);
|
||||||
if (ch == '}')
|
if (ch == '}')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!isalnum(ch) && ch != '_') {
|
if (!isalnum(ch) && ch != '_') {
|
||||||
unsigned end_ch;
|
unsigned end_ch;
|
||||||
unsigned char last_ch;
|
unsigned char last_ch;
|
||||||
@ -5027,6 +5052,7 @@ static int parse_dollar(o_string *as_string,
|
|||||||
* special var name, e.g. ${#!}.
|
* special var name, e.g. ${#!}.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
eat_until_closing:
|
||||||
/* Eat everything until closing '}' (or ':') */
|
/* Eat everything until closing '}' (or ':') */
|
||||||
end_ch = '}';
|
end_ch = '}';
|
||||||
if (BASH_SUBSTR
|
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}
|
hush: syntax error: unterminated ${name}
|
||||||
|
Loading…
Reference in New Issue
Block a user