diff options
author | Rich Felker <dalias@aerifal.cx> | 2017-10-21 12:17:49 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2017-10-21 12:32:16 -0400 |
commit | ec04d122f1182aeb91f39b0e80ae40c68e4d9605 (patch) | |
tree | ee67bcb20b9a98cde96c8aca065313f2274597a3 /src | |
parent | 004dc9549b8003288e635ba5aa91e3353e1974c4 (diff) | |
download | musl-ec04d122f1182aeb91f39b0e80ae40c68e4d9605.zip musl-ec04d122f1182aeb91f39b0e80ae40c68e4d9605.tar.gz musl-ec04d122f1182aeb91f39b0e80ae40c68e4d9605.tar.bz2 |
fix regression in glob with literal . or .. path component
commit 8c4be3e2209d2a1d3874b8bc2b474668fcbbbac6 was written to
preclude the GLOB_PERIOD extension from matching these directory
entries, but also precluded literal matches.
adjust the check that excludes . and .. to check whether the
GLOB_PERIOD flag is in effect, so that it cannot alter behavior in
cases governed by the standard, and also don't exclude . or .. in any
case where normal glob behavior (fnmatch's FNM_PERIOD flag) would have
included one or both of them (patterns such as ".*").
it's still not clear whether this is the preferred behavior for
GLOB_PERIOD, but at least it's clear that it can no longer break
applications which are not relying on quirks of a nonstandard feature.
Diffstat (limited to 'src')
-rw-r--r-- | src/regex/glob.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/regex/glob.c b/src/regex/glob.c index 6f8425c..8567198 100644 --- a/src/regex/glob.c +++ b/src/regex/glob.c @@ -100,9 +100,11 @@ static int match_in_dir(const char *d, const char *p, int flags, int (*errfunc)( continue; if (p2 && de->d_type && !S_ISDIR(de->d_type<<12) && !S_ISLNK(de->d_type<<12)) continue; - if (p2 && de->d_name[0]=='.' && !de->d_name[1]) - continue; - if (p2 && de->d_name[0]=='.' && de->d_name[1]=='.' && !de->d_name[2]) + /* With GLOB_PERIOD, don't allow matching . or .. unless + * fnmatch would match them with FNM_PERIOD rules in effect. */ + if (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.' + && (!de->d_name[1] || de->d_name[1]=='.' && !de->d_name[2]) + && fnmatch(p, de->d_name, fnm_flags | FNM_PERIOD)) continue; if (*d) { memcpy(name, d, l); |