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)
