hush: do not drop backslash from eval 'echo ok\'

newer bash does not drop it, most other shells too

function                                             old     new   delta
unbackslash                                           39      57     +18
parse_stream                                        2753    2751      -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 18/-2)              Total: 16 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-04-11 01:15:33 +02:00
parent 3632cb15f1
commit 89e9d5534d
6 changed files with 22 additions and 8 deletions

View File

@ -203,7 +203,7 @@
* TODO:
* singleword+noglob expansion:
* v='a b'; [[ $v = 'a b' ]]; echo 0:$?
* [[ /bin/* ]]; echo 0:$?
* [[ /bin/n* ]]; echo 0:$?
* -a/-o are not AND/OR ops! (they are just strings)
* quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
* = is glob match operator, not equality operator: STR = GLOB

View File

@ -0,0 +1 @@
ok\

View File

@ -0,0 +1 @@
eval 'echo ok\'

View File

@ -1,2 +1,2 @@
redir_exec1.tests: line 1: can't create /cant/be/created: nonexistent directory
./redir_exec1.tests: line 1: can't create /cant/be/created: nonexistent directory
First

View File

@ -83,7 +83,7 @@
* Status of [[ support:
* [[ args ]] are CMD_SINGLEWORD_NOGLOB:
* v='a b'; [[ $v = 'a b' ]]; echo 0:$?
* [[ /bin/* ]]; echo 0:$?
* [[ /bin/n* ]]; echo 0:$?
* TODO:
* &&/|| are AND/OR ops, -a/-o are not
* quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
@ -1426,8 +1426,19 @@ static char *unbackslash(char *src)
{
char *dst = src = strchrnul(src, '\\');
while (1) {
if (*src == '\\')
if (*src == '\\') {
src++;
if (*src != '\0') {
/* \x -> x */
*dst++ = *src++;
continue;
}
/* else: "\<nul>". Do not delete this backslash.
* Testcase: eval 'echo ok\'
*/
*dst++ = '\\';
/* fallthrough */
}
if ((*dst++ = *src++) == '\0')
break;
}
@ -5392,16 +5403,17 @@ static struct pipe *parse_stream(char **pstring,
continue; /* get next char */
case '\\':
/*nommu_addchr(&ctx.as_string, '\\'); - already done */
o_addchr(&ctx.word, '\\');
ch = i_getch(input);
if (ch == EOF) {
/* Ignore this '\'. Testcase: eval 'echo Ok\' */
#if !BB_MMU
/* Testcase: eval 'echo Ok\' */
#if 0 /* bash-4.3.43 was removing backslash, but 4.4.19 retains it, most other shells too */
/* Remove trailing '\' from ctx.as_string */
ctx.as_string.data[--ctx.as_string.length] = '\0';
#endif
continue; /* get next char */
}
o_addchr(&ctx.word, '\\');
/* Example: echo Hello \2>file
* we need to know that word 2 is quoted
*/

View File

@ -1 +1 @@
ok
ok\