mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-11 12:40:42 +02:00
changes to handling of "." and ".." when dotglob is enabled; other minor changes
This commit is contained in:
+2
-44
@@ -1,6 +1,6 @@
|
||||
/* glob.c -- file-name wildcard pattern matching for Bash.
|
||||
|
||||
Copyright (C) 1985-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1985-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -304,35 +304,6 @@ skipname (pat, dname, flags)
|
||||
pat[0] != '.' && (pat[0] != '\\' || pat[1] != '.'))
|
||||
return 1;
|
||||
|
||||
/* Special checks for `.'. The only things that can match `.' are ".",
|
||||
"\.", ".*", and "\.*". We don't try to match everything here, just
|
||||
make sure that we don't let something obviously disqualifying by.
|
||||
We only do this if we're not negating the pattern. */
|
||||
else if ((flags & GX_NEGATE) == 0 && dname[0] == '.' && dname[1] == '\0')
|
||||
{
|
||||
if (pat[0] != '.' && (pat[0] != '\\' || pat[1] != '.'))
|
||||
return 1;
|
||||
i = (pat[0] == '.') ? 1 : 2;
|
||||
if (pat[i] && pat[i] != '*')
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* These are additional special checks for `..'. We let through "..",
|
||||
"\..", ".\.", "\.\.", ".*", ".?", "\.*", and "\.?".
|
||||
Disabled because it doesn't deal with things like `@(.).' at all. */
|
||||
else if (dname[0] == '.' && dname[1] == '.' && dname[2] == '\0')
|
||||
{
|
||||
if (pat[0] != '.' && (pat[0] != '\\' || pat[1] != '.')) /* [\]. */
|
||||
return 1;
|
||||
i = (pat[0] == '.') ? 1 : 2;
|
||||
if (pat[i] && (pat[i] == '*' || pat[i] == '?') && pat[i+1] == '\0')
|
||||
return 0; /* [\].[*?] */
|
||||
if (pat[i] != '.' && (pat[i] != '\\' || pat[i+1] != '.')) /* [\].[\]. */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -371,19 +342,6 @@ wskipname (pat, dname, flags)
|
||||
pat[0] != L'.' && (pat[0] != L'\\' || pat[1] != L'.'))
|
||||
return 1;
|
||||
|
||||
/* Special checks for `.'. The only things that can match `.' are ".",
|
||||
"\.", ".*", and "\.*". We don't try to match everything here, just
|
||||
make sure that we don't let something obviously disqualifying by.
|
||||
We only do this if we're not negating the pattern. */
|
||||
else if ((flags & GX_NEGATE) == 0 && dname[0] == L'.' && dname[1] == L'\0')
|
||||
{
|
||||
if (pat[0] != L'.' && (pat[0] != L'\\' || pat[1] != L'.'))
|
||||
return 1;
|
||||
i = (pat[0] == L'.') ? 1 : 2;
|
||||
if (pat[i] != L'\0' && pat[i] != L'*')
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -848,7 +806,7 @@ glob_vector (pat, dir, flags)
|
||||
|
||||
/* Compute the flags that will be passed to strmatch(). We don't
|
||||
need to do this every time through the loop. */
|
||||
mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
|
||||
mflags = (noglob_dot_filenames ? FNM_PERIOD : FNM_DOTDOT) | FNM_PATHNAME;
|
||||
|
||||
#ifdef FNM_CASEFOLD
|
||||
if (glob_ignore_case)
|
||||
|
||||
+43
-8
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -83,6 +83,7 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
||||
|
||||
#ifdef EXTENDED_GLOB
|
||||
/* EXTMATCH () will handle recursively calling GMATCH, so we can
|
||||
|
||||
just return what EXTMATCH() returns. */
|
||||
if ((flags & FNM_EXTMATCH) && *p == L('(') &&
|
||||
(c == L('+') || c == L('*') || c == L('?') || c == L('@') || c == L('!'))) /* ) */
|
||||
@@ -90,7 +91,7 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
||||
int lflags;
|
||||
/* If we're not matching the start of the string, we're not
|
||||
concerned about the special cases for matching `.' */
|
||||
lflags = (n == string) ? flags : (flags & ~FNM_PERIOD);
|
||||
lflags = (n == string) ? flags : (flags & ~(FNM_PERIOD|FNM_DOTDOT));
|
||||
return (EXTMATCH (c, n, se, p, pe, lflags));
|
||||
}
|
||||
#endif /* EXTENDED_GLOB */
|
||||
@@ -109,6 +110,15 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
||||
string or if it is the first character following a slash and
|
||||
we are matching a pathname. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
/* `?' cannot match `.' or `..' if it is the first character of the
|
||||
string or if it is the first character following a slash and
|
||||
we are matching a pathname. */
|
||||
if ((flags & FNM_DOTDOT) &&
|
||||
((n == string && SDOT_OR_DOTDOT(n)) ||
|
||||
((flags & FNM_PATHNAME) && n[-1] == L('/') && PDOT_OR_DOTDOT(n))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
break;
|
||||
|
||||
case L('\\'): /* backslash escape removes special meaning */
|
||||
@@ -147,6 +157,14 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
||||
we are matching a pathname. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
/* `*' cannot match `.' or `..' if it is the first character of the
|
||||
string or if it is the first character following a slash and
|
||||
we are matching a pathname. */
|
||||
if ((flags & FNM_DOTDOT) &&
|
||||
((n == string && SDOT_OR_DOTDOT(n)) ||
|
||||
((flags & FNM_PATHNAME) && n[-1] == L('/') && PDOT_OR_DOTDOT(n))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (p == pe)
|
||||
return 0;
|
||||
|
||||
@@ -288,7 +306,7 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
||||
continue;
|
||||
|
||||
/* Otherwise, we just recurse. */
|
||||
if (GMATCH (n, se, p, pe, &end, flags & ~FNM_PERIOD) == 0)
|
||||
if (GMATCH (n, se, p, pe, &end, flags & ~(FNM_PERIOD|FNM_DOTDOT)) == 0)
|
||||
{
|
||||
if (end.pattern == NULL)
|
||||
return (0);
|
||||
@@ -321,6 +339,14 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
||||
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
/* `?' cannot match `.' or `..' if it is the first character of the
|
||||
string or if it is the first character following a slash and
|
||||
we are matching a pathname. */
|
||||
if ((flags & FNM_DOTDOT) &&
|
||||
((n == string && SDOT_OR_DOTDOT(n)) ||
|
||||
((flags & FNM_PATHNAME) && n[-1] == L('/') && PDOT_OR_DOTDOT(n))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
p = BRACKMATCH (p, sc, flags);
|
||||
if (p == 0)
|
||||
return FNM_NOMATCH;
|
||||
@@ -843,7 +869,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
|
||||
if (m1)
|
||||
{
|
||||
/* if srest > s, we are not at start of string */
|
||||
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
|
||||
xflags = (srest > s) ? (flags & ~(FNM_PERIOD|FNM_DOTDOT)) : flags;
|
||||
m2 = (GMATCH (srest, se, prest, pe, NULL, xflags) == 0) ||
|
||||
(s != srest && GMATCH (srest, se, p - 1, pe, NULL, xflags) == 0);
|
||||
}
|
||||
@@ -873,7 +899,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
|
||||
for ( ; srest <= se; srest++)
|
||||
{
|
||||
/* if srest > s, we are not at start of string */
|
||||
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
|
||||
xflags = (srest > s) ? (flags & ~(FNM_PERIOD|FNM_DOTDOT)) : flags;
|
||||
if (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0 &&
|
||||
GMATCH (srest, se, prest, pe, NULL, xflags) == 0)
|
||||
return (0);
|
||||
@@ -899,12 +925,17 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
|
||||
|
||||
/* If nothing matched, but the string starts with a period and we
|
||||
need to match periods explicitly, don't return this as a match,
|
||||
even for negation. Might need to do this only if srest == s. */
|
||||
if (m1 == 0 && *s == '.' && (flags & FNM_PERIOD))
|
||||
even for negation. */
|
||||
if (m1 == 0 && (flags & FNM_PERIOD) && *s == '.')
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
if (m1 == 0 && (flags & FNM_DOTDOT) &&
|
||||
(SDOT_OR_DOTDOT (s) ||
|
||||
((flags & FNM_PATHNAME) && s[-1] == L('/') && PDOT_OR_DOTDOT(s))))
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
/* if srest > s, we are not at start of string */
|
||||
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
|
||||
xflags = (srest > s) ? (flags & ~(FNM_PERIOD|FNM_DOTDOT)) : flags;
|
||||
if (m1 == 0 && GMATCH (srest, se, prest, pe, NULL, xflags) == 0)
|
||||
return (0);
|
||||
}
|
||||
@@ -939,4 +970,8 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
|
||||
#undef MEMCHR
|
||||
#undef COLLEQUIV
|
||||
#undef RANGECMP
|
||||
#undef ISDIRSEP
|
||||
#undef PATHSEP
|
||||
#undef PDOT_OR_DOTDOT
|
||||
#undef SDOT_OR_DOTDOT
|
||||
#undef L
|
||||
|
||||
+22
-1
@@ -1,7 +1,7 @@
|
||||
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
|
||||
globbing. */
|
||||
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -308,6 +308,16 @@ is_cclass (c, name)
|
||||
? TOLOWER ((unsigned char)c) \
|
||||
: ((unsigned char)c))
|
||||
|
||||
#if !defined (__CYGWIN__)
|
||||
# define ISDIRSEP(c) ((c) == '/')
|
||||
#else
|
||||
# define ISDIRSEP(c) ((c) == '/' || (c) == '\\')
|
||||
#endif /* __CYGWIN__ */
|
||||
#define PATHSEP(c) (ISDIRSEP(c) || (c) == 0)
|
||||
|
||||
# define PDOT_OR_DOTDOT(s) (s[0] == '.' && (PATHSEP (s[1]) || (s[1] == '.' && PATHSEP (s[2]))))
|
||||
# define SDOT_OR_DOTDOT(s) (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
|
||||
|
||||
#define FCT internal_strmatch
|
||||
#define GMATCH gmatch
|
||||
#define COLLSYM collsym
|
||||
@@ -553,6 +563,17 @@ posix_cclass_only (pattern)
|
||||
|
||||
/* Now include `sm_loop.c' for multibyte characters. */
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c))
|
||||
|
||||
# if !defined (__CYGWIN__)
|
||||
# define ISDIRSEP(c) ((c) == L'/')
|
||||
# else
|
||||
# define ISDIRSEP(c) ((c) == L'/' || (c) == L'\\')
|
||||
# endif /* __CYGWIN__ */
|
||||
# define PATHSEP(c) (ISDIRSEP(c) || (c) == L'\0')
|
||||
|
||||
# define PDOT_OR_DOTDOT(w) (w[0] == L'.' && (PATHSEP(w[1]) || (w[1] == L'.' && PATHSEP(w[2]))))
|
||||
# define SDOT_OR_DOTDOT(w) (w[0] == L'.' && (w[1] == L'\0' || (w[1] == L'.' && w[2] == L'\0')))
|
||||
|
||||
#define FCT internal_wstrmatch
|
||||
#define GMATCH gmatch_wc
|
||||
#define COLLSYM collwcsym
|
||||
|
||||
+2
-1
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
|
||||
|
||||
#define FNM_FIRSTCHAR (1 << 6) /* Match only the first character */
|
||||
#define FNM_DOTDOT (1 << 7) /* force `.' and `..' to match explicitly even if FNM_PERIOD not supplied. */
|
||||
|
||||
/* Value returned by `strmatch' if STRING does not match PATTERN. */
|
||||
#undef FNM_NOMATCH
|
||||
|
||||
@@ -1598,7 +1598,7 @@ puts_face (const char *str, const char *face, int n)
|
||||
char cur_face;
|
||||
|
||||
for (cur_face = FACE_NORMAL, i = 0; i < n; i++)
|
||||
putc_face (str[i], face[i], &cur_face);
|
||||
putc_face ((unsigned char) str[i], face[i], &cur_face);
|
||||
putc_face (EOF, FACE_NORMAL, &cur_face);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user