mirror of git://sourceware.org/git/glibc.git
[BZ #3996]
2007-02-14 Jakub Jelinek <jakub@redhat.com> [BZ #3996] * posix/glob.c (attribute_hidden): Define if not defined. (glob): Unescape dirname, filename or username when needed and not GLOB_NOESCAPE. Handle \/ correctly. Handle GLOB_MARK if filename is NULL. Handle unescaped [ in pattern without closing ]. Don't pass GLOB_CHECK down to recursive glob for directories. (__glob_pattern_type): New function. (__glob_pattern_p): Implement using __glob_pattern_type. (glob_in_dir): Handle GLOB_NOCHECK patterns containing no meta characters and backslashes if not GLOB_NOESCAPE or unterminated [. Remove unreachable code. * posix/globtest.sh: Add a couple of new tests.
This commit is contained in:
parent
2f69996772
commit
05f135ba3b
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
2007-02-14 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
[BZ #3996]
|
||||||
|
* posix/glob.c (attribute_hidden): Define if not defined.
|
||||||
|
(glob): Unescape dirname, filename or username when needed and not
|
||||||
|
GLOB_NOESCAPE. Handle \/ correctly. Handle GLOB_MARK if filename
|
||||||
|
is NULL. Handle unescaped [ in pattern without closing ].
|
||||||
|
Don't pass GLOB_CHECK down to recursive glob for directories.
|
||||||
|
(__glob_pattern_type): New function.
|
||||||
|
(__glob_pattern_p): Implement using __glob_pattern_type.
|
||||||
|
(glob_in_dir): Handle GLOB_NOCHECK patterns containing no meta
|
||||||
|
characters and backslashes if not GLOB_NOESCAPE or unterminated [.
|
||||||
|
Remove unreachable code.
|
||||||
|
* posix/globtest.sh: Add a couple of new tests.
|
||||||
|
|
||||||
2007-02-13 Ulrich Drepper <drepper@redhat.com>
|
2007-02-13 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* po/ru.po: Update from translation team.
|
* po/ru.po: Update from translation team.
|
||||||
|
|
205
posix/glob.c
205
posix/glob.c
|
@ -1,4 +1,5 @@
|
||||||
/* Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
|
/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007
|
||||||
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -192,9 +193,15 @@ static const char *next_brace_sub (const char *begin, int flags) __THROW;
|
||||||
|
|
||||||
#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
|
#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
|
||||||
|
|
||||||
|
#ifndef attribute_hidden
|
||||||
|
# define attribute_hidden
|
||||||
|
#endif
|
||||||
|
|
||||||
static int glob_in_dir (const char *pattern, const char *directory,
|
static int glob_in_dir (const char *pattern, const char *directory,
|
||||||
int flags, int (*errfunc) (const char *, int),
|
int flags, int (*errfunc) (const char *, int),
|
||||||
glob_t *pglob);
|
glob_t *pglob);
|
||||||
|
extern int __glob_pattern_type (const char *pattern, int quote)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
#if !defined _LIBC || !defined GLOB_ONLY_P
|
#if !defined _LIBC || !defined GLOB_ONLY_P
|
||||||
static int prefix_array (const char *prefix, char **array, size_t n) __THROW;
|
static int prefix_array (const char *prefix, char **array, size_t n) __THROW;
|
||||||
|
@ -250,6 +257,9 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
size_t dirlen;
|
size_t dirlen;
|
||||||
int status;
|
int status;
|
||||||
size_t oldcount;
|
size_t oldcount;
|
||||||
|
int meta;
|
||||||
|
int dirname_modified;
|
||||||
|
glob_t dirs;
|
||||||
|
|
||||||
if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
|
if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
|
||||||
{
|
{
|
||||||
|
@ -418,6 +428,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
filename = strchr (pattern, ':');
|
filename = strchr (pattern, ':');
|
||||||
#endif /* __MSDOS__ || WINDOWS32 */
|
#endif /* __MSDOS__ || WINDOWS32 */
|
||||||
|
dirname_modified = 0;
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
{
|
{
|
||||||
/* This can mean two things: a simple name or "~name". The latter
|
/* This can mean two things: a simple name or "~name". The latter
|
||||||
|
@ -486,10 +497,32 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
&& dirlen > 1)
|
&& dirlen > 1)
|
||||||
/* "pattern/". Expand "pattern", appending slashes. */
|
/* "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);
|
int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
|
pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
|
||||||
| (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;
|
||||||
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,7 +550,9 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
#ifndef VMS
|
#ifndef VMS
|
||||||
if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
|
if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
|
||||||
{
|
{
|
||||||
if (dirname[1] == '\0' || dirname[1] == '/')
|
if (dirname[1] == '\0' || dirname[1] == '/'
|
||||||
|
|| (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
|
||||||
|
&& (dirname[2] == '\0' || dirname[2] == '/')))
|
||||||
{
|
{
|
||||||
/* Look up home directory. */
|
/* Look up home directory. */
|
||||||
const char *home_dir = getenv ("HOME");
|
const char *home_dir = getenv ("HOME");
|
||||||
|
@ -594,7 +629,10 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
# endif
|
# endif
|
||||||
/* Now construct the full directory. */
|
/* Now construct the full directory. */
|
||||||
if (dirname[1] == '\0')
|
if (dirname[1] == '\0')
|
||||||
|
{
|
||||||
dirname = home_dir;
|
dirname = home_dir;
|
||||||
|
dirlen = strlen (dirname);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *newp;
|
char *newp;
|
||||||
|
@ -603,7 +641,9 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
mempcpy (mempcpy (newp, home_dir, home_len),
|
mempcpy (mempcpy (newp, home_dir, home_len),
|
||||||
&dirname[1], dirlen);
|
&dirname[1], dirlen);
|
||||||
dirname = newp;
|
dirname = newp;
|
||||||
|
dirlen += home_len - 1;
|
||||||
}
|
}
|
||||||
|
dirname_modified = 1;
|
||||||
}
|
}
|
||||||
# if !defined _AMIGA && !defined WINDOWS32
|
# if !defined _AMIGA && !defined WINDOWS32
|
||||||
else
|
else
|
||||||
|
@ -611,13 +651,50 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
char *end_name = strchr (dirname, '/');
|
char *end_name = strchr (dirname, '/');
|
||||||
const char *user_name;
|
const char *user_name;
|
||||||
const char *home_dir;
|
const char *home_dir;
|
||||||
|
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)
|
if (end_name == NULL)
|
||||||
user_name = dirname + 1;
|
user_name = dirname + 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *newp;
|
char *newp;
|
||||||
newp = (char *) __alloca (end_name - dirname);
|
newp = (char *) __alloca (end_name - dirname);
|
||||||
|
if (unescape != NULL)
|
||||||
|
{
|
||||||
|
char *p = mempcpy (newp, dirname + 1,
|
||||||
|
unescape - dirname - 1);
|
||||||
|
char *q = unescape;
|
||||||
|
while (*q != '\0')
|
||||||
|
{
|
||||||
|
if (*q == '\\')
|
||||||
|
{
|
||||||
|
if (q[1] == '\0')
|
||||||
|
{
|
||||||
|
/* "~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))
|
*((char *) mempcpy (newp, dirname + 1, end_name - dirname))
|
||||||
= '\0';
|
= '\0';
|
||||||
user_name = newp;
|
user_name = newp;
|
||||||
|
@ -673,6 +750,8 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
*((char *) mempcpy (mempcpy (newp, home_dir, home_len),
|
*((char *) mempcpy (mempcpy (newp, home_dir, home_len),
|
||||||
end_name, rest_len)) = '\0';
|
end_name, rest_len)) = '\0';
|
||||||
dirname = newp;
|
dirname = newp;
|
||||||
|
dirlen = home_len + rest_len;
|
||||||
|
dirname_modified = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (flags & GLOB_TILDE_CHECK)
|
if (flags & GLOB_TILDE_CHECK)
|
||||||
|
@ -714,9 +793,22 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
}
|
}
|
||||||
pglob->gl_pathv = new_gl_pathv;
|
pglob->gl_pathv = new_gl_pathv;
|
||||||
|
|
||||||
|
if (flags & GLOB_MARK)
|
||||||
|
{
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pglob->gl_pathv[newcount] = strdup (dirname);
|
pglob->gl_pathv[newcount] = strdup (dirname);
|
||||||
if (pglob->gl_pathv[newcount] == NULL)
|
if (pglob->gl_pathv[newcount] == NULL)
|
||||||
goto nospace;
|
goto nospace;
|
||||||
|
}
|
||||||
pglob->gl_pathv[++newcount] = NULL;
|
pglob->gl_pathv[++newcount] = NULL;
|
||||||
++pglob->gl_pathc;
|
++pglob->gl_pathc;
|
||||||
pglob->gl_flags = flags;
|
pglob->gl_flags = flags;
|
||||||
|
@ -728,14 +820,30 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
return GLOB_NOMATCH;
|
return GLOB_NOMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
|
meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
|
||||||
|
/* meta is 1 if correct glob pattern containing metacharacters.
|
||||||
|
If meta has bit (1 << 2) set, it means there was an unterminated
|
||||||
|
[ which we handle the same, using fnmatch. Broken unterminated
|
||||||
|
pattern bracket expressions ought to be rare enough that it is
|
||||||
|
not worth special casing them, fnmatch will do the right thing. */
|
||||||
|
if (meta & 5)
|
||||||
{
|
{
|
||||||
/* The directory name contains metacharacters, so we
|
/* The directory name contains metacharacters, so we
|
||||||
have to glob for the directory, and then glob for
|
have to glob for the directory, and then glob for
|
||||||
the pattern in each directory found. */
|
the pattern in each directory found. */
|
||||||
glob_t dirs;
|
|
||||||
size_t i;
|
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];
|
||||||
|
|
||||||
|
while (p > dirname && p[-1] == '\\') --p;
|
||||||
|
if ((&dirname[dirlen] - p) & 1)
|
||||||
|
*(char *) &dirname[--dirlen] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
if ((flags & GLOB_ALTDIRFUNC) != 0)
|
if ((flags & GLOB_ALTDIRFUNC) != 0)
|
||||||
{
|
{
|
||||||
/* Use the alternative access functions also in the recursive
|
/* Use the alternative access functions also in the recursive
|
||||||
|
@ -748,12 +856,16 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
}
|
}
|
||||||
|
|
||||||
status = glob (dirname,
|
status = glob (dirname,
|
||||||
((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE
|
((flags & (GLOB_ERR | GLOB_NOESCAPE
|
||||||
| GLOB_ALTDIRFUNC))
|
| GLOB_ALTDIRFUNC))
|
||||||
| GLOB_NOSORT | GLOB_ONLYDIR),
|
| GLOB_NOSORT | GLOB_ONLYDIR),
|
||||||
errfunc, &dirs);
|
errfunc, &dirs);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
|
{
|
||||||
|
if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
|
||||||
return status;
|
return status;
|
||||||
|
goto no_matches;
|
||||||
|
}
|
||||||
|
|
||||||
/* We have successfully globbed the preceding directory name.
|
/* We have successfully globbed the preceding directory name.
|
||||||
For each name we found, call glob_in_dir on it and FILENAME,
|
For each name we found, call glob_in_dir on it and FILENAME,
|
||||||
|
@ -811,6 +923,7 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
flag was set we must return the input pattern itself. */
|
flag was set we must return the input pattern itself. */
|
||||||
if (pglob->gl_pathc + pglob->gl_offs == oldcount)
|
if (pglob->gl_pathc + pglob->gl_offs == oldcount)
|
||||||
{
|
{
|
||||||
|
no_matches:
|
||||||
/* No matches. */
|
/* No matches. */
|
||||||
if (flags & GLOB_NOCHECK)
|
if (flags & GLOB_NOCHECK)
|
||||||
{
|
{
|
||||||
|
@ -854,10 +967,44 @@ glob (pattern, flags, errfunc, pglob)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int old_pathc = pglob->gl_pathc;
|
int old_pathc = pglob->gl_pathc;
|
||||||
|
int orig_flags = flags;
|
||||||
|
|
||||||
|
if (meta & 2)
|
||||||
|
{
|
||||||
|
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);
|
||||||
status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
|
status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
|
||||||
if (status != 0)
|
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;
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
if (dirlen > 0)
|
if (dirlen > 0)
|
||||||
{
|
{
|
||||||
|
@ -1015,15 +1162,13 @@ prefix_array (const char *dirname, char **array, size_t n)
|
||||||
|
|
||||||
/* We must not compile this function twice. */
|
/* We must not compile this function twice. */
|
||||||
#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
|
#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
|
||||||
/* Return nonzero if PATTERN contains any metacharacters.
|
|
||||||
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
|
|
||||||
int
|
int
|
||||||
__glob_pattern_p (pattern, quote)
|
__glob_pattern_type (pattern, quote)
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
int quote;
|
int quote;
|
||||||
{
|
{
|
||||||
register const char *p;
|
register const char *p;
|
||||||
int open = 0;
|
int ret = 0;
|
||||||
|
|
||||||
for (p = pattern; *p != '\0'; ++p)
|
for (p = pattern; *p != '\0'; ++p)
|
||||||
switch (*p)
|
switch (*p)
|
||||||
|
@ -1033,21 +1178,35 @@ __glob_pattern_p (pattern, quote)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case '\\':
|
case '\\':
|
||||||
if (quote && p[1] != '\0')
|
if (quote)
|
||||||
|
{
|
||||||
|
if (p[1] != '\0')
|
||||||
++p;
|
++p;
|
||||||
|
ret |= 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
open = 1;
|
ret |= 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ']':
|
case ']':
|
||||||
if (open)
|
if (ret & 4)
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return nonzero if PATTERN contains any metacharacters.
|
||||||
|
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
|
||||||
|
int
|
||||||
|
__glob_pattern_p (pattern, quote)
|
||||||
|
const char *pattern;
|
||||||
|
int quote;
|
||||||
|
{
|
||||||
|
return __glob_pattern_type (pattern, quote) == 1;
|
||||||
}
|
}
|
||||||
# ifdef _LIBC
|
# ifdef _LIBC
|
||||||
weak_alias (__glob_pattern_p, glob_pattern_p)
|
weak_alias (__glob_pattern_p, glob_pattern_p)
|
||||||
|
@ -1109,7 +1268,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
init_names.next = NULL;
|
init_names.next = NULL;
|
||||||
init_names.count = INITIAL_COUNT;
|
init_names.count = INITIAL_COUNT;
|
||||||
|
|
||||||
meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
|
meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
|
||||||
if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
|
if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
|
||||||
{
|
{
|
||||||
/* We need not do any tests. The PATTERN contains no meta
|
/* We need not do any tests. The PATTERN contains no meta
|
||||||
|
@ -1117,8 +1276,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
result will always contain exactly one name. */
|
result will always contain exactly one name. */
|
||||||
flags |= GLOB_NOCHECK;
|
flags |= GLOB_NOCHECK;
|
||||||
}
|
}
|
||||||
else if (meta == 0 &&
|
else if (meta == 0)
|
||||||
((flags & GLOB_NOESCAPE) || strchr (pattern, '\\') == NULL))
|
|
||||||
{
|
{
|
||||||
/* Since we use the normal file functions we can also use stat()
|
/* Since we use the normal file functions we can also use stat()
|
||||||
to verify the file is there. */
|
to verify the file is there. */
|
||||||
|
@ -1137,19 +1295,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
of the function to copy this name into the result. */
|
of the function to copy this name into the result. */
|
||||||
flags |= GLOB_NOCHECK;
|
flags |= GLOB_NOCHECK;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pattern[0] == '\0')
|
|
||||||
{
|
|
||||||
/* This is a special case for matching directories like in
|
|
||||||
"*a/". */
|
|
||||||
names->name[cur] = (char *) malloc (1);
|
|
||||||
if (names->name[cur] == NULL)
|
|
||||||
goto memory_error;
|
|
||||||
*names->name[cur++] = '\0';
|
|
||||||
nfound = 1;
|
|
||||||
meta = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stream = ((flags & GLOB_ALTDIRFUNC)
|
stream = ((flags & GLOB_ALTDIRFUNC)
|
||||||
|
@ -1161,7 +1306,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
&& ((errfunc != NULL && (*errfunc) (directory, errno))
|
&& ((errfunc != NULL && (*errfunc) (directory, errno))
|
||||||
|| (flags & GLOB_ERR)))
|
|| (flags & GLOB_ERR)))
|
||||||
return GLOB_ABORTED;
|
return GLOB_ABORTED;
|
||||||
meta = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1256,7 +1400,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (nfound == 0 && (flags & GLOB_NOCHECK))
|
if (nfound == 0 && (flags & GLOB_NOCHECK))
|
||||||
{
|
{
|
||||||
|
|
|
@ -706,6 +706,77 @@ if test $failed -ne 0; then
|
||||||
result=1
|
result=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
mkdir $testdir/'dir3*'
|
||||||
|
echo 1 > $testdir/'dir3*'/file1
|
||||||
|
mkdir $testdir/'dir4[a'
|
||||||
|
echo 2 > $testdir/'dir4[a'/file1
|
||||||
|
echo 3 > $testdir/'dir4[a'/file2
|
||||||
|
mkdir $testdir/'dir5[ab]'
|
||||||
|
echo 4 > $testdir/'dir5[ab]'/file1
|
||||||
|
echo 5 > $testdir/'dir5[ab]'/file2
|
||||||
|
mkdir $testdir/dir6
|
||||||
|
echo 6 > $testdir/dir6/'file1[a'
|
||||||
|
echo 7 > $testdir/dir6/'file1[ab]'
|
||||||
|
failed=0
|
||||||
|
v=`${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
|
||||||
|
${common_objpfx}posix/globtest "$testdir" 'dir3\*/file2'`
|
||||||
|
test "$v" != 'GLOB_NOMATCH' && echo "$v" >> $logfile && failed=1
|
||||||
|
${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
|
||||||
|
${common_objpfx}posix/globtest -c "$testdir" \
|
||||||
|
'dir3\*/file1' 'dir3\*/file2' 'dir1/file\1_1' 'dir1/file\1_9' \
|
||||||
|
'dir2\/' 'nondir\/' 'dir4[a/fil*1' 'di*r4[a/file2' 'dir5[ab]/file[12]' \
|
||||||
|
'dir6/fil*[a' 'dir*6/file1[a' 'dir6/fi*l[ab]' 'dir*6/file1[ab]' |
|
||||||
|
sort > $testout
|
||||||
|
cat <<"EOF" | $CMP - $testout >> $logfile || failed=1
|
||||||
|
`di*r4[a/file2'
|
||||||
|
`dir*6/file1[a'
|
||||||
|
`dir*6/file1[ab]'
|
||||||
|
`dir1/file1_1'
|
||||||
|
`dir1/file\1_9'
|
||||||
|
`dir2/'
|
||||||
|
`dir3*/file1'
|
||||||
|
`dir3\*/file2'
|
||||||
|
`dir4[a/fil*1'
|
||||||
|
`dir5[ab]/file[12]'
|
||||||
|
`dir6/fi*l[ab]'
|
||||||
|
`dir6/fil*[a'
|
||||||
|
`nondir\/'
|
||||||
|
EOF
|
||||||
|
HOME="$testdir" \
|
||||||
|
${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
|
||||||
|
${common_objpfx}posix/globtest -ct "$testdir" \
|
||||||
|
'~/dir1/file1_1' '~/dir1/file1_9' '~/dir3\*/file1' '~/dir3\*/file2' \
|
||||||
|
'~\/dir1/file1_2' |
|
||||||
|
sort > $testout
|
||||||
|
cat <<EOF | $CMP - $testout >> $logfile || failed=1
|
||||||
|
\`$testdir/dir1/file1_1'
|
||||||
|
\`$testdir/dir1/file1_2'
|
||||||
|
\`$testdir/dir3*/file1'
|
||||||
|
\`~/dir1/file1_9'
|
||||||
|
\`~/dir3\\*/file2'
|
||||||
|
EOF
|
||||||
|
if eval test -d ~"$USER"/; then
|
||||||
|
user=`echo "$USER" | sed -n -e 's/^\([^\\]\)\([^\\][^\\]*\)$/~\1\\\\\2/p'`
|
||||||
|
if test -n "$user"; then
|
||||||
|
${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
|
||||||
|
${common_objpfx}posix/globtest -ctq "$testdir" "$user/" |
|
||||||
|
sort > $testout
|
||||||
|
eval echo ~$USER/ | $CMP - $testout >> $logfile || failed=1
|
||||||
|
${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
|
||||||
|
${common_objpfx}posix/globtest -ctq "$testdir" "$user\\/" |
|
||||||
|
sort > $testout
|
||||||
|
eval echo ~$USER/ | $CMP - $testout >> $logfile || failed=1
|
||||||
|
${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
|
||||||
|
${common_objpfx}posix/globtest -ctq "$testdir" "$user" |
|
||||||
|
sort > $testout
|
||||||
|
eval echo ~$USER | $CMP - $testout >> $logfile || failed=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test $failed -ne 0; then
|
||||||
|
echo "Escape tests failed" >> $logfile
|
||||||
|
result=1
|
||||||
|
fi
|
||||||
|
|
||||||
if test $result -eq 0; then
|
if test $result -eq 0; then
|
||||||
chmod 777 $testdir/noread
|
chmod 777 $testdir/noread
|
||||||
rm -fr $testdir $testout
|
rm -fr $testdir $testout
|
||||||
|
|
Loading…
Reference in New Issue