Index: src/ftpcmd.y =================================================================== RCS file: /cvsroot/wu-ftpd/src/ftpcmd.y,v retrieving revision 1.27 retrieving revision 1.27.2.1 diff -u -r1.27 -r1.27.2.1 --- src/ftpcmd.y 2000/07/01 18:17:39 1.27 +++ src/ftpcmd.y 2001/11/28 12:05:42 1.27.2.1 @@ -20,7 +20,7 @@ If you did not receive a copy of the license, it may be obtained online at http://www.wu-ftpd.org/license.html. - $Id: ftpcmd.y,v 1.27 2000/07/01 18:17:39 wuftpd Exp $ + $Id: ftpcmd.y,v 1.27.2.1 2001/11/28 12:05:42 wuftpd Exp $ ****************************************************************************/ /* @@ -1128,19 +1128,23 @@ strcpy(t + 1, $1); globlist = ftpglob(t); if (globerr) { - reply(550, globerr); + reply(550, "%s", globerr); $$ = NULL; if (globlist) { blkfree(globlist); free((char *) globlist); } } - else if (globlist) { + else if (globlist && *globlist) { $$ = *globlist; blkfree(&globlist[1]); free((char *) globlist); } else { + if (globlist) { + blkfree(globlist); + free((char *) globlist); + } errno = ENOENT; perror_reply(550, $1); $$ = NULL; @@ -1154,19 +1158,23 @@ globlist = ftpglob($1); if (globerr) { - reply(550, globerr); + reply(550, "%s", globerr); $$ = NULL; if (globlist) { blkfree(globlist); free((char *) globlist); } } - else if (globlist) { + else if (globlist && *globlist) { $$ = *globlist; blkfree(&globlist[1]); free((char *) globlist); } else { + if (globlist) { + blkfree(globlist); + free((char *) globlist); + } errno = ENOENT; perror_reply(550, $1); $$ = NULL; Index: src/glob.c =================================================================== RCS file: /cvsroot/wu-ftpd/src/glob.c,v retrieving revision 1.14 retrieving revision 1.14.2.1 diff -u -r1.14 -r1.14.2.1 --- src/glob.c 2000/07/01 18:17:39 1.14 +++ src/glob.c 2001/11/28 12:20:53 1.14.2.1 @@ -20,7 +20,7 @@ If you did not receive a copy of the license, it may be obtained online at http://www.wu-ftpd.org/license.html. - $Id: glob.c,v 1.14 2000/07/01 18:17:39 wuftpd Exp $ + $Id: glob.c,v 1.14.2.1 2001/11/28 12:20:53 wuftpd Exp $ ****************************************************************************/ /* @@ -174,19 +174,21 @@ sort(); } +static int +argcmp(const void *p1, const void *p2) +{ + char *s1 = *(char **) p1; + char *s2 = *(char **) p2; + + return (strcmp(s1, s2)); +} + static void sort(void) { - register char **p1, **p2, *c; char **Gvp = &gargv[gargc]; - p1 = sortbas; - while (p1 < Gvp - 1) { - p2 = p1; - while (++p2 < Gvp) - if (strcmp(*p1, *p2) > 0) - c = *p1, *p1 = *p2, *p2 = c; - p1++; - } + if (!globerr) + qsort(sortbas, Gvp - sortbas, sizeof (*sortbas), argcmp); sortbas = Gvp; } @@ -292,13 +294,16 @@ static int execbrc(char *p, char *s) { char restbuf[BUFSIZ + 2]; + char *restbufend = &restbuf[sizeof(restbuf)]; register char *pe, *pm, *pl; int brclev = 0; char *lm, savec, *sgpathp; - for (lm = restbuf; *p != '{'; *lm++ = *p++) - continue; - for (pe = ++p; *pe; pe++) + for (lm = restbuf; *p != '{'; *lm++ = *p++) { + if (lm >= restbufend) + return (0); + } + for (pe = ++p; *pe; pe++) { switch (*pe) { case '{': @@ -314,11 +319,19 @@ case '[': for (pe++; *pe && *pe != ']'; pe++) continue; + if (!*pe) { + globerr = "Missing ]"; + return (0); + } continue; } + } pend: - brclev = 0; - for (pl = pm = p; pm <= pe; pm++) + if (brclev || !*pe) { + globerr = "Missing }"; + return (0); + } + for (pl = pm = p; pm <= pe; pm++) { switch (*pm & (QUOTE | TRIM)) { case '{': @@ -339,6 +352,8 @@ doit: savec = *pm; *pm = 0; + if (lm + strlen(pl) + strlen(pe + 1) >= restbufend) + return (0); (void) strcpy(lm, pl); (void) strcat(restbuf, pe + 1); *pm = savec; @@ -352,19 +367,18 @@ return (1); sort(); pl = pm + 1; - if (brclev) - return (0); continue; case '[': for (pm++; *pm && *pm != ']'; pm++) continue; - if (!*pm) - pm--; + if (!*pm) { + globerr = "Missing ]"; + return (0); + } continue; } - if (brclev) - goto doit; + } return (0); } @@ -416,11 +430,10 @@ else if (scc == (lc = cc)) ok++; } - if (cc == 0) - if (ok) - p--; - else - return 0; + if (cc == 0) { + globerr = "Missing ]"; + return (0); + } continue; case '*': @@ -473,73 +486,16 @@ } } -/* This function appears to be unused, so why waste time and space on it? */ -#if 0 == 1 -static int Gmatch(register char *s, register char *p) -{ - register int scc; - int ok, lc; - int c, cc; - - for (;;) { - scc = *s++ & TRIM; - switch (c = *p++) { - - case '[': - ok = 0; - lc = 077777; - while (cc = *p++) { - if (cc == ']') { - if (ok) - break; - return (0); - } - if (cc == '-') { - if (lc <= scc && scc <= *p++) - ok++; - } - else if (scc == (lc = cc)) - ok++; - } - if (cc == 0) - if (ok) - p--; - else - return 0; - continue; - - case '*': - if (!*p) - return (1); - for (s--; *s; s++) - if (Gmatch(s, p)) - return (1); - return (0); - - case 0: - return (scc == 0); - - default: - if ((c & TRIM) != scc) - return (0); - continue; - - case '?': - if (scc == 0) - return (0); - continue; - - } - } -} -#endif /* Gmatch exclusion */ - static void Gcat(register char *s1, register char *s2) { register size_t len = strlen(s1) + strlen(s2) + 1; + if (globerr) + return; if (len >= gnleft || gargc >= GAVSIZ - 1) globerr = "Arguments too long"; + else if (len > MAXPATHLEN) + globerr = "Pathname too long"; else { gargc++; gnleft -= len; @@ -620,8 +576,10 @@ { register char **av = av0; - while (*av) - free(*av++); + if (av) { + while (*av) + free(*av++); + } } char *strspl(register char *cp, register char *dp)