1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Skip '.' and '..' when globbing patterns like .*

There are convincing arguments why including '.' and '..' in the
result of pathname expansion is actively harmful. See:
https://www.austingroupbugs.net/view.php?id=1228
https://github.com/ksh93/ksh/issues/58#issuecomment-653716846

pdksh, mksh and zsh already skip these special traversal names
in all cases. This commit makes ksh act like these shells.

Since passing '.' and especially '..' as arguments to commands like
'chmod -R' and 'cp -r' may cause harm, this change seems likely to
fix more legacy scripts than it breaks. I'm unaware of anyone ever
having come up with a concrete use case for the old behaviour.

This change also fixes the bug that '.' and '..' failed to be
ignored as documented if FIGNORE is set.

src/lib/libast/misc/glob.c: glob_dir():
- Explicitly skip any matching '.' and '..' in all cases.

src/cmd/ksh93/tests/glob.sh:
- Add test_glob() tests for '*' and '.*'.

src/cmd/ksh93/sh.1: File Name Generation:
- Update to match new behaviour.

Resolves: https://github.com/ksh93/ksh/issues/58
This commit is contained in:
Martijn Dekker 2020-08-10 00:02:23 +01:00
parent be5ea8bbb2
commit 5312a59d5a
5 changed files with 25 additions and 7 deletions

8
NEWS
View file

@ -3,6 +3,14 @@ For full details, see the git log at: https://github.com/ksh93/ksh
Any uppercase BUG_* names are modernish shell bug IDs.
2020-08-09:
- File name generation (a.k.a. pathname expansion, a.k.a. globbing) now
never matches the special navigational names '.' (current directory) and
'..' (parent directory). This change makes a pattern like .* useful; it
now matches all hidden files (dotfiles) in the current directory, without
the harmful inclusion of '.' and '..'.
2020-08-08:
- Argument checking in the 'redirect' builtin command (see 2020-06-11) has

View file

@ -17,4 +17,4 @@
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#define SH_RELEASE "93u+m 2020-08-08"
#define SH_RELEASE "93u+m 2020-08-09"

View file

@ -2426,6 +2426,11 @@ that component of the filename is left unchanged unless
the pattern is prefixed with
.B \(ap(N)\fP
in which case it is removed as described below.
The special traversal names
.B .
and
.B ..
are never matched.
If
.SM
.B FIGNORE
@ -2435,11 +2440,6 @@ that matches the pattern defined by the value of
.SM
.B FIGNORE
is ignored when generating the matching filenames.
The names
.B .
and
.B ..
are also ignored.
If
.SM
.B FIGNORE

View file

@ -276,10 +276,18 @@ test_glob '<Beware> <abc> <abe> <bdir> <ca> <de> <man>' *
FIGNORE=
test_glob '<man/man1/sh.1>' */man*/sh.*
test_glob '<.x> <.y> <Beware> <a> <a-b> <aXb> <abc> <abd> <abe> <b> <bb> <bcd> <bdir> <c> <ca> <cb> <d> <dd> <de> <man>' *
test_glob '<.x> <.y>' .*
FIGNORE='@(*[abcd]*)'
test_glob '<.x> <.y>' *
test_glob '<.x> <.y>' .*
unset FIGNORE
test_glob '<bb> <ca> <cb> <dd> <de>' ??
test_glob '<man/man1/sh.1>' */man*/sh.*
test_glob '<Beware> <a> <a-b> <aXb> <abc> <abd> <abe> <b> <bb> <bcd> <bdir> <c> <ca> <cb> <d> <dd> <de> <man>' *
test_glob '<.x> <.y>' .*
GLOBIGNORE='.*:*'
set -- *

View file

@ -528,11 +528,13 @@ skip:
*restore2 = gp->gl_delim;
while ((name = (*gp->gl_dirnext)(gp, dirf)) && !*gp->gl_intr)
{
if (name[0] == '.' && (!name[1] || name[1] == '.' && !name[2]))
continue; /* do not ever match '.' or '..' */
if (notdir = (gp->gl_status & GLOB_NOTDIR))
gp->gl_status &= ~GLOB_NOTDIR;
if (ire && !regexec(ire, name, 0, NiL, 0))
continue;
if (matchdir && (name[0] != '.' || name[1] && (name[1] != '.' || name[2])) && !notdir)
if (matchdir && !notdir)
addmatch(gp, prefix, name, matchdir, NiL, anymeta);
if (!regexec(pre, name, 0, NiL, 0))
{