aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-06-26 22:55:44 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-06-26 22:55:44 +0200
commitfd33e17a2bf4c09bb12ac09a645cfd0f0f914fec (patch)
tree45d99d8cc103dcd97086b61f8f8616f5ac14e931
parentb768aeb164d361d1ca2c8f6c091e93442f072656 (diff)
downloadbusybox-w32-fd33e17a2bf4c09bb12ac09a645cfd0f0f914fec.tar.gz
busybox-w32-fd33e17a2bf4c09bb12ac09a645cfd0f0f914fec.tar.bz2
busybox-w32-fd33e17a2bf4c09bb12ac09a645cfd0f0f914fec.zip
ash: fix obscure case of replacing + globbing + backslashes
function old new delta subevalvar 1152 1178 +26 readtoken1 3267 3275 +8 redirect 1284 1286 +2 expandarg 957 958 +1 expdir 4 - -4 evalcommand 1219 1209 -10 expmeta 481 469 -12 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 4/2 up/down: 37/-26) Total: 11 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c42
-rw-r--r--shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right10
-rwxr-xr-xshell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests21
3 files changed, 52 insertions, 21 deletions
diff --git a/shell/ash.c b/shell/ash.c
index cfd8154ef..0337a5535 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6184,8 +6184,7 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6184 char *startp; 6184 char *startp;
6185 char *loc; 6185 char *loc;
6186 char *rmesc, *rmescend; 6186 char *rmesc, *rmescend;
6187 IF_ASH_BASH_COMPAT(char *repl = NULL;) 6187 IF_ASH_BASH_COMPAT(const char *repl = NULL;)
6188 IF_ASH_BASH_COMPAT(char null = '\0';)
6189 IF_ASH_BASH_COMPAT(int pos, len, orig_len;) 6188 IF_ASH_BASH_COMPAT(int pos, len, orig_len;)
6190 int saveherefd = herefd; 6189 int saveherefd = herefd;
6191 int amount, workloc, resetloc; 6190 int amount, workloc, resetloc;
@@ -6306,7 +6305,7 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6306 if (!repl) { 6305 if (!repl) {
6307 repl = parse_sub_pattern(str, varflags & VSQUOTE); 6306 repl = parse_sub_pattern(str, varflags & VSQUOTE);
6308 if (!repl) 6307 if (!repl)
6309 repl = &null; 6308 repl = nullstr;
6310 } 6309 }
6311 6310
6312 /* If there's no pattern to match, return the expansion unmolested */ 6311 /* If there's no pattern to match, return the expansion unmolested */
@@ -6357,8 +6356,12 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6357 idx = loc; 6356 idx = loc;
6358 } 6357 }
6359 6358
6360 for (loc = repl; *loc; loc++) { 6359 for (loc = (char*)repl; *loc; loc++) {
6361 char *restart_detect = stackblock(); 6360 char *restart_detect = stackblock();
6361 if (quotes && *loc == '\\') {
6362 STPUTC(CTLESC, expdest);
6363 len++;
6364 }
6362 STPUTC(*loc, expdest); 6365 STPUTC(*loc, expdest);
6363 if (stackblock() != restart_detect) 6366 if (stackblock() != restart_detect)
6364 goto restart; 6367 goto restart;
@@ -6368,6 +6371,10 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6368 if (subtype == VSREPLACE) { 6371 if (subtype == VSREPLACE) {
6369 while (*idx) { 6372 while (*idx) {
6370 char *restart_detect = stackblock(); 6373 char *restart_detect = stackblock();
6374 if (quotes && *idx == '\\') {
6375 STPUTC(CTLESC, expdest);
6376 len++;
6377 }
6371 STPUTC(*idx, expdest); 6378 STPUTC(*idx, expdest);
6372 if (stackblock() != restart_detect) 6379 if (stackblock() != restart_detect)
6373 goto restart; 6380 goto restart;
@@ -6381,11 +6388,10 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6381 /* We've put the replaced text into a buffer at workloc, now 6388 /* We've put the replaced text into a buffer at workloc, now
6382 * move it to the right place and adjust the stack. 6389 * move it to the right place and adjust the stack.
6383 */ 6390 */
6384 startp = stackblock() + startloc;
6385 STPUTC('\0', expdest); 6391 STPUTC('\0', expdest);
6386 memmove(startp, stackblock() + workloc, len); 6392 startp = (char *)stackblock() + startloc;
6387 startp[len++] = '\0'; 6393 memmove(startp, (char *)stackblock() + workloc, len + 1);
6388 amount = expdest - ((char *)stackblock() + startloc + len - 1); 6394 amount = expdest - (startp + len);
6389 STADJUST(-amount, expdest); 6395 STADJUST(-amount, expdest);
6390 return startp; 6396 return startp;
6391 } 6397 }
@@ -6685,7 +6691,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
6685 */ 6691 */
6686 STPUTC('\0', expdest); 6692 STPUTC('\0', expdest);
6687 patloc = expdest - (char *)stackblock(); 6693 patloc = expdest - (char *)stackblock();
6688 if (0 == subevalvar(p, /* str: */ NULL, patloc, subtype, 6694 if (NULL == subevalvar(p, /* str: */ NULL, patloc, subtype,
6689 startloc, varflags, 6695 startloc, varflags,
6690//TODO: | EXP_REDIR too? All other such places do it too 6696//TODO: | EXP_REDIR too? All other such places do it too
6691 /* quotes: */ flags & (EXP_FULL | EXP_CASE), 6697 /* quotes: */ flags & (EXP_FULL | EXP_CASE),
@@ -6848,13 +6854,11 @@ addfname(const char *name)
6848 exparg.lastp = &sp->next; 6854 exparg.lastp = &sp->next;
6849} 6855}
6850 6856
6851static char *expdir;
6852
6853/* 6857/*
6854 * Do metacharacter (i.e. *, ?, [...]) expansion. 6858 * Do metacharacter (i.e. *, ?, [...]) expansion.
6855 */ 6859 */
6856static void 6860static void
6857expmeta(char *enddir, char *name) 6861expmeta(char *expdir, char *enddir, char *name)
6858{ 6862{
6859 char *p; 6863 char *p;
6860 const char *cp; 6864 const char *cp;
@@ -6953,7 +6957,7 @@ expmeta(char *enddir, char *name)
6953 for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';) 6957 for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';)
6954 continue; 6958 continue;
6955 p[-1] = '/'; 6959 p[-1] = '/';
6956 expmeta(p, endname); 6960 expmeta(expdir, p, endname);
6957 } 6961 }
6958 } 6962 }
6959 } 6963 }
@@ -7035,6 +7039,7 @@ expandmeta(struct strlist *str /*, int flag*/)
7035 /* TODO - EXP_REDIR */ 7039 /* TODO - EXP_REDIR */
7036 7040
7037 while (str) { 7041 while (str) {
7042 char *expdir;
7038 struct strlist **savelastp; 7043 struct strlist **savelastp;
7039 struct strlist *sp; 7044 struct strlist *sp;
7040 char *p; 7045 char *p;
@@ -7051,8 +7056,7 @@ expandmeta(struct strlist *str /*, int flag*/)
7051 int i = strlen(str->text); 7056 int i = strlen(str->text);
7052 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */ 7057 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
7053 } 7058 }
7054 7059 expmeta(expdir, expdir, p);
7055 expmeta(expdir, p);
7056 free(expdir); 7060 free(expdir);
7057 if (p != str->text) 7061 if (p != str->text)
7058 free(p); 7062 free(p);
@@ -9101,19 +9105,15 @@ evalcommand(union node *cmd, int flags)
9101 /* Print the command if xflag is set. */ 9105 /* Print the command if xflag is set. */
9102 if (xflag) { 9106 if (xflag) {
9103 int n; 9107 int n;
9104 const char *p = " %s"; 9108 const char *p = " %s" + 1;
9105 9109
9106 p++;
9107 fdprintf(preverrout_fd, p, expandstr(ps4val())); 9110 fdprintf(preverrout_fd, p, expandstr(ps4val()));
9108
9109 sp = varlist.list; 9111 sp = varlist.list;
9110 for (n = 0; n < 2; n++) { 9112 for (n = 0; n < 2; n++) {
9111 while (sp) { 9113 while (sp) {
9112 fdprintf(preverrout_fd, p, sp->text); 9114 fdprintf(preverrout_fd, p, sp->text);
9113 sp = sp->next; 9115 sp = sp->next;
9114 if (*p == '%') { 9116 p = " %s";
9115 p--;
9116 }
9117 } 9117 }
9118 sp = arglist.list; 9118 sp = arglist.list;
9119 } 9119 }
diff --git a/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right
new file mode 100644
index 000000000..b212c246c
--- /dev/null
+++ b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.right
@@ -0,0 +1,10 @@
1192\.168\.0\.1
2192\.168\.0\.1[
3192\.168\.0\.1[
4192\\.168\\.0\\.1[
5192\.168\.0\.1[
6192\.168\.0\.1
7192\.168\.0\.1[
8192\.168\.0\.1[
9192\\.168\\.0\\.1[
10192\.168\.0\.1[
diff --git a/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests
new file mode 100755
index 000000000..3fa2f186d
--- /dev/null
+++ b/shell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests
@@ -0,0 +1,21 @@
1# The bug here was triggered by:
2# * performin pathname expansion because we see [
3# * replace operator did not escape \ in replace string
4
5IP=192.168.0.1
6
7rm -f '192.168.0.1['
8echo "${IP//./\\.}"
9echo "${IP//./\\.}"'[' # bug was here
10echo "${IP//./\\.}[" # bug was here
11echo "${IP//./\\\\.}[" # bug was here
12echo "192\.168\.0\.1["
13
14echo >'192.168.0.1['
15echo "${IP//./\\.}"
16echo "${IP//./\\.}"'[' # bug was here
17echo "${IP//./\\.}[" # bug was here
18echo "${IP//./\\\\.}[" # bug was here
19echo "192\.168\.0\.1["
20
21rm -f '192.168.0.1['