aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-19 15:28:10 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-19 15:45:45 +0200
commit97c3b5e3ff252b3399d10835d5c906886a7499f4 (patch)
tree91b0292f8621f48f3a35b5854e99b0998f2e4895
parentfd217c1cbf7a702ad632bb21f7757433de1755b7 (diff)
downloadbusybox-w32-97c3b5e3ff252b3399d10835d5c906886a7499f4.tar.gz
busybox-w32-97c3b5e3ff252b3399d10835d5c906886a7499f4.tar.bz2
busybox-w32-97c3b5e3ff252b3399d10835d5c906886a7499f4.zip
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>
-rw-r--r--shell/ash_test/ash-parsing/bkslash_newline4.right4
-rwxr-xr-xshell/ash_test/ash-parsing/bkslash_newline4.tests14
-rw-r--r--shell/hush.c28
-rw-r--r--shell/hush_test/hush-parsing/bkslash_newline4.right4
-rwxr-xr-xshell/hush_test/hush-parsing/bkslash_newline4.tests14
-rw-r--r--shell/hush_test/hush-vars/var6.right2
6 files changed, 64 insertions, 2 deletions
diff --git a/shell/ash_test/ash-parsing/bkslash_newline4.right b/shell/ash_test/ash-parsing/bkslash_newline4.right
new file mode 100644
index 000000000..2110716d1
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline4.right
@@ -0,0 +1,4 @@
11:1
222:22
33:3
4Ok:0
diff --git a/shell/ash_test/ash-parsing/bkslash_newline4.tests b/shell/ash_test/ash-parsing/bkslash_newline4.tests
new file mode 100755
index 000000000..c8f5037c4
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline4.tests
@@ -0,0 +1,14 @@
1set -- 1 22 333
2echo 1:$\
31
4echo 22:$\
5{\
62\
7}
8echo 3:$\
9{\
10#\
113\
12}
13echo Ok:$\
14?
diff --git a/shell/hush.c b/shell/hush.c
index e8d24d40b..1aa0a400d 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4998,6 +4998,32 @@ static int parse_dollar(o_string *as_string,
4998 * which check invalid constructs like ${%}. 4998 * which check invalid constructs like ${%}.
4999 * Oh well... let's check that the var name part is fine... */ 4999 * Oh well... let's check that the var name part is fine... */
5000 5000
5001 if (isdigit(len_single_ch)
5002 || (len_single_ch == '#' && isdigit(i_peek_and_eat_bkslash_nl(input)))
5003 ) {
5004 /* Execution engine uses plain xatoi_positive()
5005 * to interpret ${NNN} and {#NNN},
5006 * check syntax here in the parser.
5007 * (bash does not support expressions in ${#NN},
5008 * e.g. ${#$var} and {#1:+WORD} are not supported).
5009 */
5010 unsigned cnt = 9; /* max 9 digits for ${NN} and 8 for {#NN} */
5011 while (1) {
5012 o_addchr(dest, ch);
5013 debug_printf_parse(": '%c'\n", ch);
5014 ch = i_getch_and_eat_bkslash_nl(input);
5015 nommu_addchr(as_string, ch);
5016 if (ch == '}')
5017 break;
5018 if (--cnt == 0)
5019 goto bad_dollar_syntax;
5020 if (len_single_ch != '#' && strchr(VAR_SUBST_OPS, ch))
5021 /* ${NN<op>...} is valid */
5022 goto eat_until_closing;
5023 if (!isdigit(ch))
5024 goto bad_dollar_syntax;
5025 }
5026 } else
5001 while (1) { 5027 while (1) {
5002 unsigned pos; 5028 unsigned pos;
5003 5029
@@ -5008,7 +5034,6 @@ static int parse_dollar(o_string *as_string,
5008 nommu_addchr(as_string, ch); 5034 nommu_addchr(as_string, ch);
5009 if (ch == '}') 5035 if (ch == '}')
5010 break; 5036 break;
5011
5012 if (!isalnum(ch) && ch != '_') { 5037 if (!isalnum(ch) && ch != '_') {
5013 unsigned end_ch; 5038 unsigned end_ch;
5014 unsigned char last_ch; 5039 unsigned char last_ch;
@@ -5027,6 +5052,7 @@ static int parse_dollar(o_string *as_string,
5027 * special var name, e.g. ${#!}. 5052 * special var name, e.g. ${#!}.
5028 */ 5053 */
5029 } 5054 }
5055 eat_until_closing:
5030 /* Eat everything until closing '}' (or ':') */ 5056 /* Eat everything until closing '}' (or ':') */
5031 end_ch = '}'; 5057 end_ch = '}';
5032 if (BASH_SUBSTR 5058 if (BASH_SUBSTR
diff --git a/shell/hush_test/hush-parsing/bkslash_newline4.right b/shell/hush_test/hush-parsing/bkslash_newline4.right
new file mode 100644
index 000000000..2110716d1
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline4.right
@@ -0,0 +1,4 @@
11:1
222:22
33:3
4Ok:0
diff --git a/shell/hush_test/hush-parsing/bkslash_newline4.tests b/shell/hush_test/hush-parsing/bkslash_newline4.tests
new file mode 100755
index 000000000..c8f5037c4
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline4.tests
@@ -0,0 +1,14 @@
1set -- 1 22 333
2echo 1:$\
31
4echo 22:$\
5{\
62\
7}
8echo 3:$\
9{\
10#\
113\
12}
13echo Ok:$\
14?
diff --git a/shell/hush_test/hush-vars/var6.right b/shell/hush_test/hush-vars/var6.right
index 40e67fdf5..5e28d2fab 100644
--- a/shell/hush_test/hush-vars/var6.right
+++ b/shell/hush_test/hush-vars/var6.right
@@ -1,2 +1,2 @@
1hush: invalid number '1q' 1hush: syntax error: unterminated ${name}
2hush: syntax error: unterminated ${name} 2hush: syntax error: unterminated ${name}