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.
This commit is contained in:
Ulrich Drepper 2004-09-30 06:42:39 +00:00
parent 8930fcf9be
commit 66b38fc99e
3 changed files with 71 additions and 20 deletions

View file

@ -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.

View file

@ -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;
}

View file

@ -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
@ -1427,6 +1455,15 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
name = d->d_name;
if (fnmatch (pattern, name, fnm_flags) == 0)
{
/* 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));
@ -1449,6 +1486,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
}
}
}
}
if (nfound == 0 && (flags & GLOB_NOCHECK))
{