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;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to