diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | posix/tst-gnuglob.c | 12 | ||||
-rw-r--r-- | sysdeps/generic/glob.c | 66 |
3 files changed, 69 insertions, 18 deletions
@@ -1,3 +1,12 @@ +2004-09-29 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/generic/glob.c (glob_in_dir): Don't blindly trust + readdir results; for symlinks or files of unknown type check using + stat whether the file exists. + + * posix/tst-gnuglob.c (find_file): Handle leading "./". Fix + recognition of files. + 2004-09-29 Jakub Jelinek <jakub@redhat.com> * time/tzfile.c (tzfile_mtime): New variable. diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c index b15dad1..72f3fa4 100644 --- a/posix/tst-gnuglob.c +++ b/posix/tst-gnuglob.c @@ -30,7 +30,7 @@ #include <sys/stat.h> -/* #define DEBUG */ +// #define DEBUG #ifdef DEBUG # define PRINTF(fmt, args...) printf (fmt, ##args) #else @@ -106,6 +106,9 @@ find_file (const char *s) if (strcmp (s, ".") == 0) return 0; + if (s[0] == '.' && s[1] == '/') + s += 2; + while (*s != '\0') { char *endp = strchrnul (s, '/'); @@ -126,6 +129,10 @@ find_file (const char *s) errno = ENOENT; return -1; } + + if (*endp == '\0') + return idx + 1; + if (filesystem[idx].type != DT_DIR && (idx + 1 >= nfiles || filesystem[idx].level >= filesystem[idx + 1].level)) @@ -136,9 +143,6 @@ find_file (const char *s) ++idx; - if (*endp == '\0') - return idx; - s = endp + 1; ++level; } diff --git a/sysdeps/generic/glob.c b/sysdeps/generic/glob.c index a6d6ada..658599e 100644 --- a/sysdeps/generic/glob.c +++ b/sysdeps/generic/glob.c @@ -1273,6 +1273,34 @@ weak_alias (__glob_pattern_p, glob_pattern_p) #endif /* !GLOB_ONLY_P */ +/* We put this in a separate function mainly to allow the memory + allocated with alloca to be recycled. */ +#if !defined _LIBC || !defined GLOB_ONLY_P +static int +link_exists_p (const char *dir, size_t dirlen, const char *fname, + glob_t *pglob, int flags) +{ + size_t fnamelen = strlen (fname); + char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1); + struct stat st; + struct stat64 st64; + +# ifdef HAVE_MEMPCPY + mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1), + fname, fnamelen + 1); +# else + memcpy (fullname, dir, dirlen); + fullname[dirlen] = '/'; + memcpy (&fullname[dirlen + 1], fname, fnamelen + 1); +# endif + + return (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (fullname, &st) + : __stat64 (fullname, &st64)) == 0); +} +#endif + + /* Like `glob', but PATTERN is a final pathname component, and matches are searched for in DIRECTORY. The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. @@ -1285,6 +1313,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) int (*errfunc) (const char *, int); glob_t *pglob; { + size_t dirlen = strlen (directory); __ptr_t stream = NULL; struct globlink { @@ -1315,7 +1344,6 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) struct stat64 st64; # endif size_t patlen = strlen (pattern); - size_t dirlen = strlen (directory); char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1); # ifdef HAVE_MEMPCPY @@ -1428,22 +1456,32 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) if (fnmatch (pattern, name, fnm_flags) == 0) { - struct globlink *new = (struct globlink *) - __alloca (sizeof (struct globlink)); - len = NAMLEN (d); - new->name = (char *) malloc (len + 1); - if (new->name == NULL) - goto memory_error; + /* If the file we found is a symlink we have to + make sure the target file exists. */ + if ( +#ifdef HAVE_D_TYPE + (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK) || +#endif + link_exists_p (directory, dirlen, name, pglob, + flags)) + { + struct globlink *new = (struct globlink *) + __alloca (sizeof (struct globlink)); + len = NAMLEN (d); + new->name = (char *) malloc (len + 1); + if (new->name == NULL) + goto memory_error; #ifdef HAVE_MEMPCPY - *((char *) mempcpy ((__ptr_t) new->name, name, len)) - = '\0'; + *((char *) mempcpy ((__ptr_t) new->name, name, len)) + = '\0'; #else - memcpy ((__ptr_t) new->name, name, len); - new->name[len] = '\0'; + memcpy ((__ptr_t) new->name, name, len); + new->name[len] = '\0'; #endif - new->next = names; - names = new; - ++nfound; + new->next = names; + names = new; + ++nfound; + } } } } |