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)