[git commit] ash: fix slash treatment in expmeta

Denys Vlasenko vda.linux at googlemail.com
Fri Sep 4 20:23:54 UTC 2015


commit: http://git.busybox.net/busybox/commit/?id=ca25af9b06b0c3ded77ac70087227896b34003c4
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Commit 549deab caused this sequence of commands:

   mkdir foo
   cd foo
   touch a b
   echo "./"*

to return './*' instead of the expected './a ./b'.  The problem
was caused by the backport of commit 880d952 from dash.  In dash
the issue was fixed by two further commits by Herbert Xu:

<d6d06ff> [EXPAND] Fixed non-leading slash treatment in expmeta
<36f0fa8> [EXPAND] Fix slash treatment in expmeta

(See git://git.kernel.org/pub/scm/utils/dash/dash.git)

Apply these fixes to BusyBox ash, thus causing the new test
glob3.tests to succeed.

function                                             old     new   delta
expmeta                                              469     528     +59

Reported-by: Aaro Koskinen <aaro.koskinen at iki.fi>
Signed-off-by: Ron Yorston <rmy at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash.c |   23 +++++++++++++----------
 1 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index f6190c3..42c9125 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6992,10 +6992,11 @@ expmeta(char *expdir, char *enddir, char *name)
 	struct dirent *dp;
 	int atend;
 	int matchdot;
+	int esc;
 
 	metaflag = 0;
 	start = name;
-	for (p = name; *p; p++) {
+	for (p = name; esc = 0, *p; p += esc + 1) {
 		if (*p == '*' || *p == '?')
 			metaflag = 1;
 		else if (*p == '[') {
@@ -7012,15 +7013,16 @@ expmeta(char *expdir, char *enddir, char *name)
 					break;
 				}
 			}
-		} else if (*p == '\\')
-			p++;
-		else if (*p == '/') {
-			if (metaflag)
-				goto out;
-			start = p + 1;
+		} else {
+			if (*p == '\\')
+				esc++;
+			if (p[esc] == '/') {
+				if (metaflag)
+					break;
+				start = p + esc + 1;
+			}
 		}
 	}
- out:
 	if (metaflag == 0) {    /* we've reached the end of the file name */
 		if (enddir != expdir)
 			metaflag++;
@@ -7060,7 +7062,8 @@ expmeta(char *expdir, char *enddir, char *name)
 		atend = 1;
 	} else {
 		atend = 0;
-		*endname++ = '\0';
+		*endname = '\0';
+		endname += esc + 1;
 	}
 	matchdot = 0;
 	p = start;
@@ -7085,7 +7088,7 @@ expmeta(char *expdir, char *enddir, char *name)
 	}
 	closedir(dirp);
 	if (!atend)
-		endname[-1] = '/';
+		endname[-esc - 1] = esc ? '\\' : '/';
 }
 
 static struct strlist *


More information about the busybox-cvs mailing list