Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jul 2016 16:06:21 +0000 (UTC)
From:      "Andrey A. Chernov" <ache@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r303004 - head/lib/libc/gen
Message-ID:  <201607181606.u6IG6LOd011643@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ache
Date: Mon Jul 18 16:06:21 2016
New Revision: 303004
URL: https://svnweb.freebsd.org/changeset/base/303004

Log:
  1) POSIX defines well when GLOB_ABORTED can be returned (only for directory
  open/read errors and with GLOB_ERR and gl_errfunc processing), so we can't
  blindly return it on any MAXPATHLEN overflow. Even our manpage disagrees
  with such GLOB_ABORTED usage. Use GLOB_NOSPACE for that now with errno is
  set to 0 as for limits.
  
  2) Return GLOB_NOSPACE when valid ~ expansion can't happens due to
  MAXPATHLEN overflow too.
  
  3) POSIX (and our manpage) says, if GLOB_ERR is set, GLOB_ABORTED should
  be returned immediatelly, without using gl_errfunc. Implement it now.

Modified:
  head/lib/libc/gen/glob.c

Modified: head/lib/libc/gen/glob.c
==============================================================================
--- head/lib/libc/gen/glob.c	Mon Jul 18 15:50:54 2016	(r303003)
+++ head/lib/libc/gen/glob.c	Mon Jul 18 16:06:21 2016	(r303004)
@@ -421,7 +421,7 @@ globtilde(const Char *pattern, Char *pat
 		continue;
 
 	if (*p != EOS && *p != SLASH)
-		return (pattern);
+		return (NULL);
 
 	*b = EOS;
 	h = NULL;
@@ -446,8 +446,9 @@ globtilde(const Char *pattern, Char *pat
 		/*
 		 * Expand a ~user
 		 */
-		if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf)) ||
-		    (pwd = getpwnam((char *)wbuf)) == NULL)
+		if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf)))
+			return (NULL);
+		if ((pwd = getpwnam((char *)wbuf)) == NULL)
 			return (pattern);
 		else
 			h = pwd->pw_dir;
@@ -474,13 +475,13 @@ globtilde(const Char *pattern, Char *pat
 		sc += clen;
 	}
 	if (too_long)
-		return (pattern);
+		return (NULL);
 
 	dc = wbuf;
 	for (b = patbuf; b < eb && *dc != EOS; *b++ = *dc++)
 		continue;
 	if (*dc != EOS)
-		return (pattern);
+		return (NULL);
 
 	/* Append the rest of the pattern */
 	if (*p != EOS) {
@@ -492,7 +493,7 @@ globtilde(const Char *pattern, Char *pat
 			}
 		}
 		if (too_long)
-			return (pattern);
+			return (NULL);
 	} else
 		*b = EOS;
 
@@ -515,6 +516,10 @@ glob0(const Char *pattern, glob_t *pglob
 	Char *bufnext, c, patbuf[MAXPATHLEN];
 
 	qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
+	if (qpatnext == NULL) {
+		errno = 0;
+		return (GLOB_NOSPACE);
+	}
 	oldpathc = pglob->gl_pathc;
 	bufnext = patbuf;
 
@@ -638,7 +643,7 @@ glob2(Char *pathbuf, Char *pathend, Char
 			    limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) {
 				errno = 0;
 				if (pathend + 1 > pathend_last)
-					return (GLOB_ABORTED);
+					return (GLOB_NOSPACE);
 				*pathend++ = SEP;
 				*pathend = EOS;
 				return (GLOB_NOSPACE);
@@ -648,8 +653,10 @@ glob2(Char *pathbuf, Char *pathend, Char
 			    || (S_ISLNK(sb.st_mode) &&
 			    (g_stat(pathbuf, &sb, pglob) == 0) &&
 			    S_ISDIR(sb.st_mode)))) {
-				if (pathend + 1 > pathend_last)
-					return (GLOB_ABORTED);
+				if (pathend + 1 > pathend_last) {
+					errno = 0;
+					return (GLOB_NOSPACE);
+				}
 				*pathend++ = SEP;
 				*pathend = EOS;
 			}
@@ -663,8 +670,10 @@ glob2(Char *pathbuf, Char *pathend, Char
 		while (*p != EOS && *p != SEP) {
 			if (ismeta(*p))
 				anymeta = 1;
-			if (q + 1 > pathend_last)
-				return (GLOB_ABORTED);
+			if (q + 1 > pathend_last) {
+				errno = 0;
+				return (GLOB_NOSPACE);
+			}
 			*q++ = *p++;
 		}
 
@@ -672,8 +681,10 @@ glob2(Char *pathbuf, Char *pathend, Char
 			pathend = q;
 			pattern = p;
 			while (*pattern == SEP) {
-				if (pathend + 1 > pathend_last)
-					return (GLOB_ABORTED);
+				if (pathend + 1 > pathend_last) {
+					errno = 0;
+					return (GLOB_NOSPACE);
+				}
 				*pathend++ = *pattern++;
 			}
 		} else			/* Need expansion, recurse. */
@@ -695,18 +706,21 @@ glob3(Char *pathbuf, Char *pathend, Char
 
 	struct dirent *(*readdirfunc)(DIR *);
 
+	errno = 0;
 	if (pathend > pathend_last)
-		return (GLOB_ABORTED);
+		return (GLOB_NOSPACE);
 	*pathend = EOS;
-	errno = 0;
 
 	if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
 		/* TODO: don't call for ENOENT or ENOTDIR? */
+		if (pglob->gl_flags & GLOB_ERR)
+			return (GLOB_ABORTED);
 		if (pglob->gl_errfunc) {
-			if (g_Ctoc(pathbuf, buf, sizeof(buf)))
-				return (GLOB_ABORTED);
-			if (pglob->gl_errfunc(buf, errno) ||
-			    pglob->gl_flags & GLOB_ERR)
+			if (g_Ctoc(pathbuf, buf, sizeof(buf))) {
+				errno = 0;
+				return (GLOB_NOSPACE);
+			}
+			if (pglob->gl_errfunc(buf, errno))
 				return (GLOB_ABORTED);
 		}
 		return (0);
@@ -732,7 +746,7 @@ glob3(Char *pathbuf, Char *pathend, Char
 		    limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) {
 			errno = 0;
 			if (pathend + 1 > pathend_last)
-				err = GLOB_ABORTED;
+				err = GLOB_NOSPACE;
 			else {
 				*pathend++ = SEP;
 				*pathend = EOS;
@@ -831,6 +845,7 @@ globextend(const Char *path, glob_t *pgl
 	if ((copy = malloc(len)) != NULL) {
 		if (g_Ctoc(path, copy, len)) {
 			free(copy);
+			errno = 0;
 			return (GLOB_NOSPACE);
 		}
 		pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607181606.u6IG6LOd011643>