aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-09-29 18:07:42 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-09-29 18:07:42 +0200
commit657086a3dc573649165a5271473fa1bcf58dc9ed (patch)
treec9be8956c010bf8b512a048ca4f41999c1a4e6a7
parentd17a91db6e0817644445f28515d68b3033388eb4 (diff)
downloadbusybox-w32-657086a3dc573649165a5271473fa1bcf58dc9ed.tar.gz
busybox-w32-657086a3dc573649165a5271473fa1bcf58dc9ed.tar.bz2
busybox-w32-657086a3dc573649165a5271473fa1bcf58dc9ed.zip
hush: fix handling of by backslash-newline in $((arith)) and $(cmd)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/shell/hush.c b/shell/hush.c
index e3dcf2c38..177a794b5 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2387,6 +2387,15 @@ static void o_addchr(o_string *o, int ch)
2387 o->data[o->length] = '\0'; 2387 o->data[o->length] = '\0';
2388} 2388}
2389 2389
2390#if 0
2391/* Valid only if we know o_string is not empty */
2392static void o_delchr(o_string *o)
2393{
2394 o->length--;
2395 o->data[o->length] = '\0';
2396}
2397#endif
2398
2390static void o_addblock(o_string *o, const char *str, int len) 2399static void o_addblock(o_string *o, const char *str, int len)
2391{ 2400{
2392 o_grow_by(o, len); 2401 o_grow_by(o, len);
@@ -3900,6 +3909,23 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
3900 /* command remains "open", available for possible redirects */ 3909 /* command remains "open", available for possible redirects */
3901} 3910}
3902 3911
3912static int i_peek_and_eat_bkslash_nl(struct in_str *input)
3913{
3914 for (;;) {
3915 int ch, ch2;
3916
3917 ch = i_peek(input);
3918 if (ch != '\\')
3919 return ch;
3920 ch2 = i_peek2(input);
3921 if (ch2 != '\n')
3922 return ch;
3923 /* backslash+newline, skip it */
3924 i_getch(input);
3925 i_getch(input);
3926 }
3927}
3928
3903#if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS 3929#if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS
3904/* Subroutines for copying $(...) and `...` things */ 3930/* Subroutines for copying $(...) and `...` things */
3905static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); 3931static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
@@ -4017,7 +4043,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
4017 if (!dbl) 4043 if (!dbl)
4018 break; 4044 break;
4019 /* we look for closing )) of $((EXPR)) */ 4045 /* we look for closing )) of $((EXPR)) */
4020 if (i_peek(input) == end_ch) { 4046 if (i_peek_and_eat_bkslash_nl(input) == end_ch) {
4021 i_getch(input); /* eat second ')' */ 4047 i_getch(input); /* eat second ')' */
4022 break; 4048 break;
4023 } 4049 }
@@ -4055,6 +4081,13 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
4055 syntax_error_unterm_ch(')'); 4081 syntax_error_unterm_ch(')');
4056 return 0; 4082 return 0;
4057 } 4083 }
4084#if 0
4085 if (ch == '\n') {
4086 /* "backslash+newline", ignore both */
4087 o_delchr(dest); /* undo insertion of '\' */
4088 continue;
4089 }
4090#endif
4058 o_addchr(dest, ch); 4091 o_addchr(dest, ch);
4059 continue; 4092 continue;
4060 } 4093 }
@@ -4073,7 +4106,7 @@ static int parse_dollar(o_string *as_string,
4073 o_string *dest, 4106 o_string *dest,
4074 struct in_str *input, unsigned char quote_mask) 4107 struct in_str *input, unsigned char quote_mask)
4075{ 4108{
4076 int ch = i_peek(input); /* first character after the $ */ 4109 int ch = i_peek_and_eat_bkslash_nl(input); /* first character after the $ */
4077 4110
4078 debug_printf_parse("parse_dollar entered: ch='%c'\n", ch); 4111 debug_printf_parse("parse_dollar entered: ch='%c'\n", ch);
4079 if (isalpha(ch)) { 4112 if (isalpha(ch)) {
@@ -4085,18 +4118,8 @@ static int parse_dollar(o_string *as_string,
4085 debug_printf_parse(": '%c'\n", ch); 4118 debug_printf_parse(": '%c'\n", ch);
4086 o_addchr(dest, ch | quote_mask); 4119 o_addchr(dest, ch | quote_mask);
4087 quote_mask = 0; 4120 quote_mask = 0;
4088 next_ch: 4121 ch = i_peek_and_eat_bkslash_nl(input);
4089 ch = i_peek(input);
4090 if (!isalnum(ch) && ch != '_') { 4122 if (!isalnum(ch) && ch != '_') {
4091 if (ch == '\\') {
4092 /* If backslash+newline, skip it */
4093 int ch2 = i_peek2(input);
4094 if (ch2 == '\n') {
4095 i_getch(input);
4096 i_getch(input);
4097 goto next_ch;
4098 }
4099 }
4100 /* End of variable name reached */ 4123 /* End of variable name reached */
4101 break; 4124 break;
4102 } 4125 }
@@ -4126,6 +4149,7 @@ static int parse_dollar(o_string *as_string,
4126 ch = i_getch(input); /* eat '{' */ 4149 ch = i_getch(input); /* eat '{' */
4127 nommu_addchr(as_string, ch); 4150 nommu_addchr(as_string, ch);
4128 4151
4152 i_peek_and_eat_bkslash_nl(input);
4129 ch = i_getch(input); /* first char after '{' */ 4153 ch = i_getch(input); /* first char after '{' */
4130 /* It should be ${?}, or ${#var}, 4154 /* It should be ${?}, or ${#var},
4131 * or even ${?+subst} - operator acting on a special variable, 4155 * or even ${?+subst} - operator acting on a special variable,
@@ -4232,7 +4256,7 @@ static int parse_dollar(o_string *as_string,
4232 ch = i_getch(input); 4256 ch = i_getch(input);
4233 nommu_addchr(as_string, ch); 4257 nommu_addchr(as_string, ch);
4234# if ENABLE_SH_MATH_SUPPORT 4258# if ENABLE_SH_MATH_SUPPORT
4235 if (i_peek(input) == '(') { 4259 if (i_peek_and_eat_bkslash_nl(input) == '(') {
4236 ch = i_getch(input); 4260 ch = i_getch(input);
4237 nommu_addchr(as_string, ch); 4261 nommu_addchr(as_string, ch);
4238 o_addchr(dest, SPECIAL_VAR_SYMBOL); 4262 o_addchr(dest, SPECIAL_VAR_SYMBOL);
@@ -4269,7 +4293,7 @@ static int parse_dollar(o_string *as_string,
4269 case '_': 4293 case '_':
4270 ch = i_getch(input); 4294 ch = i_getch(input);
4271 nommu_addchr(as_string, ch); 4295 nommu_addchr(as_string, ch);
4272 ch = i_peek(input); 4296 ch = i_peek_and_eat_bkslash_nl(input);
4273 if (isalnum(ch)) { /* it's $_name or $_123 */ 4297 if (isalnum(ch)) { /* it's $_name or $_123 */
4274 ch = '_'; 4298 ch = '_';
4275 goto make_var; 4299 goto make_var;