ash: fix slash treatment in expmeta

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@iki.fi>
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ron Yorston 2015-09-04 10:32:41 +01:00 committed by Denys Vlasenko
parent b5be13ccd9
commit ca25af9b06

View File

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