hush: partially fix wrong expansion on $IFS (bug 4027).
In the added testcase, before patch we failed 8 out of 9 tests, now we fail only 2 (4th and 5th). function old new delta expand_on_ifs 225 258 +33 expand_vars_to_list 1038 1054 +16 o_save_ptr_helper 115 119 +4 builtin_umask 132 133 +1 o_addQstr 165 161 -4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/1 up/down: 54/-4) Total: 50 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
954dbd3a00
commit
4fb53fb08c
39
shell/hush.c
39
shell/hush.c
@ -2281,7 +2281,7 @@ static void o_addqblock(o_string *o, const char *str, int len)
|
|||||||
ordinary_cnt = len;
|
ordinary_cnt = len;
|
||||||
o_addblock(o, str, ordinary_cnt);
|
o_addblock(o, str, ordinary_cnt);
|
||||||
if (ordinary_cnt == len)
|
if (ordinary_cnt == len)
|
||||||
return;
|
return; /* NUL is already added by o_addblock */
|
||||||
str += ordinary_cnt;
|
str += ordinary_cnt;
|
||||||
len -= ordinary_cnt + 1; /* we are processing + 1 char below */
|
len -= ordinary_cnt + 1; /* we are processing + 1 char below */
|
||||||
|
|
||||||
@ -2295,8 +2295,8 @@ static void o_addqblock(o_string *o, const char *str, int len)
|
|||||||
o_grow_by(o, sz);
|
o_grow_by(o, sz);
|
||||||
o->data[o->length] = ch;
|
o->data[o->length] = ch;
|
||||||
o->length++;
|
o->length++;
|
||||||
o->data[o->length] = '\0';
|
|
||||||
}
|
}
|
||||||
|
o->data[o->length] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void o_addQblock(o_string *o, const char *str, int len)
|
static void o_addQblock(o_string *o, const char *str, int len)
|
||||||
@ -2385,6 +2385,7 @@ static int o_save_ptr_helper(o_string *o, int n)
|
|||||||
n, string_len, string_start);
|
n, string_len, string_start);
|
||||||
o->has_empty_slot = 0;
|
o->has_empty_slot = 0;
|
||||||
}
|
}
|
||||||
|
o->has_quoted_part = 0;
|
||||||
list[n] = (char*)(uintptr_t)string_len;
|
list[n] = (char*)(uintptr_t)string_len;
|
||||||
return n + 1;
|
return n + 1;
|
||||||
}
|
}
|
||||||
@ -4754,8 +4755,13 @@ static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len
|
|||||||
static int expand_on_ifs(o_string *output, int n, const char *str)
|
static int expand_on_ifs(o_string *output, int n, const char *str)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
int word_len = strcspn(str, G.ifs);
|
int word_len;
|
||||||
|
|
||||||
|
if (!*str) /* EOL - do not finalize word */
|
||||||
|
break;
|
||||||
|
word_len = strcspn(str, G.ifs);
|
||||||
if (word_len) {
|
if (word_len) {
|
||||||
|
/* We have WORD_LEN leading non-IFS chars */
|
||||||
if (!(output->o_expflags & EXP_FLAG_GLOB)) {
|
if (!(output->o_expflags & EXP_FLAG_GLOB)) {
|
||||||
o_addblock(output, str, word_len);
|
o_addblock(output, str, word_len);
|
||||||
} else {
|
} else {
|
||||||
@ -4769,13 +4775,25 @@ static int expand_on_ifs(o_string *output, int n, const char *str)
|
|||||||
/*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */
|
/*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */
|
||||||
}
|
}
|
||||||
str += word_len;
|
str += word_len;
|
||||||
|
if (!*str) /* EOL - do not finalize word */
|
||||||
|
break;
|
||||||
|
goto finalize; /* optimization (can just fall thru) */
|
||||||
}
|
}
|
||||||
if (!*str) /* EOL - do not finalize word */
|
/* Case "v=' a'; echo ''$v": we do need to finalize empty word */
|
||||||
break;
|
if (output->has_quoted_part
|
||||||
o_addchr(output, '\0');
|
/* Case "v=' a'; echo $v":
|
||||||
debug_print_list("expand_on_ifs", output, n);
|
* here nothing precedes the space in $v expansion,
|
||||||
n = o_save_ptr(output, n);
|
* therefore we should not finish the word
|
||||||
str += strspn(str, G.ifs); /* skip ifs chars */
|
* (IOW: if there *is* word to finalize, only then do it)
|
||||||
|
*/
|
||||||
|
|| (output->length && output->data[output->length - 1])
|
||||||
|
) {
|
||||||
|
finalize:
|
||||||
|
o_addchr(output, '\0');
|
||||||
|
debug_print_list("expand_on_ifs", output, n);
|
||||||
|
n = o_save_ptr(output, n);
|
||||||
|
}
|
||||||
|
str += strspn(str, G.ifs); /* skip IFS chars */
|
||||||
}
|
}
|
||||||
debug_print_list("expand_on_ifs[1]", output, n);
|
debug_print_list("expand_on_ifs[1]", output, n);
|
||||||
return n;
|
return n;
|
||||||
@ -5270,11 +5288,13 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
|||||||
if (G.ifs[0])
|
if (G.ifs[0])
|
||||||
o_addchr(output, G.ifs[0]);
|
o_addchr(output, G.ifs[0]);
|
||||||
}
|
}
|
||||||
|
output->has_quoted_part = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPECIAL_VAR_SYMBOL: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
|
case SPECIAL_VAR_SYMBOL: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
|
||||||
/* "Empty variable", used to make "" etc to not disappear */
|
/* "Empty variable", used to make "" etc to not disappear */
|
||||||
|
output->has_quoted_part = 1;
|
||||||
arg++;
|
arg++;
|
||||||
cant_be_null = 0x80;
|
cant_be_null = 0x80;
|
||||||
break;
|
break;
|
||||||
@ -5316,6 +5336,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
|||||||
val = NULL;
|
val = NULL;
|
||||||
}
|
}
|
||||||
} else { /* quoted $VAR, val will be appended below */
|
} else { /* quoted $VAR, val will be appended below */
|
||||||
|
output->has_quoted_part = 1;
|
||||||
debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
|
debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
|
||||||
!!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
|
!!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
|
||||||
}
|
}
|
||||||
|
9
shell/hush_test/hush-vars/var_expand_on_ifs.right
Normal file
9
shell/hush_test/hush-vars/var_expand_on_ifs.right
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
1 a b c
|
||||||
|
2 a + b c
|
||||||
|
3 a b c
|
||||||
|
4 a b c
|
||||||
|
5 a b c
|
||||||
|
6 a b + c
|
||||||
|
7 a b c
|
||||||
|
8 a b c
|
||||||
|
9 a b c
|
11
shell/hush_test/hush-vars/var_expand_on_ifs.tests
Executable file
11
shell/hush_test/hush-vars/var_expand_on_ifs.tests
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
b=' b '
|
||||||
|
e=''
|
||||||
|
echo 1 a $b c
|
||||||
|
echo 2 a +$b c
|
||||||
|
echo 3 a $e$b c
|
||||||
|
echo 4 a "$e"$b c
|
||||||
|
echo 5 a ""$b c
|
||||||
|
echo 6 a $b+ c
|
||||||
|
echo 7 a $b$e c
|
||||||
|
echo 8 a $b"$e" c
|
||||||
|
echo 9 a $b"" c
|
Loading…
Reference in New Issue
Block a user