On Saturday 26 June 2010 16:12, Ralf Friedl wrote:
> I have the following effect with this script:
> 
> $ cat /tmp/test.sh
> #!/bin/sh
> 
> IP=192.168.0.1
> echo "${IP//./\\.}"
> echo "${IP//./\\.}"' '
> echo "${IP//./\\.}"'['
> echo "${IP//./\\.}["
> echo "${IP//./\\\\.}["
> # end
> 
> $ ash /tmp/test.sh
> 192\.168\.0\.1
> 192\.168\.0\.1
> 192.168.0.1[
> 192.168.0.1[
> 192\.168\.0\.1[
> $ bash /tmp/test.sh
> 192\.168\.0\.1
> 192\.168\.0\.1
> 192\.168\.0\.1[
> 192\.168\.0\.1[
> 192\\.168\\.0\\.1[
> 
> The intent is to build a regular expression that has the dots quoted. It 
> works when nothing follows the substitution (1. echo). It works when 
> followed by a quoted space, or every other character I tried (2. echo). 
> The quote doesn't appear when it is followed by an opening bracket, 
> either in single quotes or in double quotes (3. echo and 4. echo). It 
> seems that in this case extra backslashes are needed (5. echo). The 
> substitution is performed, but the following bracket somehow causes an 
> extra unquoting of the argument.
> The results with bash are different.
> BusyBox is v1.16.1.

Please try attached patch.
-- 
vda
diff -ad -urpN busybox.0/shell/ash.c busybox.1/shell/ash.c
--- busybox.0/shell/ash.c	2010-06-26 02:39:36.000000000 +0200
+++ busybox.1/shell/ash.c	2010-06-26 22:46:50.000000000 +0200
@@ -6184,8 +6184,7 @@ subevalvar(char *p, char *str, int strlo
 	char *startp;
 	char *loc;
 	char *rmesc, *rmescend;
-	IF_ASH_BASH_COMPAT(char *repl = NULL;)
-	IF_ASH_BASH_COMPAT(char null = '\0';)
+	IF_ASH_BASH_COMPAT(const char *repl = NULL;)
 	IF_ASH_BASH_COMPAT(int pos, len, orig_len;)
 	int saveherefd = herefd;
 	int amount, workloc, resetloc;
@@ -6306,7 +6305,7 @@ subevalvar(char *p, char *str, int strlo
 		if (!repl) {
 			repl = parse_sub_pattern(str, varflags & VSQUOTE);
 			if (!repl)
-				repl = &null;
+				repl = nullstr;
 		}
 
 		/* If there's no pattern to match, return the expansion unmolested */
@@ -6357,8 +6356,12 @@ subevalvar(char *p, char *str, int strlo
 				idx = loc;
 			}
 
-			for (loc = repl; *loc; loc++) {
+			for (loc = (char*)repl; *loc; loc++) {
 				char *restart_detect = stackblock();
+				if (quotes && *loc == '\\') {
+					STPUTC(CTLESC, expdest);
+					len++;
+				}
 				STPUTC(*loc, expdest);
 				if (stackblock() != restart_detect)
 					goto restart;
@@ -6368,6 +6371,10 @@ subevalvar(char *p, char *str, int strlo
 			if (subtype == VSREPLACE) {
 				while (*idx) {
 					char *restart_detect = stackblock();
+					if (quotes && *idx == '\\') {
+						STPUTC(CTLESC, expdest);
+						len++;
+					}
 					STPUTC(*idx, expdest);
 					if (stackblock() != restart_detect)
 						goto restart;
@@ -6381,11 +6388,10 @@ subevalvar(char *p, char *str, int strlo
 		/* We've put the replaced text into a buffer at workloc, now
 		 * move it to the right place and adjust the stack.
 		 */
-		startp = stackblock() + startloc;
 		STPUTC('\0', expdest);
-		memmove(startp, stackblock() + workloc, len);
-		startp[len++] = '\0';
-		amount = expdest - ((char *)stackblock() + startloc + len - 1);
+		startp = (char *)stackblock() + startloc;
+		memmove(startp, (char *)stackblock() + workloc, len + 1);
+		amount = expdest - (startp + len);
 		STADJUST(-amount, expdest);
 		return startp;
 	}
@@ -6685,7 +6691,7 @@ evalvar(char *p, int flags, struct strli
 		 */
 		STPUTC('\0', expdest);
 		patloc = expdest - (char *)stackblock();
-		if (0 == subevalvar(p, /* str: */ NULL, patloc, subtype,
+		if (NULL == subevalvar(p, /* str: */ NULL, patloc, subtype,
 				startloc, varflags,
 //TODO: | EXP_REDIR too? All other such places do it too
 				/* quotes: */ flags & (EXP_FULL | EXP_CASE),
@@ -6848,13 +6854,11 @@ addfname(const char *name)
 	exparg.lastp = &sp->next;
 }
 
-static char *expdir;
-
 /*
  * Do metacharacter (i.e. *, ?, [...]) expansion.
  */
 static void
-expmeta(char *enddir, char *name)
+expmeta(char *expdir, char *enddir, char *name)
 {
 	char *p;
 	const char *cp;
@@ -6953,7 +6957,7 @@ expmeta(char *enddir, char *name)
 				for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';)
 					continue;
 				p[-1] = '/';
-				expmeta(p, endname);
+				expmeta(expdir, p, endname);
 			}
 		}
 	}
@@ -7035,6 +7039,7 @@ expandmeta(struct strlist *str /*, int f
 	/* TODO - EXP_REDIR */
 
 	while (str) {
+		char *expdir;
 		struct strlist **savelastp;
 		struct strlist *sp;
 		char *p;
@@ -7051,8 +7056,7 @@ expandmeta(struct strlist *str /*, int f
 			int i = strlen(str->text);
 			expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
 		}
-
-		expmeta(expdir, p);
+		expmeta(expdir, expdir, p);
 		free(expdir);
 		if (p != str->text)
 			free(p);
@@ -9101,19 +9105,15 @@ evalcommand(union node *cmd, int flags)
 	/* Print the command if xflag is set. */
 	if (xflag) {
 		int n;
-		const char *p = " %s";
+		const char *p = " %s" + 1;
 
-		p++;
 		fdprintf(preverrout_fd, p, expandstr(ps4val()));
-
 		sp = varlist.list;
 		for (n = 0; n < 2; n++) {
 			while (sp) {
 				fdprintf(preverrout_fd, p, sp->text);
 				sp = sp->next;
-				if (*p == '%') {
-					p--;
-				}
+				p = " %s";
 			}
 			sp = arglist.list;
 		}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to