aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-05-22 00:26:06 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-05-22 00:26:06 +0200
commita6ad397ea92cd9c53973243728d3e52640fe63ec (patch)
tree058f34aaf8877c15a1c667efaa491267f046c7e7 /shell/hush.c
parent7436950a7516d1f4498285ccc81bf6d926f3af5e (diff)
downloadbusybox-w32-a6ad397ea92cd9c53973243728d3e52640fe63ec.tar.gz
busybox-w32-a6ad397ea92cd9c53973243728d3e52640fe63ec.tar.bz2
busybox-w32-a6ad397ea92cd9c53973243728d3e52640fe63ec.zip
hush: fix more obscure ${var%...} cases
function old new delta add_till_closing_paren 313 359 +46 builtin_exit 48 47 -1 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/shell/hush.c b/shell/hush.c
index a3df5edcd..32b90876f 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -45,6 +45,8 @@
45 * follow IFS rules more precisely, including update semantics 45 * follow IFS rules more precisely, including update semantics
46 * builtins mandated by standards we don't support: 46 * builtins mandated by standards we don't support:
47 * [un]alias, command, fc, getopts, newgrp, readonly, times 47 * [un]alias, command, fc, getopts, newgrp, readonly, times
48 * make complex ${var%...} constructs support optional
49 * make here documents optional
48 * 50 *
49 * Bash compat TODO: 51 * Bash compat TODO:
50 * redirection of stdout+stderr: &> and >& 52 * redirection of stdout+stderr: &> and >&
@@ -5887,36 +5889,36 @@ static void add_till_backquote(o_string *dest, struct in_str *input)
5887 * echo $(echo 'TEST)' BEST) TEST) BEST 5889 * echo $(echo 'TEST)' BEST) TEST) BEST
5888 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST 5890 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST
5889 * 5891 *
5890 * BUG: enter: echo $(( `printf '(\x28 1'` + `echo 2))` )) 5892 * Also adapted to eat ${var%...} constructs, since ... part
5891 * on the command line, press Enter. You get > prompt which is impossible 5893 * can contain arbitrary constructs, just like $(cmd).
5892 * to exit with ^C.
5893 */ 5894 */
5894#define DOUBLE_CLOSE_CHAR_FLAG 0x80 5895#define DOUBLE_CLOSE_CHAR_FLAG 0x80
5895static void add_till_closing_paren(o_string *dest, struct in_str *input, char end_ch) 5896static void add_till_closing_paren(o_string *dest, struct in_str *input, char end_ch)
5896{ 5897{
5897 int count = 0;
5898 char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG; 5898 char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG;
5899 end_ch &= (DOUBLE_CLOSE_CHAR_FLAG-1); 5899 end_ch &= (DOUBLE_CLOSE_CHAR_FLAG-1);
5900 while (1) { 5900 while (1) {
5901 int ch = i_getch(input); 5901 int ch = i_getch(input);
5902 if (ch == EOF) { 5902 if (ch == EOF) {
5903 syntax_error_unterm_ch(')'); 5903 syntax_error_unterm_ch(end_ch);
5904 /*xfunc_die(); - redundant */ 5904 /*xfunc_die(); - redundant */
5905 } 5905 }
5906 if (ch == '(' || ch == '{') 5906 if (ch == end_ch) {
5907 count++; 5907 if (!dbl)
5908 if (ch == ')' || ch == '}') { 5908 break;
5909 count--; 5909 /* we look for closing )) of $((EXPR)) */
5910 if (count < 0 && ch == end_ch) { 5910 if (i_peek(input) == end_ch) {
5911 if (!dbl) 5911 i_getch(input); /* eat second ')' */
5912 break; 5912 break;
5913 if (i_peek(input) == ')') {
5914 i_getch(input);
5915 break;
5916 }
5917 } 5913 }
5918 } 5914 }
5919 o_addchr(dest, ch); 5915 o_addchr(dest, ch);
5916 if (ch == '(' || ch == '{') {
5917 ch = (ch == '(' ? ')' : '}');
5918 add_till_closing_paren(dest, input, ch);
5919 o_addchr(dest, ch);
5920 continue;
5921 }
5920 if (ch == '\'') { 5922 if (ch == '\'') {
5921 add_till_single_quote(dest, input); 5923 add_till_single_quote(dest, input);
5922 o_addchr(dest, ch); 5924 o_addchr(dest, ch);
@@ -5927,6 +5929,11 @@ static void add_till_closing_paren(o_string *dest, struct in_str *input, char en
5927 o_addchr(dest, ch); 5929 o_addchr(dest, ch);
5928 continue; 5930 continue;
5929 } 5931 }
5932 if (ch == '`') {
5933 add_till_backquote(dest, input);
5934 o_addchr(dest, ch);
5935 continue;
5936 }
5930 if (ch == '\\') { 5937 if (ch == '\\') {
5931 /* \x. Copy verbatim. Important for \(, \) */ 5938 /* \x. Copy verbatim. Important for \(, \) */
5932 ch = i_getch(input); 5939 ch = i_getch(input);