bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/5] posix: Sync glob code with gnulib


From: Adhemerval Zanella
Subject: [PATCH 2/5] posix: Sync glob code with gnulib
Date: Wed, 30 Dec 2020 17:15:04 -0300

It sync with gnulib commit 43ee1a6bf and fixes and use-after-free
bug (gnulib commit 717766da8926e36).  The main change over gnulib
is:

--- posix/glob.c
+++ lib/glob.c
@@ -59,6 +59,12 @@
 # define readdir(str) __readdir64 (str)
 # define getpwnam_r(name, bufp, buf, len, res) \
     __getpwnam_r (name, bufp, buf, len, res)
+# ifndef __lstat64
+#  define __lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
+# endif
+# ifndef __stat64
+#  define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
+# endif
 # define struct_stat64          struct stat64
 # define FLEXIBLE_ARRAY_MEMBER
 # include <shlib-compat.h>

Which is required since xstat symbols are not used internally anymore.

Checked on x86_64-linux-gnu.
---
 posix/glob.c           | 1748 ++++++++++++++++++++--------------------
 posix/glob_pattern_p.c |    2 +-
 posix/globfree.c       |    2 +-
 3 files changed, 886 insertions(+), 866 deletions(-)

diff --git a/posix/glob.c b/posix/glob.c
index b4b34945e2..20239f780f 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -15,6 +15,16 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#ifndef _LIBC
+
+/* Don't use __attribute__ __nonnull__ in this compilation unit.  Otherwise gcc
+   optimizes away the pattern == NULL test below.  */
+# define _GL_ARG_NONNULL(params)
+
+# include <config.h>
+
+#endif
+
 #include <glob.h>
 
 #include <errno.h>
@@ -26,7 +36,7 @@
 #include <assert.h>
 #include <unistd.h>
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if defined _WIN32 && ! defined __CYGWIN__
 # define WINDOWS32
 #endif
 
@@ -49,14 +59,19 @@
 # define readdir(str) __readdir64 (str)
 # define getpwnam_r(name, bufp, buf, len, res) \
     __getpwnam_r (name, bufp, buf, len, res)
-# define struct_stat64         struct stat64
+# define struct_stat64          struct stat64
 # define FLEXIBLE_ARRAY_MEMBER
 # include <shlib-compat.h>
 #else /* !_LIBC */
 # define __glob                 glob
 # define __getlogin_r(buf, len) getlogin_r (buf, len)
 # define __lstat64(fname, buf)  lstat (fname, buf)
+# if defined _WIN32 && !defined __CYGWIN__
+   /* Avoid GCC or clang warning.  The original __stat64 macro is unused.  */
+#  undef __stat64
+# endif
 # define __stat64(fname, buf)   stat (fname, buf)
+# define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
 # define struct_stat64          struct stat
 # ifndef __MVS__
 #  define __alloca              alloca
@@ -73,7 +88,9 @@
 
 static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
 
-typedef uint_fast8_t dirent_type;
+/* The type of ((struct dirent *) 0)->d_type is 'unsigned char' on most
+   platforms, but 'unsigned int' in the mingw from mingw.org.  */
+typedef uint_fast32_t dirent_type;
 
 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
 /* Any distinct values will do here.
@@ -112,9 +129,9 @@ readdir_result_type (struct readdir_result d)
 /* Construct an initializer for a struct readdir_result object from a
    struct dirent *.  No copy of the name is made.  */
 #define READDIR_RESULT_INITIALIZER(source) \
-  {                                       \
-    source->d_name,                       \
-    D_TYPE_TO_RESULT (source)             \
+  {                                        \
+    source->d_name,                        \
+    D_TYPE_TO_RESULT (source)              \
   }
 
 /* Call gl_readdir on STREAM.  This macro can be overridden to reduce
@@ -204,7 +221,7 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname)
 static bool
 size_add_wrapv (size_t a, size_t b, size_t *r)
 {
-#if 5 <= __GNUC__ && !defined __ICC
+#if 7 <= __GNUC__ && !defined __ICC
   return __builtin_add_overflow (a, b, r);
 #else
   *r = a + b;
@@ -221,8 +238,8 @@ glob_use_alloca (size_t alloca_used, size_t len)
 }
 
 static int glob_in_dir (const char *pattern, const char *directory,
-                       int flags, int (*errfunc) (const char *, int),
-                       glob_t *pglob, size_t alloca_used);
+                        int flags, int (*errfunc) (const char *, int),
+                        glob_t *pglob, size_t alloca_used);
 static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
 static int collated_compare (const void *, const void *) __THROWNL;
 
@@ -247,17 +264,17 @@ next_brace_sub (const char *cp, int flags)
   while (*cp != '\0')
     if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
       {
-       if (*++cp == '\0')
-         break;
-       ++cp;
+        if (*++cp == '\0')
+          break;
+        ++cp;
       }
     else
       {
-       if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
-         break;
+        if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
+          break;
 
-       if (*cp++ == '{')
-         depth++;
+        if (*cp++ == '{')
+          depth++;
       }
 
   return *cp != '\0' ? cp : NULL;
@@ -278,7 +295,7 @@ next_brace_sub (const char *cp, int flags)
 int
 GLOB_ATTRIBUTE
 __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
-       glob_t *pglob)
+        glob_t *pglob)
 {
   const char *filename;
   char *dirname = NULL;
@@ -312,22 +329,22 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
     {
       pglob->gl_pathc = 0;
       if (!(flags & GLOB_DOOFFS))
-       pglob->gl_pathv = NULL;
+        pglob->gl_pathv = NULL;
       else
-       {
-         size_t i;
+        {
+          size_t i;
 
-         if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
-           return GLOB_NOSPACE;
+          if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
+            return GLOB_NOSPACE;
 
-         pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
-                                             * sizeof (char *));
-         if (pglob->gl_pathv == NULL)
-           return GLOB_NOSPACE;
+          pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
+                                              * sizeof (char *));
+          if (pglob->gl_pathv == NULL)
+            return GLOB_NOSPACE;
 
-         for (i = 0; i <= pglob->gl_offs; ++i)
-           pglob->gl_pathv[i] = NULL;
-       }
+          for (i = 0; i <= pglob->gl_offs; ++i)
+            pglob->gl_pathv[i] = NULL;
+        }
     }
 
   if (flags & GLOB_BRACE)
@@ -335,129 +352,129 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
       const char *begin;
 
       if (flags & GLOB_NOESCAPE)
-       begin = strchr (pattern, '{');
+        begin = strchr (pattern, '{');
       else
-       {
-         begin = pattern;
-         while (1)
-           {
-             if (*begin == '\0')
-               {
-                 begin = NULL;
-                 break;
-               }
-
-             if (*begin == '\\' && begin[1] != '\0')
-               ++begin;
-             else if (*begin == '{')
-               break;
-
-             ++begin;
-           }
-       }
+        {
+          begin = pattern;
+          while (1)
+            {
+              if (*begin == '\0')
+                {
+                  begin = NULL;
+                  break;
+                }
+
+              if (*begin == '\\' && begin[1] != '\0')
+                ++begin;
+              else if (*begin == '{')
+                break;
+
+              ++begin;
+            }
+        }
 
       if (begin != NULL)
-       {
-         /* Allocate working buffer large enough for our work.  Note that
-           we have at least an opening and closing brace.  */
-         size_t firstc;
-         char *alt_start;
-         const char *p;
-         const char *next;
-         const char *rest;
-         size_t rest_len;
-         char *onealt;
-         size_t pattern_len = strlen (pattern) - 1;
-         int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
-         if (alloca_onealt)
-           onealt = alloca_account (pattern_len, alloca_used);
-         else
-           {
-             onealt = malloc (pattern_len);
-             if (onealt == NULL)
-               return GLOB_NOSPACE;
-           }
-
-         /* We know the prefix for all sub-patterns.  */
-         alt_start = mempcpy (onealt, pattern, begin - pattern);
-
-         /* Find the first sub-pattern and at the same time find the
-            rest after the closing brace.  */
-         next = next_brace_sub (begin + 1, flags);
-         if (next == NULL)
-           {
-             /* It is an invalid expression.  */
-           illegal_brace:
-             if (__glibc_unlikely (!alloca_onealt))
-               free (onealt);
-             flags &= ~GLOB_BRACE;
-             goto no_brace;
-           }
-
-         /* Now find the end of the whole brace expression.  */
-         rest = next;
-         while (*rest != '}')
-           {
-             rest = next_brace_sub (rest + 1, flags);
-             if (rest == NULL)
-               /* It is an illegal expression.  */
-               goto illegal_brace;
-           }
-         /* Please note that we now can be sure the brace expression
-            is well-formed.  */
-         rest_len = strlen (++rest) + 1;
-
-         /* We have a brace expression.  BEGIN points to the opening {,
-            NEXT points past the terminator of the first element, and END
-            points past the final }.  We will accumulate result names from
-            recursive runs for each brace alternative in the buffer using
-            GLOB_APPEND.  */
-         firstc = pglob->gl_pathc;
-
-         p = begin + 1;
-         while (1)
-           {
-             int result;
-
-             /* Construct the new glob expression.  */
-             mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
-
-             result = __glob (onealt,
-                              ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
-                               | GLOB_APPEND),
-                              errfunc, pglob);
-
-             /* If we got an error, return it.  */
-             if (result && result != GLOB_NOMATCH)
-               {
-                 if (__glibc_unlikely (!alloca_onealt))
-                   free (onealt);
-                 if (!(flags & GLOB_APPEND))
-                   {
-                     globfree (pglob);
-                     pglob->gl_pathc = 0;
-                   }
-                 return result;
-               }
-
-             if (*next == '}')
-               /* We saw the last entry.  */
-               break;
-
-             p = next + 1;
-             next = next_brace_sub (p, flags);
-             assert (next != NULL);
-           }
-
-         if (__glibc_unlikely (!alloca_onealt))
-           free (onealt);
-
-         if (pglob->gl_pathc != firstc)
-           /* We found some entries.  */
-           return 0;
-         else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
-           return GLOB_NOMATCH;
-       }
+        {
+          /* Allocate working buffer large enough for our work.  Note that
+             we have at least an opening and closing brace.  */
+          size_t firstc;
+          char *alt_start;
+          const char *p;
+          const char *next;
+          const char *rest;
+          size_t rest_len;
+          char *onealt;
+          size_t pattern_len = strlen (pattern) - 1;
+          int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
+          if (alloca_onealt)
+            onealt = alloca_account (pattern_len, alloca_used);
+          else
+            {
+              onealt = malloc (pattern_len);
+              if (onealt == NULL)
+                return GLOB_NOSPACE;
+            }
+
+          /* We know the prefix for all sub-patterns.  */
+          alt_start = mempcpy (onealt, pattern, begin - pattern);
+
+          /* Find the first sub-pattern and at the same time find the
+             rest after the closing brace.  */
+          next = next_brace_sub (begin + 1, flags);
+          if (next == NULL)
+            {
+              /* It is an invalid expression.  */
+            illegal_brace:
+              if (__glibc_unlikely (!alloca_onealt))
+                free (onealt);
+              flags &= ~GLOB_BRACE;
+              goto no_brace;
+            }
+
+          /* Now find the end of the whole brace expression.  */
+          rest = next;
+          while (*rest != '}')
+            {
+              rest = next_brace_sub (rest + 1, flags);
+              if (rest == NULL)
+                /* It is an illegal expression.  */
+                goto illegal_brace;
+            }
+          /* Please note that we now can be sure the brace expression
+             is well-formed.  */
+          rest_len = strlen (++rest) + 1;
+
+          /* We have a brace expression.  BEGIN points to the opening {,
+             NEXT points past the terminator of the first element, and END
+             points past the final }.  We will accumulate result names from
+             recursive runs for each brace alternative in the buffer using
+             GLOB_APPEND.  */
+          firstc = pglob->gl_pathc;
+
+          p = begin + 1;
+          while (1)
+            {
+              int result;
+
+              /* Construct the new glob expression.  */
+              mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
+
+              result = __glob (onealt,
+                               ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
+                                | GLOB_APPEND),
+                               errfunc, pglob);
+
+              /* If we got an error, return it.  */
+              if (result && result != GLOB_NOMATCH)
+                {
+                  if (__glibc_unlikely (!alloca_onealt))
+                    free (onealt);
+                  if (!(flags & GLOB_APPEND))
+                    {
+                      globfree (pglob);
+                      pglob->gl_pathc = 0;
+                    }
+                  return result;
+                }
+
+              if (*next == '}')
+                /* We saw the last entry.  */
+                break;
+
+              p = next + 1;
+              next = next_brace_sub (p, flags);
+              assert (next != NULL);
+            }
+
+          if (__glibc_unlikely (!alloca_onealt))
+            free (onealt);
+
+          if (pglob->gl_pathc != firstc)
+            /* We found some entries.  */
+            return 0;
+          else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
+            return GLOB_NOMATCH;
+        }
     }
 
  no_brace:
@@ -479,33 +496,33 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
   if (filename == NULL)
     {
       /* This can mean two things: a simple name or "~name".  The latter
-        case is nothing but a notation for a directory.  */
+         case is nothing but a notation for a directory.  */
       if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
-       {
-         dirname = (char *) pattern;
-         dirlen = strlen (pattern);
-
-         /* Set FILENAME to NULL as a special flag.  This is ugly but
-            other solutions would require much more code.  We test for
-            this special case below.  */
-         filename = NULL;
-       }
+        {
+          dirname = (char *) pattern;
+          dirlen = strlen (pattern);
+
+          /* Set FILENAME to NULL as a special flag.  This is ugly but
+             other solutions would require much more code.  We test for
+             this special case below.  */
+          filename = NULL;
+        }
       else
-       {
-         if (__glibc_unlikely (pattern[0] == '\0'))
-           {
-             dirs.gl_pathv = NULL;
-             goto no_matches;
-           }
-
-         filename = pattern;
-         dirname = (char *) ".";
-         dirlen = 0;
-       }
+        {
+          if (__glibc_unlikely (pattern[0] == '\0'))
+            {
+              dirs.gl_pathv = NULL;
+              goto no_matches;
+            }
+
+          filename = pattern;
+          dirname = (char *) ".";
+          dirlen = 0;
+        }
     }
   else if (filename == pattern
-          || (filename == pattern + 1 && pattern[0] == '\\'
-              && (flags & GLOB_NOESCAPE) == 0))
+           || (filename == pattern + 1 && pattern[0] == '\\'
+               && (flags & GLOB_NOESCAPE) == 0))
     {
       /* "/pattern" or "\\/pattern".  */
       dirname = (char *) "/";
@@ -518,32 +535,32 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
       dirlen = filename - pattern;
 #if defined __MSDOS__ || defined WINDOWS32
       if (*filename == ':'
-         || (filename > pattern + 1 && filename[-1] == ':'))
-       {
-         char *drive_spec;
-
-         ++dirlen;
-         drive_spec = __alloca (dirlen + 1);
-         *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
-         /* For now, disallow wildcards in the drive spec, to
-            prevent infinite recursion in glob.  */
-         if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
-           return GLOB_NOMATCH;
-         /* If this is "d:pattern", we need to copy ':' to DIRNAME
-            as well.  If it's "d:/pattern", don't remove the slash
-            from "d:/", since "d:" and "d:/" are not the same.*/
-       }
+          || (filename > pattern + 1 && filename[-1] == ':'))
+        {
+          char *drive_spec;
+
+          ++dirlen;
+          drive_spec = __alloca (dirlen + 1);
+          *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
+          /* For now, disallow wildcards in the drive spec, to
+             prevent infinite recursion in glob.  */
+          if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
+            return GLOB_NOMATCH;
+          /* If this is "d:pattern", we need to copy ':' to DIRNAME
+             as well.  If it's "d:/pattern", don't remove the slash
+             from "d:/", since "d:" and "d:/" are not the same.*/
+        }
 #endif
 
       if (glob_use_alloca (alloca_used, dirlen + 1))
-       newp = alloca_account (dirlen + 1, alloca_used);
+        newp = alloca_account (dirlen + 1, alloca_used);
       else
-       {
-         newp = malloc (dirlen + 1);
-         if (newp == NULL)
-           return GLOB_NOSPACE;
-         malloc_dirname = 1;
-       }
+        {
+          newp = malloc (dirlen + 1);
+          if (newp == NULL)
+            return GLOB_NOSPACE;
+          malloc_dirname = 1;
+        }
       *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
       dirname = newp;
       ++filename;
@@ -559,363 +576,366 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
 
       if (filename[0] == '\0' && dirlen > 1 && !drive_root)
         /* "pattern/".  Expand "pattern", appending slashes.  */
-       {
-         int orig_flags = flags;
-         if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
-           {
-             /* "pattern\\/".  Remove the final backslash if it hasn't
-                been quoted.  */
-             char *p = (char *) &dirname[dirlen - 1];
-
-             while (p > dirname && p[-1] == '\\') --p;
-             if ((&dirname[dirlen] - p) & 1)
-               {
-                 *(char *) &dirname[--dirlen] = '\0';
-                 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
-               }
-           }
-         int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob);
-         if (val == 0)
-           pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
-                              | (flags & GLOB_MARK));
-         else if (val == GLOB_NOMATCH && flags != orig_flags)
-           {
-             /* Make sure globfree (&dirs); is a nop.  */
-             dirs.gl_pathv = NULL;
-             flags = orig_flags;
-             oldcount = pglob->gl_pathc + pglob->gl_offs;
-             goto no_matches;
-           }
-         retval = val;
-         goto out;
-       }
+        {
+          int orig_flags = flags;
+          if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
+            {
+              /* "pattern\\/".  Remove the final backslash if it hasn't
+                 been quoted.  */
+              char *p = (char *) &dirname[dirlen - 1];
+
+              while (p > dirname && p[-1] == '\\') --p;
+              if ((&dirname[dirlen] - p) & 1)
+                {
+                  *(char *) &dirname[--dirlen] = '\0';
+                  flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
+                }
+            }
+          int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob);
+          if (val == 0)
+            pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
+                               | (flags & GLOB_MARK));
+          else if (val == GLOB_NOMATCH && flags != orig_flags)
+            {
+              /* Make sure globfree (&dirs); is a nop.  */
+              dirs.gl_pathv = NULL;
+              flags = orig_flags;
+              oldcount = pglob->gl_pathc + pglob->gl_offs;
+              goto no_matches;
+            }
+          retval = val;
+          goto out;
+        }
     }
 
   if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
     {
       if (dirname[1] == '\0' || dirname[1] == '/'
-         || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
-             && (dirname[2] == '\0' || dirname[2] == '/')))
-       {
-         /* Look up home directory.  */
-         char *home_dir = getenv ("HOME");
-         int malloc_home_dir = 0;
-         if (home_dir == NULL || home_dir[0] == '\0')
-           {
+          || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
+              && (dirname[2] == '\0' || dirname[2] == '/')))
+        {
+          /* Look up home directory.  */
+          char *home_dir = getenv ("HOME");
+          int malloc_home_dir = 0;
+          if (home_dir == NULL || home_dir[0] == '\0')
+            {
 #ifdef WINDOWS32
-             /* Windows NT defines HOMEDRIVE and HOMEPATH.  But give
-                preference to HOME, because the user can change HOME.  */
-             const char *home_drive = getenv ("HOMEDRIVE");
-             const char *home_path = getenv ("HOMEPATH");
-
-             if (home_drive != NULL && home_path != NULL)
-               {
-                 size_t home_drive_len = strlen (home_drive);
-                 size_t home_path_len = strlen (home_path);
-                 char *mem = alloca (home_drive_len + home_path_len + 1);
-
-                 memcpy (mem, home_drive, home_drive_len);
-                 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
-                 home_dir = mem;
-               }
-             else
-               home_dir = "c:/users/default"; /* poor default */
+              /* Windows NT defines HOMEDRIVE and HOMEPATH.  But give
+                 preference to HOME, because the user can change HOME.  */
+              const char *home_drive = getenv ("HOMEDRIVE");
+              const char *home_path = getenv ("HOMEPATH");
+
+              if (home_drive != NULL && home_path != NULL)
+                {
+                  size_t home_drive_len = strlen (home_drive);
+                  size_t home_path_len = strlen (home_path);
+                  char *mem = alloca (home_drive_len + home_path_len + 1);
+
+                  memcpy (mem, home_drive, home_drive_len);
+                  memcpy (mem + home_drive_len, home_path, home_path_len + 1);
+                  home_dir = mem;
+                }
+              else
+                home_dir = "c:/users/default"; /* poor default */
 #else
-             int err;
-             struct passwd *p;
-             struct passwd pwbuf;
-             struct scratch_buffer s;
-             scratch_buffer_init (&s);
-             while (true)
-               {
-                 p = NULL;
-                 err = __getlogin_r (s.data, s.length);
-                 if (err == 0)
-                   {
+              int err;
+              struct passwd *p;
+              struct passwd pwbuf;
+              struct scratch_buffer s;
+              scratch_buffer_init (&s);
+              while (true)
+                {
+                  p = NULL;
+                  err = __getlogin_r (s.data, s.length);
+                  if (err == 0)
+                    {
 # if defined HAVE_GETPWNAM_R || defined _LIBC
-                     size_t ssize = strlen (s.data) + 1;
-                     char *sdata = s.data;
-                     err = getpwnam_r (sdata, &pwbuf, sdata + ssize,
-                                       s.length - ssize, &p);
+                      size_t ssize = strlen (s.data) + 1;
+                      char *sdata = s.data;
+                      err = getpwnam_r (sdata, &pwbuf, sdata + ssize,
+                                        s.length - ssize, &p);
 # else
-                     p = getpwnam (s.data);
-                     if (p == NULL)
-                       err = errno;
+                      p = getpwnam (s.data);
+                      if (p == NULL)
+                        err = errno;
 # endif
-                   }
-                 if (err != ERANGE)
-                   break;
-                 if (!scratch_buffer_grow (&s))
-                   {
-                     retval = GLOB_NOSPACE;
-                     goto out;
-                   }
-               }
-             if (err == 0)
-               {
-                 home_dir = strdup (p->pw_dir);
-                 malloc_home_dir = 1;
-               }
-             scratch_buffer_free (&s);
-             if (err == 0 && home_dir == NULL)
-               {
-                 retval = GLOB_NOSPACE;
-                 goto out;
-               }
+                    }
+                  if (err != ERANGE)
+                    break;
+                  if (!scratch_buffer_grow (&s))
+                    {
+                      retval = GLOB_NOSPACE;
+                      goto out;
+                    }
+                }
+              if (err == 0)
+                {
+                  home_dir = strdup (p->pw_dir);
+                  malloc_home_dir = 1;
+                }
+              scratch_buffer_free (&s);
+              if (err == 0 && home_dir == NULL)
+                {
+                  retval = GLOB_NOSPACE;
+                  goto out;
+                }
 #endif /* WINDOWS32 */
-           }
-         if (home_dir == NULL || home_dir[0] == '\0')
-           {
-             if (__glibc_unlikely (malloc_home_dir))
-               free (home_dir);
-             if (flags & GLOB_TILDE_CHECK)
-               {
-                 retval = GLOB_NOMATCH;
-                 goto out;
-               }
-             else
-               {
-                 home_dir = (char *) "~"; /* No luck.  */
-                 malloc_home_dir = 0;
-               }
-           }
-         /* Now construct the full directory.  */
-         if (dirname[1] == '\0')
-           {
-             if (__glibc_unlikely (malloc_dirname))
-               free (dirname);
-
-             dirname = home_dir;
-             dirlen = strlen (dirname);
-             malloc_dirname = malloc_home_dir;
-           }
-         else
-           {
-             char *newp;
-             size_t home_len = strlen (home_dir);
-             int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
-             if (use_alloca)
-               newp = alloca_account (home_len + dirlen, alloca_used);
-             else
-               {
-                 newp = malloc (home_len + dirlen);
-                 if (newp == NULL)
-                   {
-                     if (__glibc_unlikely (malloc_home_dir))
-                       free (home_dir);
-                     retval = GLOB_NOSPACE;
-                     goto out;
-                   }
-               }
-
-             mempcpy (mempcpy (newp, home_dir, home_len),
-                      &dirname[1], dirlen);
-
-             if (__glibc_unlikely (malloc_dirname))
-               free (dirname);
-
-             dirname = newp;
-             dirlen += home_len - 1;
-             malloc_dirname = !use_alloca;
-
-             if (__glibc_unlikely (malloc_home_dir))
-               free (home_dir);
-           }
-         dirname_modified = 1;
-       }
+            }
+          if (home_dir == NULL || home_dir[0] == '\0')
+            {
+              if (__glibc_unlikely (malloc_home_dir))
+                free (home_dir);
+              if (flags & GLOB_TILDE_CHECK)
+                {
+                  retval = GLOB_NOMATCH;
+                  goto out;
+                }
+              else
+                {
+                  home_dir = (char *) "~"; /* No luck.  */
+                  malloc_home_dir = 0;
+                }
+            }
+          /* Now construct the full directory.  */
+          if (dirname[1] == '\0')
+            {
+              if (__glibc_unlikely (malloc_dirname))
+                free (dirname);
+
+              dirname = home_dir;
+              dirlen = strlen (dirname);
+              malloc_dirname = malloc_home_dir;
+            }
+          else
+            {
+              char *newp;
+              size_t home_len = strlen (home_dir);
+              int use_alloca = glob_use_alloca (alloca_used, home_len + 
dirlen);
+              if (use_alloca)
+                newp = alloca_account (home_len + dirlen, alloca_used);
+              else
+                {
+                  newp = malloc (home_len + dirlen);
+                  if (newp == NULL)
+                    {
+                      if (__glibc_unlikely (malloc_home_dir))
+                        free (home_dir);
+                      retval = GLOB_NOSPACE;
+                      goto out;
+                    }
+                }
+
+              mempcpy (mempcpy (newp, home_dir, home_len),
+                       &dirname[1], dirlen);
+
+              if (__glibc_unlikely (malloc_dirname))
+                free (dirname);
+
+              dirname = newp;
+              dirlen += home_len - 1;
+              malloc_dirname = !use_alloca;
+
+              if (__glibc_unlikely (malloc_home_dir))
+                free (home_dir);
+            }
+          dirname_modified = 1;
+        }
       else
-       {
+        {
 #ifndef WINDOWS32
-         char *end_name = strchr (dirname, '/');
-         char *user_name;
-         int malloc_user_name = 0;
-         char *unescape = NULL;
-
-         if (!(flags & GLOB_NOESCAPE))
-           {
-             if (end_name == NULL)
-               {
-                 unescape = strchr (dirname, '\\');
-                 if (unescape)
-                   end_name = strchr (unescape, '\0');
-               }
-             else
-               unescape = memchr (dirname, '\\', end_name - dirname);
-           }
-         if (end_name == NULL)
-           user_name = dirname + 1;
-         else
-           {
-             char *newp;
-             if (glob_use_alloca (alloca_used, end_name - dirname))
-               newp = alloca_account (end_name - dirname, alloca_used);
-             else
-               {
-                 newp = malloc (end_name - dirname);
-                 if (newp == NULL)
-                   {
-                     retval = GLOB_NOSPACE;
-                     goto out;
-                   }
-                 malloc_user_name = 1;
-               }
-             if (unescape != NULL)
-               {
-                 char *p = mempcpy (newp, dirname + 1,
-                                    unescape - dirname - 1);
-                 char *q = unescape;
-                 while (q != end_name)
-                   {
-                     if (*q == '\\')
-                       {
-                         if (q + 1 == end_name)
-                           {
-                             /* "~fo\\o\\" unescape to user_name "foo\\",
-                                but "~fo\\o\\/" unescape to user_name
-                                "foo".  */
-                             if (filename == NULL)
-                               *p++ = '\\';
-                             break;
-                           }
-                         ++q;
-                       }
-                     *p++ = *q++;
-                   }
-                 *p = '\0';
-               }
-             else
-               *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
-                 = '\0';
-             user_name = newp;
-           }
-
-         /* Look up specific user's home directory.  */
-         {
-           struct passwd *p;
-           struct scratch_buffer pwtmpbuf;
-           scratch_buffer_init (&pwtmpbuf);
+          char *end_name = strchr (dirname, '/');
+          char *user_name;
+          int malloc_user_name = 0;
+          char *unescape = NULL;
+
+          if (!(flags & GLOB_NOESCAPE))
+            {
+              if (end_name == NULL)
+                {
+                  unescape = strchr (dirname, '\\');
+                  if (unescape)
+                    end_name = strchr (unescape, '\0');
+                }
+              else
+                unescape = memchr (dirname, '\\', end_name - dirname);
+            }
+          if (end_name == NULL)
+            user_name = dirname + 1;
+          else
+            {
+              char *newp;
+              if (glob_use_alloca (alloca_used, end_name - dirname))
+                newp = alloca_account (end_name - dirname, alloca_used);
+              else
+                {
+                  newp = malloc (end_name - dirname);
+                  if (newp == NULL)
+                    {
+                      retval = GLOB_NOSPACE;
+                      goto out;
+                    }
+                  malloc_user_name = 1;
+                }
+              if (unescape != NULL)
+                {
+                  char *p = mempcpy (newp, dirname + 1,
+                                     unescape - dirname - 1);
+                  char *q = unescape;
+                  while (q != end_name)
+                    {
+                      if (*q == '\\')
+                        {
+                          if (q + 1 == end_name)
+                            {
+                              /* "~fo\\o\\" unescape to user_name "foo\\",
+                                 but "~fo\\o\\/" unescape to user_name
+                                 "foo".  */
+                              if (filename == NULL)
+                                *p++ = '\\';
+                              break;
+                            }
+                          ++q;
+                        }
+                      *p++ = *q++;
+                    }
+                  *p = '\0';
+                }
+              else
+                *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
+                  = '\0';
+              user_name = newp;
+            }
+
+          /* Look up specific user's home directory.  */
+          {
+            struct passwd *p;
+            struct scratch_buffer pwtmpbuf;
+            scratch_buffer_init (&pwtmpbuf);
 
 #  if defined HAVE_GETPWNAM_R || defined _LIBC
-           struct passwd pwbuf;
-
-           while (getpwnam_r (user_name, &pwbuf,
-                              pwtmpbuf.data, pwtmpbuf.length, &p)
-                  == ERANGE)
-             {
-               if (!scratch_buffer_grow (&pwtmpbuf))
-                 {
-                   retval = GLOB_NOSPACE;
-                   goto out;
-                 }
-             }
+            struct passwd pwbuf;
+
+            while (getpwnam_r (user_name, &pwbuf,
+                               pwtmpbuf.data, pwtmpbuf.length, &p)
+                   == ERANGE)
+              {
+                if (!scratch_buffer_grow (&pwtmpbuf))
+                  {
+                    retval = GLOB_NOSPACE;
+                    goto out;
+                  }
+              }
 #  else
-           p = getpwnam (user_name);
+            p = getpwnam (user_name);
 #  endif
 
-           if (__glibc_unlikely (malloc_user_name))
-             free (user_name);
-
-           /* If we found a home directory use this.  */
-           if (p != NULL)
-             {
-               size_t home_len = strlen (p->pw_dir);
-               size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
-               char *d, *newp;
-               bool use_alloca = glob_use_alloca (alloca_used,
-                                                  home_len + rest_len + 1);
-
-               if (use_alloca)
-                 newp = alloca_account (home_len + rest_len + 1, alloca_used);
-               else
-                 {
-                   newp = malloc (home_len + rest_len + 1);
-                   if (newp == NULL)
-                     {
-                       scratch_buffer_free (&pwtmpbuf);
-                       retval = GLOB_NOSPACE;
-                       goto out;
-                     }
-                 }
-               d = mempcpy (newp, p->pw_dir, home_len);
-               if (end_name != NULL)
-                 d = mempcpy (d, end_name, rest_len);
-               *d = '\0';
-
-               if (__glibc_unlikely (malloc_dirname))
-                 free (dirname);
-               dirname = newp;
-               malloc_dirname = !use_alloca;
-
-               dirlen = home_len + rest_len;
-               dirname_modified = 1;
-             }
-           else
-             {
-               if (flags & GLOB_TILDE_CHECK)
-                 {
-                   /* We have to regard it as an error if we cannot find the
-                      home directory.  */
-                   retval = GLOB_NOMATCH;
-                   goto out;
-                 }
-             }
-           scratch_buffer_free (&pwtmpbuf);
-         }
+            if (__glibc_unlikely (malloc_user_name))
+              free (user_name);
+
+            /* If we found a home directory use this.  */
+            if (p != NULL)
+              {
+                size_t home_len = strlen (p->pw_dir);
+                size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
+                /* dirname contains end_name; we can't free it now.  */
+                char *prev_dirname =
+                  (__glibc_unlikely (malloc_dirname) ? dirname : NULL);
+                char *d;
+
+                malloc_dirname = 0;
+
+                if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
+                  dirname = alloca_account (home_len + rest_len + 1,
+                                            alloca_used);
+                else
+                  {
+                    dirname = malloc (home_len + rest_len + 1);
+                    if (dirname == NULL)
+                      {
+                        free (prev_dirname);
+                        scratch_buffer_free (&pwtmpbuf);
+                        retval = GLOB_NOSPACE;
+                        goto out;
+                      }
+                    malloc_dirname = 1;
+                  }
+                d = mempcpy (dirname, p->pw_dir, home_len);
+                if (end_name != NULL)
+                  d = mempcpy (d, end_name, rest_len);
+                *d = '\0';
+
+                free (prev_dirname);
+
+                dirlen = home_len + rest_len;
+                dirname_modified = 1;
+              }
+            else
+              {
+                if (flags & GLOB_TILDE_CHECK)
+                  {
+                    /* We have to regard it as an error if we cannot find the
+                       home directory.  */
+                    retval = GLOB_NOMATCH;
+                    goto out;
+                  }
+              }
+            scratch_buffer_free (&pwtmpbuf);
+          }
 #endif /* !WINDOWS32 */
-       }
+        }
     }
 
   /* Now test whether we looked for "~" or "~NAME".  In this case we
      can give the answer now.  */
   if (filename == NULL)
     {
-       size_t newcount = pglob->gl_pathc + pglob->gl_offs;
-       char **new_gl_pathv;
-
-       if (newcount > SIZE_MAX / sizeof (char *) - 2)
-         {
-         nospace:
-           free (pglob->gl_pathv);
-           pglob->gl_pathv = NULL;
-           pglob->gl_pathc = 0;
-           retval = GLOB_NOSPACE;
-           goto out;
-         }
-
-       new_gl_pathv = realloc (pglob->gl_pathv,
-                               (newcount + 2) * sizeof (char *));
-       if (new_gl_pathv == NULL)
-         goto nospace;
-       pglob->gl_pathv = new_gl_pathv;
-
-       if (flags & GLOB_MARK && is_dir (dirname, flags, pglob))
-         {
-           char *p;
-           pglob->gl_pathv[newcount] = malloc (dirlen + 2);
-           if (pglob->gl_pathv[newcount] == NULL)
-             goto nospace;
-           p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
-           p[0] = '/';
-           p[1] = '\0';
-           if (__glibc_unlikely (malloc_dirname))
-             free (dirname);
-         }
-       else
-         {
-           if (__glibc_unlikely (malloc_dirname))
-             pglob->gl_pathv[newcount] = dirname;
-           else
-             {
-               pglob->gl_pathv[newcount] = strdup (dirname);
-               if (pglob->gl_pathv[newcount] == NULL)
-                 goto nospace;
-             }
-         }
-       pglob->gl_pathv[++newcount] = NULL;
-       ++pglob->gl_pathc;
-       pglob->gl_flags = flags;
-
-       return 0;
+      size_t newcount = pglob->gl_pathc + pglob->gl_offs;
+      char **new_gl_pathv;
+
+      if (newcount > SIZE_MAX / sizeof (char *) - 2)
+        {
+        nospace:
+          free (pglob->gl_pathv);
+          pglob->gl_pathv = NULL;
+          pglob->gl_pathc = 0;
+          retval = GLOB_NOSPACE;
+          goto out;
+        }
+
+      new_gl_pathv = realloc (pglob->gl_pathv,
+                              (newcount + 2) * sizeof (char *));
+      if (new_gl_pathv == NULL)
+        goto nospace;
+      pglob->gl_pathv = new_gl_pathv;
+
+      if (flags & GLOB_MARK && is_dir (dirname, flags, pglob))
+        {
+          char *p;
+          pglob->gl_pathv[newcount] = malloc (dirlen + 2);
+          if (pglob->gl_pathv[newcount] == NULL)
+            goto nospace;
+          p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
+          p[0] = '/';
+          p[1] = '\0';
+          if (__glibc_unlikely (malloc_dirname))
+            free (dirname);
+        }
+      else
+        {
+          if (__glibc_unlikely (malloc_dirname))
+            pglob->gl_pathv[newcount] = dirname;
+          else
+            {
+              pglob->gl_pathv[newcount] = strdup (dirname);
+              if (pglob->gl_pathv[newcount] == NULL)
+                goto nospace;
+            }
+        }
+      pglob->gl_pathv[++newcount] = NULL;
+      ++pglob->gl_pathc;
+      pglob->gl_flags = flags;
+
+      return 0;
     }
 
   meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
@@ -927,135 +947,135 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
   if (meta & (GLOBPAT_SPECIAL | GLOBPAT_BRACKET))
     {
       /* The directory name contains metacharacters, so we
-        have to glob for the directory, and then glob for
-        the pattern in each directory found.  */
+         have to glob for the directory, and then glob for
+         the pattern in each directory found.  */
       size_t i;
 
       if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == 
'\\')
-       {
-         /* "foo\\/bar".  Remove the final backslash from dirname
-            if it has not been quoted.  */
-         char *p = (char *) &dirname[dirlen - 1];
+        {
+          /* "foo\\/bar".  Remove the final backslash from dirname
+             if it has not been quoted.  */
+          char *p = (char *) &dirname[dirlen - 1];
 
-         while (p > dirname && p[-1] == '\\') --p;
-         if ((&dirname[dirlen] - p) & 1)
-           *(char *) &dirname[--dirlen] = '\0';
-       }
+          while (p > dirname && p[-1] == '\\') --p;
+          if ((&dirname[dirlen] - p) & 1)
+            *(char *) &dirname[--dirlen] = '\0';
+        }
 
       if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
-       {
-         /* Use the alternative access functions also in the recursive
-            call.  */
-         dirs.gl_opendir = pglob->gl_opendir;
-         dirs.gl_readdir = pglob->gl_readdir;
-         dirs.gl_closedir = pglob->gl_closedir;
-         dirs.gl_stat = pglob->gl_stat;
-         dirs.gl_lstat = pglob->gl_lstat;
-       }
+        {
+          /* Use the alternative access functions also in the recursive
+             call.  */
+          dirs.gl_opendir = pglob->gl_opendir;
+          dirs.gl_readdir = pglob->gl_readdir;
+          dirs.gl_closedir = pglob->gl_closedir;
+          dirs.gl_stat = pglob->gl_stat;
+          dirs.gl_lstat = pglob->gl_lstat;
+        }
 
       status = __glob (dirname,
-                      ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
-                       | GLOB_NOSORT | GLOB_ONLYDIR),
-                      errfunc, &dirs);
+                       ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
+                        | GLOB_NOSORT | GLOB_ONLYDIR),
+                       errfunc, &dirs);
       if (status != 0)
-       {
-         if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
-           {
-             retval = status;
-             goto out;
-           }
-         goto no_matches;
-       }
+        {
+          if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
+            {
+              retval = status;
+              goto out;
+            }
+          goto no_matches;
+        }
 
       /* We have successfully globbed the preceding directory name.
-        For each name we found, call glob_in_dir on it and FILENAME,
-        appending the results to PGLOB.  */
+         For each name we found, call glob_in_dir on it and FILENAME,
+         appending the results to PGLOB.  */
       for (i = 0; i < dirs.gl_pathc; ++i)
-       {
-         size_t old_pathc;
-
-         old_pathc = pglob->gl_pathc;
-         status = glob_in_dir (filename, dirs.gl_pathv[i],
-                               ((flags | GLOB_APPEND)
-                                & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
-                               errfunc, pglob, alloca_used);
-         if (status == GLOB_NOMATCH)
-           /* No matches in this directory.  Try the next.  */
-           continue;
-
-         if (status != 0)
-           {
-             globfree (&dirs);
-             globfree (pglob);
-             pglob->gl_pathc = 0;
-             retval = status;
-             goto out;
-           }
-
-         /* Stick the directory on the front of each name.  */
-         if (prefix_array (dirs.gl_pathv[i],
-                           &pglob->gl_pathv[old_pathc + pglob->gl_offs],
-                           pglob->gl_pathc - old_pathc))
-           {
-             globfree (&dirs);
-             globfree (pglob);
-             pglob->gl_pathc = 0;
-             retval = GLOB_NOSPACE;
-             goto out;
-           }
-       }
+        {
+          size_t old_pathc;
+
+          old_pathc = pglob->gl_pathc;
+          status = glob_in_dir (filename, dirs.gl_pathv[i],
+                                ((flags | GLOB_APPEND)
+                                 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
+                                errfunc, pglob, alloca_used);
+          if (status == GLOB_NOMATCH)
+            /* No matches in this directory.  Try the next.  */
+            continue;
+
+          if (status != 0)
+            {
+              globfree (&dirs);
+              globfree (pglob);
+              pglob->gl_pathc = 0;
+              retval = status;
+              goto out;
+            }
+
+          /* Stick the directory on the front of each name.  */
+          if (prefix_array (dirs.gl_pathv[i],
+                            &pglob->gl_pathv[old_pathc + pglob->gl_offs],
+                            pglob->gl_pathc - old_pathc))
+            {
+              globfree (&dirs);
+              globfree (pglob);
+              pglob->gl_pathc = 0;
+              retval = GLOB_NOSPACE;
+              goto out;
+            }
+        }
 
       flags |= GLOB_MAGCHAR;
 
       /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
-        But if we have not found any matching entry and the GLOB_NOCHECK
-        flag was set we must return the input pattern itself.  */
+         But if we have not found any matching entry and the GLOB_NOCHECK
+         flag was set we must return the input pattern itself.  */
       if (pglob->gl_pathc + pglob->gl_offs == oldcount)
-       {
-       no_matches:
-         /* No matches.  */
-         if (flags & GLOB_NOCHECK)
-           {
-             size_t newcount = pglob->gl_pathc + pglob->gl_offs;
-             char **new_gl_pathv;
-
-             if (newcount > SIZE_MAX / sizeof (char *) - 2)
-               {
-               nospace2:
-                 globfree (&dirs);
-                 retval = GLOB_NOSPACE;
-                 goto out;
-               }
-
-             new_gl_pathv = realloc (pglob->gl_pathv,
-                                     (newcount + 2) * sizeof (char *));
-             if (new_gl_pathv == NULL)
-               goto nospace2;
-             pglob->gl_pathv = new_gl_pathv;
-
-             pglob->gl_pathv[newcount] = strdup (pattern);
-             if (pglob->gl_pathv[newcount] == NULL)
-               {
-                 globfree (&dirs);
-                 globfree (pglob);
-                 pglob->gl_pathc = 0;
-                 retval = GLOB_NOSPACE;
-                 goto out;
-               }
-
-             ++pglob->gl_pathc;
-             ++newcount;
-
-             pglob->gl_pathv[newcount] = NULL;
-             pglob->gl_flags = flags;
-           }
-         else
-           {
-             globfree (&dirs);
-             retval = GLOB_NOMATCH;
-             goto out;
-           }
-       }
+        {
+        no_matches:
+          /* No matches.  */
+          if (flags & GLOB_NOCHECK)
+            {
+              size_t newcount = pglob->gl_pathc + pglob->gl_offs;
+              char **new_gl_pathv;
+
+              if (newcount > SIZE_MAX / sizeof (char *) - 2)
+                {
+                nospace2:
+                  globfree (&dirs);
+                  retval = GLOB_NOSPACE;
+                  goto out;
+                }
+
+              new_gl_pathv = realloc (pglob->gl_pathv,
+                                      (newcount + 2) * sizeof (char *));
+              if (new_gl_pathv == NULL)
+                goto nospace2;
+              pglob->gl_pathv = new_gl_pathv;
+
+              pglob->gl_pathv[newcount] = strdup (pattern);
+              if (pglob->gl_pathv[newcount] == NULL)
+                {
+                  globfree (&dirs);
+                  globfree (pglob);
+                  pglob->gl_pathc = 0;
+                  retval = GLOB_NOSPACE;
+                  goto out;
+                }
+
+              ++pglob->gl_pathc;
+              ++newcount;
+
+              pglob->gl_pathv[newcount] = NULL;
+              pglob->gl_flags = flags;
+            }
+          else
+            {
+              globfree (&dirs);
+              retval = GLOB_NOMATCH;
+              goto out;
+            }
+        }
 
       globfree (&dirs);
     }
@@ -1065,57 +1085,57 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
       int orig_flags = flags;
 
       if (meta & GLOBPAT_BACKSLASH)
-       {
-         char *p = strchr (dirname, '\\'), *q;
-         /* We need to unescape the dirname string.  It is certainly
-            allocated by alloca, as otherwise filename would be NULL
-            or dirname wouldn't contain backslashes.  */
-         q = p;
-         do
-           {
-             if (*p == '\\')
-               {
-                 *q = *++p;
-                 --dirlen;
-               }
-             else
-               *q = *p;
-             ++q;
-           }
-         while (*p++ != '\0');
-         dirname_modified = 1;
-       }
+        {
+          char *p = strchr (dirname, '\\'), *q;
+          /* We need to unescape the dirname string.  It is certainly
+             allocated by alloca, as otherwise filename would be NULL
+             or dirname wouldn't contain backslashes.  */
+          q = p;
+          do
+            {
+              if (*p == '\\')
+                {
+                  *q = *++p;
+                  --dirlen;
+                }
+              else
+                *q = *p;
+              ++q;
+            }
+          while (*p++ != '\0');
+          dirname_modified = 1;
+        }
       if (dirname_modified)
-       flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
+        flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
       status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
-                           alloca_used);
+                            alloca_used);
       if (status != 0)
-       {
-         if (status == GLOB_NOMATCH && flags != orig_flags
-             && pglob->gl_pathc + pglob->gl_offs == oldcount)
-           {
-             /* Make sure globfree (&dirs); is a nop.  */
-             dirs.gl_pathv = NULL;
-             flags = orig_flags;
-             goto no_matches;
-           }
-         retval = status;
-         goto out;
-       }
+        {
+          if (status == GLOB_NOMATCH && flags != orig_flags
+              && pglob->gl_pathc + pglob->gl_offs == oldcount)
+            {
+              /* Make sure globfree (&dirs); is a nop.  */
+              dirs.gl_pathv = NULL;
+              flags = orig_flags;
+              goto no_matches;
+            }
+          retval = status;
+          goto out;
+        }
 
       if (dirlen > 0)
-       {
-         /* Stick the directory on the front of each name.  */
-         if (prefix_array (dirname,
-                           &pglob->gl_pathv[old_pathc + pglob->gl_offs],
-                           pglob->gl_pathc - old_pathc))
-           {
-             globfree (pglob);
-             pglob->gl_pathc = 0;
-             retval = GLOB_NOSPACE;
-             goto out;
-           }
-       }
+        {
+          /* Stick the directory on the front of each name.  */
+          if (prefix_array (dirname,
+                            &pglob->gl_pathv[old_pathc + pglob->gl_offs],
+                            pglob->gl_pathc - old_pathc))
+            {
+              globfree (pglob);
+              pglob->gl_pathc = 0;
+              retval = GLOB_NOSPACE;
+              goto out;
+            }
+        }
     }
 
   if (flags & GLOB_MARK)
@@ -1124,28 +1144,28 @@ __glob (const char *pattern, int flags, int (*errfunc) 
(const char *, int),
       size_t i;
 
       for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
-       if (is_dir (pglob->gl_pathv[i], flags, pglob))
-         {
-           size_t len = strlen (pglob->gl_pathv[i]) + 2;
-           char *new = realloc (pglob->gl_pathv[i], len);
-           if (new == NULL)
-             {
-               globfree (pglob);
-               pglob->gl_pathc = 0;
-               retval = GLOB_NOSPACE;
-               goto out;
-             }
-           strcpy (&new[len - 2], "/");
-           pglob->gl_pathv[i] = new;
-         }
+        if (is_dir (pglob->gl_pathv[i], flags, pglob))
+          {
+            size_t len = strlen (pglob->gl_pathv[i]) + 2;
+            char *new = realloc (pglob->gl_pathv[i], len);
+            if (new == NULL)
+              {
+                globfree (pglob);
+                pglob->gl_pathc = 0;
+                retval = GLOB_NOSPACE;
+                goto out;
+              }
+            strcpy (&new[len - 2], "/");
+            pglob->gl_pathv[i] = new;
+          }
     }
 
   if (!(flags & GLOB_NOSORT))
     {
       /* Sort the vector.  */
       qsort (&pglob->gl_pathv[oldcount],
-            pglob->gl_pathc + pglob->gl_offs - oldcount,
-            sizeof (char *), collated_compare);
+             pglob->gl_pathc + pglob->gl_offs - oldcount,
+             sizeof (char *), collated_compare);
     }
 
  out:
@@ -1197,14 +1217,14 @@ prefix_array (const char *dirname, char **array, size_t 
n)
   if (dirlen > 1)
     {
       if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
-       /* DIRNAME is "d:/".  Don't prepend the slash from DIRNAME.  */
-       --dirlen;
+        /* DIRNAME is "d:/".  Don't prepend the slash from DIRNAME.  */
+        --dirlen;
       else if (dirname[dirlen - 1] == ':')
-       {
-         /* DIRNAME is "d:".  Use ':' instead of '/'.  */
-         --dirlen;
-         dirsep_char = ':';
-       }
+        {
+          /* DIRNAME is "d:".  Use ':' instead of '/'.  */
+          --dirlen;
+          dirsep_char = ':';
+        }
     }
 #endif
 
@@ -1213,16 +1233,16 @@ prefix_array (const char *dirname, char **array, size_t 
n)
       size_t eltlen = strlen (array[i]) + 1;
       char *new = malloc (dirlen + 1 + eltlen);
       if (new == NULL)
-       {
-         while (i > 0)
-           free (array[--i]);
-         return 1;
-       }
+        {
+          while (i > 0)
+            free (array[--i]);
+          return 1;
+        }
 
       {
-       char *endp = mempcpy (new, dirname, dirlen);
-       *endp++ = dirsep_char;
-       mempcpy (endp, array[i], eltlen);
+        char *endp = mempcpy (new, dirname, dirlen);
+        *endp++ = dirsep_char;
+        mempcpy (endp, array[i], eltlen);
       }
       free (array[i]);
       array[i] = new;
@@ -1237,8 +1257,8 @@ prefix_array (const char *dirname, char **array, size_t n)
    The GLOB_APPEND flag is assumed to be set (always appends).  */
 static int
 glob_in_dir (const char *pattern, const char *directory, int flags,
-            int (*errfunc) (const char *, int),
-            glob_t *pglob, size_t alloca_used)
+             int (*errfunc) (const char *, int),
+             glob_t *pglob, size_t alloca_used)
 {
   size_t dirlen = strlen (directory);
   void *stream = NULL;
@@ -1266,8 +1286,8 @@ glob_in_dir (const char *pattern, const char *directory, 
int flags,
   if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
     {
       /* We need not do any tests.  The PATTERN contains no meta
-        characters and we must not return an error therefore the
-        result will always contain exactly one name.  */
+         characters and we must not return an error therefore the
+         result will always contain exactly one name.  */
       flags |= GLOB_NOCHECK;
     }
   else if (meta == GLOBPAT_NONE)
@@ -1281,102 +1301,102 @@ glob_in_dir (const char *pattern, const char 
*directory, int flags,
       if (alloca_fullname)
         fullname = alloca_account (fullsize, alloca_used);
       else
-       {
-         fullname = malloc (fullsize);
-         if (fullname == NULL)
-           return GLOB_NOSPACE;
-       }
+        {
+          fullname = malloc (fullsize);
+          if (fullname == NULL)
+            return GLOB_NOSPACE;
+        }
 
       mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
-                       "/", 1),
-              pattern, patlen + 1);
+                        "/", 1),
+               pattern, patlen + 1);
       if (glob_lstat (pglob, flags, fullname) == 0
-         || errno == EOVERFLOW)
-       /* We found this file to be existing.  Now tell the rest
-          of the function to copy this name into the result.  */
-       flags |= GLOB_NOCHECK;
+          || errno == EOVERFLOW)
+        /* We found this file to be existing.  Now tell the rest
+           of the function to copy this name into the result.  */
+        flags |= GLOB_NOCHECK;
 
       if (__glibc_unlikely (!alloca_fullname))
-       free (fullname);
+        free (fullname);
     }
   else
     {
       stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
-               ? (*pglob->gl_opendir) (directory)
-               : opendir (directory));
+                ? (*pglob->gl_opendir) (directory)
+                : opendir (directory));
       if (stream == NULL)
-       {
-         if (errno != ENOTDIR
-             && ((errfunc != NULL && (*errfunc) (directory, errno))
-                 || (flags & GLOB_ERR)))
-           return GLOB_ABORTED;
-       }
+        {
+          if (errno != ENOTDIR
+              && ((errfunc != NULL && (*errfunc) (directory, errno))
+                  || (flags & GLOB_ERR)))
+            return GLOB_ABORTED;
+        }
       else
-       {
-         int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
-                          | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
-         flags |= GLOB_MAGCHAR;
-
-         while (1)
-           {
-             struct readdir_result d;
-             {
-               if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
-                 d = convert_dirent (GL_READDIR (pglob, stream));
-               else
-                 {
+        {
+          int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
+                           | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
+          flags |= GLOB_MAGCHAR;
+
+          while (1)
+            {
+              struct readdir_result d;
+              {
+                if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
+                  d = convert_dirent (GL_READDIR (pglob, stream));
+                else
+                  {
 #ifdef COMPILE_GLOB64
-                   d = convert_dirent (__readdir (stream));
+                    d = convert_dirent (__readdir (stream));
 #else
-                   d = convert_dirent64 (__readdir64 (stream));
+                    d = convert_dirent64 (__readdir64 (stream));
 #endif
-                 }
-             }
-             if (d.name == NULL)
-               break;
-
-             /* If we shall match only directories use the information
-                provided by the dirent call if possible.  */
-             if (flags & GLOB_ONLYDIR)
-               switch (readdir_result_type (d))
-                 {
-                 case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
-                 default: continue;
-                 }
-
-             if (fnmatch (pattern, d.name, fnm_flags) == 0)
-               {
-                 if (cur == names->count)
-                   {
-                     struct globnames *newnames;
-                     size_t count = names->count * 2;
-                     size_t nameoff = offsetof (struct globnames, name);
-                     size_t size = FLEXSIZEOF (struct globnames, name,
-                                               count * sizeof (char *));
-                     if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
-                         < names->count)
-                       goto memory_error;
-                     if (glob_use_alloca (alloca_used, size))
-                       newnames = names_alloca
-                         = alloca_account (size, alloca_used);
-                     else if ((newnames = malloc (size))
-                              == NULL)
-                       goto memory_error;
-                     newnames->count = count;
-                     newnames->next = names;
-                     names = newnames;
-                     cur = 0;
-                   }
-                 names->name[cur] = strdup (d.name);
-                 if (names->name[cur] == NULL)
-                   goto memory_error;
-                 ++cur;
-                 ++nfound;
-                 if (SIZE_MAX - pglob->gl_offs <= nfound)
-                   goto memory_error;
-               }
-           }
-       }
+                  }
+              }
+              if (d.name == NULL)
+                break;
+
+              /* If we shall match only directories use the information
+                 provided by the dirent call if possible.  */
+              if (flags & GLOB_ONLYDIR)
+                switch (readdir_result_type (d))
+                  {
+                  case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
+                  default: continue;
+                  }
+
+              if (fnmatch (pattern, d.name, fnm_flags) == 0)
+                {
+                  if (cur == names->count)
+                    {
+                      struct globnames *newnames;
+                      size_t count = names->count * 2;
+                      size_t nameoff = offsetof (struct globnames, name);
+                      size_t size = FLEXSIZEOF (struct globnames, name,
+                                                count * sizeof (char *));
+                      if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
+                          < names->count)
+                        goto memory_error;
+                      if (glob_use_alloca (alloca_used, size))
+                        newnames = names_alloca
+                          = alloca_account (size, alloca_used);
+                      else if ((newnames = malloc (size))
+                               == NULL)
+                        goto memory_error;
+                      newnames->count = count;
+                      newnames->next = names;
+                      names = newnames;
+                      cur = 0;
+                    }
+                  names->name[cur] = strdup (d.name);
+                  if (names->name[cur] == NULL)
+                    goto memory_error;
+                  ++cur;
+                  ++nfound;
+                  if (SIZE_MAX - pglob->gl_offs <= nfound)
+                    goto memory_error;
+                }
+            }
+        }
     }
 
   if (nfound == 0 && (flags & GLOB_NOCHECK))
@@ -1385,7 +1405,7 @@ glob_in_dir (const char *pattern, const char *directory, 
int flags,
       nfound = 1;
       names->name[cur] = malloc (len + 1);
       if (names->name[cur] == NULL)
-       goto memory_error;
+        goto memory_error;
       *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
     }
 
@@ -1396,80 +1416,80 @@ glob_in_dir (const char *pattern, const char 
*directory, int flags,
       result = 0;
 
       if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
-         < pglob->gl_offs + nfound + 1)
-       goto memory_error;
+          < pglob->gl_offs + nfound + 1)
+        goto memory_error;
 
       new_gl_pathv
-       = realloc (pglob->gl_pathv,
-                  (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
-                   * sizeof (char *));
+        = realloc (pglob->gl_pathv,
+                   (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
+                    * sizeof (char *));
 
       if (new_gl_pathv == NULL)
-       {
-       memory_error:
-         while (1)
-           {
-             struct globnames *old = names;
-             for (size_t i = 0; i < cur; ++i)
-               free (names->name[i]);
-             names = names->next;
-             /* NB: we will not leak memory here if we exit without
-                freeing the current block assigned to OLD.  At least
-                the very first block is always allocated on the stack
-                and this is the block assigned to OLD here.  */
-             if (names == NULL)
-               {
-                 assert (old == init_names);
-                 break;
-               }
-             cur = names->count;
-             if (old == names_alloca)
-               names_alloca = names;
-             else
-               free (old);
-           }
-         result = GLOB_NOSPACE;
-       }
+        {
+        memory_error:
+          while (1)
+            {
+              struct globnames *old = names;
+              for (size_t i = 0; i < cur; ++i)
+                free (names->name[i]);
+              names = names->next;
+              /* NB: we will not leak memory here if we exit without
+                 freeing the current block assigned to OLD.  At least
+                 the very first block is always allocated on the stack
+                 and this is the block assigned to OLD here.  */
+              if (names == NULL)
+                {
+                  assert (old == init_names);
+                  break;
+                }
+              cur = names->count;
+              if (old == names_alloca)
+                names_alloca = names;
+              else
+                free (old);
+            }
+          result = GLOB_NOSPACE;
+        }
       else
-       {
-         while (1)
-           {
-             struct globnames *old = names;
-             for (size_t i = 0; i < cur; ++i)
-               new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
-                 = names->name[i];
-             names = names->next;
-             /* NB: we will not leak memory here if we exit without
-                freeing the current block assigned to OLD.  At least
-                the very first block is always allocated on the stack
-                and this is the block assigned to OLD here.  */
-             if (names == NULL)
-               {
-                 assert (old == init_names);
-                 break;
-               }
-             cur = names->count;
-             if (old == names_alloca)
-               names_alloca = names;
-             else
-               free (old);
-           }
-
-         pglob->gl_pathv = new_gl_pathv;
-
-         pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
-
-         pglob->gl_flags = flags;
-       }
+        {
+          while (1)
+            {
+              struct globnames *old = names;
+              for (size_t i = 0; i < cur; ++i)
+                new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
+                  = names->name[i];
+              names = names->next;
+              /* NB: we will not leak memory here if we exit without
+                 freeing the current block assigned to OLD.  At least
+                 the very first block is always allocated on the stack
+                 and this is the block assigned to OLD here.  */
+              if (names == NULL)
+                {
+                  assert (old == init_names);
+                  break;
+                }
+              cur = names->count;
+              if (old == names_alloca)
+                names_alloca = names;
+              else
+                free (old);
+            }
+
+          pglob->gl_pathv = new_gl_pathv;
+
+          pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+
+          pglob->gl_flags = flags;
+        }
     }
 
   if (stream != NULL)
     {
       save = errno;
       if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
-       (*pglob->gl_closedir) (stream);
+        (*pglob->gl_closedir) (stream);
       else
-       closedir (stream);
+        closedir (stream);
       __set_errno (save);
     }
 
diff --git a/posix/glob_pattern_p.c b/posix/glob_pattern_p.c
index f187baa1a5..436d38126d 100644
--- a/posix/glob_pattern_p.c
+++ b/posix/glob_pattern_p.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #ifndef _LIBC
-# include <config.h>
+# include <libc-config.h>
 #endif
 
 #include <glob.h>
diff --git a/posix/globfree.c b/posix/globfree.c
index 162b90341a..1144fdd69f 100644
--- a/posix/globfree.c
+++ b/posix/globfree.c
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #ifndef _LIBC
-# include <config.h>
+# include <libc-config.h>
 #endif
 
 #include <glob.h>
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]