Subject: Re: bin/22846
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, jmmv@menta.net>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 10/11/2006 06:10:02
The following reply was made to PR bin/22846; it has been noted by GNATS.
From: Christian Biere <christianbiere@gmx.de>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/22846
Date: Wed, 11 Oct 2006 08:08:05 +0200
Christian Biere wrote:
> There's a way to convince ksh to expand filenames with brackets:
>
> $ touch '[foo]'
> $ touch '[bar]'
> $ ls \[\[]f<tab>
The reason this works is that x_file_glob() strips all backslashes,
thus glob() will see [[]f whis is a literal '[f' as desired.
The following partial patch fixes cases like the above but not
those which require multiple tab completions:
$ touch '[foo].bak'
$ ls [f<tab> # expands too \[foo\]
$ ls \[foo\].<tab> # does not expand
Obviously, due to the internal stripped backslashes [foo].<tab>
won't expand because there is no matching file. However, even
if the backslashes are kept, yylex() does record these as
literal characters instead of marking the following character
as quoted.
The partial patch simply adds a check to see whether there
is an unquoted '[' is followed by an unquoted ']'. If not,
the '[' does not initiate a glob pattern.
--- bin/ksh/edit.c 2006-10-08 05:29:36.000000000 +0200
+++ bin/ksh/edit.c 2006-10-11 07:49:55.000000000 +0200
@@ -880,7 +880,7 @@
for (s = toglob; *s; s++) {
if (*s == '\\' && s[1])
s++;
- else if (*s == '*' || *s == '[' || *s == '?' || *s == '$'
+ else if (*s == '*' || *s == '?' || *s == '$'
|| (s[1] == '(' /*)*/ && strchr("*+?@!", *s)))
break;
else if (ISDIRSEP(*s))
--- bin/ksh/eval.c 2006-05-23 16:45:10.000000000 +0200
+++ bin/ksh/eval.c 2006-10-11 06:48:51.000000000 +0200
@@ -605,6 +605,21 @@
if (!quote)
switch (c) {
case '[':
+ {
+ const char *p = sp;
+ bool_t special = FALSE;
+ while (*p != EOS) {
+ if (p[0] == CHAR &&
+ p[1] == ']') {
+ special = TRUE;
+ break;
+ }
+
+ p += 2;
+ }
+ if (!special)
+ break;
+ }
case NOT:
case '-':
case ']':