svn commit: trunk/busybox/shell: hush_test/hush-psubst
vda at busybox.net
vda at busybox.net
Tue Jun 10 22:39:38 UTC 2008
Author: vda
Date: 2008-06-10 15:39:37 -0700 (Tue, 10 Jun 2008)
New Revision: 22288
Log:
hush: more backtick and quoting fixes...
Added:
trunk/busybox/shell/hush_test/hush-psubst/tick3.right
trunk/busybox/shell/hush_test/hush-psubst/tick3.tests
Modified:
trunk/busybox/shell/hush.c
Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c 2008-06-10 20:13:40 UTC (rev 22287)
+++ trunk/busybox/shell/hush.c 2008-06-10 22:39:37 UTC (rev 22288)
@@ -1221,6 +1221,23 @@
o_addchr(o, ch);
}
+static void o_addqstr(o_string *o, const char *str, int len, int quote)
+{
+ char ch;
+ if (!quote || str[strcspn(str, "*?[\\")] == '\0') {
+ o_addstr(o, str, len);
+ return;
+ }
+ while (len) {
+ ch = *str++;
+ if (ch && strchr("*?[\\", ch)) {
+ o_addchr(o, '\\');
+ }
+ o_addchr(o, ch);
+ len--;
+ }
+}
+
/* A special kind of o_string for $VAR and `cmd` expansion.
* It contains char* list[] at the beginning, which is grown in 16 element
* increments. Actual string data starts at the next multiple of 16.
@@ -2445,7 +2462,7 @@
* In the long run that function can be merged with run_list,
* but doing that now would hobble the debugging effort. */
free_pipe_list(pi, /* indent: */ 0);
- debug_printf_exec("run_nad_free_list return %d\n", rcode);
+ debug_printf_exec("run_and_free_list return %d\n", rcode);
return rcode;
}
@@ -2549,7 +2566,7 @@
while (1) {
int word_len = strcspn(str, ifs);
if (word_len) {
- o_addstr(output, str, word_len); /* store non-ifs chars */
+ o_addqstr(output, str, word_len, output->o_quote);
str += word_len;
}
if (!*str) /* EOL - do not finalize word */
@@ -2590,7 +2607,7 @@
while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
o_string subst_result = NULL_O_STRING;
- o_addstr(output, arg, p - arg);
+ o_addqstr(output, arg, p - arg, output->o_quote);
o_debug_list("expand_vars_to_list[1]", output, n);
arg = ++p;
p = strchr(p, SPECIAL_VAR_SYMBOL);
@@ -2636,7 +2653,7 @@
* and in this case should treat it like '$*' - see 'else...' below */
if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
while (1) {
- o_addstr(output, global_argv[i], strlen(global_argv[i]));
+ o_addqstr(output, global_argv[i], strlen(global_argv[i]), output->o_quote);
if (++i >= global_argc)
break;
o_addchr(output, '\0');
@@ -2645,7 +2662,7 @@
}
} else { /* quoted $*: add as one word */
while (1) {
- o_addstr(output, global_argv[i], strlen(global_argv[i]));
+ o_addqstr(output, global_argv[i], strlen(global_argv[i]), output->o_quote);
if (!global_argv[++i])
break;
if (ifs[0])
@@ -2684,8 +2701,9 @@
}
} /* else: quoted $VAR, val will be appended below */
}
- if (val)
- o_addstr(output, val, strlen(val));
+ if (val) {
+ o_addqstr(output, val, strlen(val), output->o_quote);
+ }
o_free(&subst_result);
arg = ++p;
@@ -2693,7 +2711,7 @@
if (arg[0]) {
o_debug_list("expand_vars_to_list[a]", output, n);
- o_addstr(output, arg, strlen(arg) + 1);
+ o_addqstr(output, arg, strlen(arg) + 1, output->o_quote);
o_debug_list("expand_vars_to_list[b]", output, n);
} else if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
&& !(ored_ch & 0x80) /* and all vars were not quoted. */
@@ -3389,7 +3407,7 @@
break;
if (ch == '\'')
break;
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
}
}
/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
@@ -3400,15 +3418,15 @@
if (ch == '"')
break;
if (ch == '\\') { /* \x. Copy both chars. */
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
ch = i_getch(input);
}
if (ch == EOF)
break;
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
if (ch == '`') {
add_till_backquote(dest, input);
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
continue;
}
// if (ch == '$') ...
@@ -3432,18 +3450,17 @@
{
while (1) {
int ch = i_getch(input);
-//bb_error_msg("ADD '%c'", ch);
if (ch == '`')
break;
if (ch == '\\') { /* \x. Copy both chars unless it is \` */
int ch2 = i_getch(input);
if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
ch = ch2;
}
if (ch == EOF)
break;
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
}
}
/* Process $(cmd) - copy contents until ")" is seen. Complicated by
@@ -3470,15 +3487,15 @@
if (ch == ')')
if (--count < 0)
break;
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
if (ch == '\'') {
add_till_single_quote(dest, input);
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
continue;
}
if (ch == '"') {
add_till_double_quote(dest, input);
- o_addchr(dest, ch);
+ o_addqchr(dest, ch, 1);
continue;
}
}
@@ -3638,7 +3655,25 @@
debug_printf_parse("parse_stream return 1: \\<eof>\n");
return 1;
}
- o_addqchr(dest, i_getch(input), dest->o_quote);
+ /* bash:
+ * "The backslash retains its special meaning [in "..."]
+ * only when followed by one of the following characters:
+ * $, `, ", \, or <newline>. A double quote may be quoted
+ * within double quotes by preceding it with a backslash.
+ * If enabled, history expansion will be performed unless
+ * an ! appearing in double quotes is escaped using
+ * a backslash. The backslash preceding the ! is not removed."
+ */
+ if (dest->o_quote) {
+ if (strchr("$`\"\\", next) != NULL) {
+ o_addqchr(dest, i_getch(input), 1);
+ } else {
+ o_addqchr(dest, '\\', 1);
+ }
+ } else {
+ o_addchr(dest, '\\');
+ o_addchr(dest, i_getch(input));
+ }
break;
case '$':
if (handle_dollar(dest, input) != 0) {
Added: trunk/busybox/shell/hush_test/hush-psubst/tick3.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-psubst/tick3.right (rev 0)
+++ trunk/busybox/shell/hush_test/hush-psubst/tick3.right 2008-06-10 22:39:37 UTC (rev 22288)
@@ -0,0 +1,6 @@
+\TESTZZBEST
+$TEST
+Q
+a\bc
+a"c
+done:0
Added: trunk/busybox/shell/hush_test/hush-psubst/tick3.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-psubst/tick3.tests (rev 0)
+++ trunk/busybox/shell/hush_test/hush-psubst/tick3.tests 2008-06-10 22:39:37 UTC (rev 22288)
@@ -0,0 +1,11 @@
+#!/bin/sh
+TEST=Q
+# \` is special
+echo `echo '\'TEST\`echo ZZ\`BEST`
+# \$ and \\ are special
+echo `echo \\$TEST`
+echo `echo \$TEST`
+echo a`echo \\\\b`c
+# \" etc are NOT special (passed verbatim WITH \)!
+echo a`echo \"`c
+echo done:$?
Property changes on: trunk/busybox/shell/hush_test/hush-psubst/tick3.tests
___________________________________________________________________
Name: svn:executable
+ *
More information about the busybox-cvs
mailing list