Fix glob with empty pattern

This commit is contained in:
Ulrich Drepper 2010-03-24 11:58:05 -07:00
parent 4ad43b62d6
commit 8f2e399413
3 changed files with 87 additions and 42 deletions

View File

@ -1,3 +1,9 @@
2010-03-24 Ulrich Drepper <drepper@redhat.com>
Andreas Schwab <andreas@redhat.com>
* posix/glob.c (glob): Clean up gl_pathc and gl_pathv earlier.
If pattern is "" bail out early
2010-03-23 Jakub Jelinek <jakub@redhat.com>
* elf/dl-lookup.c (do_lookup_x): If tab->entries is NULL,

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007, 2008
/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@ -418,6 +418,24 @@ glob (pattern, flags, errfunc, pglob)
}
}
if (!(flags & GLOB_APPEND))
{
pglob->gl_pathc = 0;
if (!(flags & GLOB_DOOFFS))
pglob->gl_pathv = NULL;
else
{
size_t i;
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;
}
}
/* Find the filename. */
filename = strrchr (pattern, '/');
#if defined __MSDOS__ || defined WINDOWS32
@ -445,6 +463,12 @@ glob (pattern, flags, errfunc, pglob)
}
else
{
if (__builtin_expect (pattern[0] == '\0', 0))
{
dirs.gl_pathv = NULL;
goto no_matches;
}
filename = pattern;
#ifdef _AMIGA
dirname = "";
@ -492,7 +516,7 @@ glob (pattern, flags, errfunc, pglob)
if (filename[0] == '\0'
#if defined __MSDOS__ || defined WINDOWS32
&& dirname[dirlen - 1] != ':'
&& dirname[dirlen - 1] != ':'
&& (dirlen < 3 || dirname[dirlen - 2] != ':'
|| dirname[dirlen - 1] != '/')
#endif
@ -529,24 +553,6 @@ glob (pattern, flags, errfunc, pglob)
}
}
if (!(flags & GLOB_APPEND))
{
pglob->gl_pathc = 0;
if (!(flags & GLOB_DOOFFS))
pglob->gl_pathv = NULL;
else
{
size_t i;
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;
}
}
oldcount = pglob->gl_pathc + pglob->gl_offs;
#ifndef VMS
@ -564,7 +570,7 @@ glob (pattern, flags, errfunc, pglob)
# else
# ifdef WINDOWS32
if (home_dir == NULL || home_dir[0] == '\0')
home_dir = "c:/users/default"; /* poor default */
home_dir = "c:/users/default"; /* poor default */
# else
if (home_dir == NULL || home_dir[0] == '\0')
{

View File

@ -1,6 +1,6 @@
/* Test the GNU extensions in glob which allow the user to provide callbacks
for the filesystem access functions.
Copyright (C) 2001-2002, 2007 Free Software Foundation, Inc.
Copyright (C) 2001-2002, 2007, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
@ -61,9 +61,9 @@ static struct
{ "..", 3, DT_DIR },
{ ".foo", 3, DT_REG },
{ "dir1lev3", 3, DT_DIR },
{ ".", 4, DT_DIR },
{ "..", 4, DT_DIR },
{ "file1lev4", 4, DT_REG },
{ ".", 4, DT_DIR },
{ "..", 4, DT_DIR },
{ "file1lev4", 4, DT_REG },
{ "file1lev3", 3, DT_REG },
{ "file2lev3", 3, DT_REG },
{ "file2lev2", 2, DT_REG },
@ -81,9 +81,9 @@ static struct
{ "..", 3, DT_DIR },
{ ".foo", 3, DT_REG },
{ ".dir", 3, DT_DIR },
{ ".", 4, DT_DIR },
{ "..", 4, DT_DIR },
{ "hidden", 4, DT_REG }
{ ".", 4, DT_DIR },
{ "..", 4, DT_DIR },
{ "hidden", 4, DT_REG }
};
#define nfiles (sizeof (filesystem) / sizeof (filesystem[0]))
@ -283,7 +283,7 @@ static const char *glob_errstring[] =
static const char *
flagstr (int flags)
{
const char *strs[] =
static const char *const strs[] =
{
"GLOB_ERR", "GLOB_MARK", "GLOB_NOSORT", "GLOB_DOOFSS", "GLOB_NOCHECK",
"GLOB_APPEND", "GLOB_NOESCAPE", "GLOB_PERIOD", "GLOB_MAGCHAR",
@ -312,6 +312,29 @@ flagstr (int flags)
}
return buf;
#undef nstrs
}
static const char *
errstr (int val)
{
static const char *const strs[] =
{
[GLOB_NOSPACE] = "GLOB_NOSPACE",
[GLOB_ABORTED] = "GLOB_ABORTED",
[GLOB_NOMATCH] = "GLOB_NOMATCH",
[GLOB_NOSYS] = "GLOB_NOSYS"
};
#define nstrs (sizeof (strs) / sizeof (strs[0]))
static char buf[100];
if (val < 0 || val >= nstrs || strs[val] == NULL)
{
snprintf (buf, sizeof (buf), "GLOB_??? (%d)", val);
return buf;
}
return strs[val];
#undef nstrs
}
@ -376,28 +399,34 @@ main (void)
gl.gl_lstat = my_stat;
gl.gl_stat = my_stat;
#define test(a, b, c...) \
#define test(a, b, r, c...) \
fmt = a; \
flags = b; \
flags = GLOB_ALTDIRFUNC | b; \
errval = glob (fmt, flags, NULL, &gl); \
if (errval != 0) \
if (errval != r) \
{ \
printf ("glob (\"%s\", %s) failed: %s\n", fmt, flagstr (flags), \
errval >= 0 && errval < nglob_errstring \
? glob_errstring[errval] : "???"); \
if (r == 0) \
printf ("glob (\"%s\", %s) failed: %s\n", fmt, flagstr (flags), \
errval >= 0 && errval < nglob_errstring \
? glob_errstring[errval] : "???"); \
else \
printf ("glob (\"%s\", %s) did not fail\n", fmt, flagstr (flags)); \
result = 1; \
} \
else if (r == 0) \
result |= test_result (fmt, flags, &gl, (const char *[]) { c, NULL }); \
else \
result |= test_result (fmt, flags, &gl, (const char *[]) { c, NULL })
printf ("result for glob (\"%s\", %s) = %s\n\n", fmt, flagstr (flags), \
errstr (errval))
test ("*/*/*", GLOB_ALTDIRFUNC,
test ("*/*/*", 0, 0,
"dir1lev1/dir2lev2/dir1lev3",
"dir1lev1/dir2lev2/file1lev3",
"dir1lev1/dir2lev2/file2lev3",
"dir1lev1/dir3lev2/file3lev3",
"dir1lev1/dir3lev2/file4lev3");
test ("*/*/*", GLOB_ALTDIRFUNC | GLOB_PERIOD,
test ("*/*/*", GLOB_PERIOD, 0,
"dir1lev1/dir1lev2/.",
"dir1lev1/dir1lev2/..",
"dir1lev1/dir2lev2/.",
@ -415,7 +444,7 @@ main (void)
"dir2lev1/dir1lev2/.dir",
"dir2lev1/dir1lev2/.foo");
test ("*/*/.*", GLOB_ALTDIRFUNC,
test ("*/*/.*", 0, 0,
"dir1lev1/dir1lev2/.",
"dir1lev1/dir1lev2/..",
"dir1lev1/dir2lev2/.",
@ -428,7 +457,7 @@ main (void)
"dir2lev1/dir1lev2/.dir",
"dir2lev1/dir1lev2/.foo");
test ("*1*/*2*/.*", GLOB_ALTDIRFUNC,
test ("*1*/*2*/.*", 0, 0,
"dir1lev1/dir1lev2/.",
"dir1lev1/dir1lev2/..",
"dir1lev1/dir2lev2/.",
@ -441,7 +470,7 @@ main (void)
"dir2lev1/dir1lev2/.dir",
"dir2lev1/dir1lev2/.foo");
test ("*1*/*1*/.*", GLOB_ALTDIRFUNC,
test ("*1*/*1*/.*", 0, 0,
"dir1lev1/dir1lev2/.",
"dir1lev1/dir1lev2/..",
"dir2lev1/dir1lev2/.",
@ -449,12 +478,16 @@ main (void)
"dir2lev1/dir1lev2/.dir",
"dir2lev1/dir1lev2/.foo");
test ("\\/*", GLOB_ALTDIRFUNC,
test ("\\/*", 0, 0,
"/dir1lev1",
"/dir2lev1",
"/file1lev1",
"/file2lev1");
test ("", 0, GLOB_NOMATCH, NULL);
test ("", GLOB_NOCHECK, 0, "");
globfree (&gl);
return result;