Configuration Information [Automatically generated, do not change]:
Machine: i386
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i386' -DCONF_OSTYPE='linux-gnu'
-DCONF_MACHTYPE='i386-pc-linux-gnu' -DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H
-D_FILE_OFFSET_BITS=64 -I. -I/usr/include
-I/home/swt/doko/export/packages/bash/bash-2.04
-I/home/swt/doko/export/packages/bash/bash-2.04/include
-I/home/swt/doko/export/packages/bash/bash-2.04/lib -I/usr/include -g -O2
uname output: Linux nostromo 2.2.14 #1 Thu Jan 13 05:18:09 MST 2000 i686 unknown
Machine Type: i386-pc-linux-gnu
Bash Version: 2.04
Patch Level: 0
Release Status: beta5
Description:
Bash behaves incorrectly on
case "/tmp" in
[/\\]*) exit 0;;
esac
exit 1
the problem is that fnmatch.c is buggy (details below in the ChangeLog
entry).
This bug is observed with 2.03 too, not tested with older bashes.
Repeat-By:
See above.
Fix:
--- ChangeLog~ Tue Mar 23 18:44:35 1993
+++ ChangeLog Tue Mar 28 13:42:48 2000
@@ -1,3 +1,14 @@
+2000-03-28 Akim Demaille <[EMAIL PROTECTED]>
+
+ fnmatch ("/tmp", "[/\\\\]*]") fails to match, because when the `/'
+ is matched, when brackmatch tries to skip the end of the
+ characters list, it misses one of the `\', hence skips `\]' and
+ then `*', and stops at `\0'. Then it tries to fnmatch ("tmp", ""),
+ which fails.
+
+ * fnmatch.c (brackmatch) [matched]: Instead of trying to use the
+ current `c', just step back from one character in `p'.
+
Thu Oct 29 08:58:12 1992 Brian Fox (bfox@cubit)
* glob.c (glob_filename): Fix tiny memory leak. Rework some
--- fnmatch.c~ Wed Sep 22 22:31:02 1999
+++ fnmatch.c Tue Mar 28 13:28:14 2000
@@ -4,17 +4,17 @@
/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
-
+
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
-
+
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-
+
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
@@ -22,7 +22,7 @@
#include <config.h>
#include <stdio.h> /* for debugging */
-
+
#include "fnmatch.h"
#include "collsyms.h"
#include <ctype.h>
@@ -39,7 +39,7 @@
static int extmatch ();
static char *patscan ();
#endif
-
+
#if !defined (isascii)
# define isascii(c) ((unsigned int)(c) <= 0177)
#endif
@@ -222,7 +222,7 @@
case '*': /* Match zero or more characters */
if (p == pe)
return 0;
-
+
if ((flags & FNM_PERIOD) && sc == '.' &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
/* `*' cannot match a `.' if it is the first character of the
@@ -339,7 +339,7 @@
if ((flags & FNM_LEADING_DIR) && *n == '/')
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
return 0;
-
+
return (FNM_NOMATCH);
}
@@ -355,7 +355,7 @@
int val;
p++; /* move past the `.' */
-
+
for (pc = 0; p[pc]; pc++)
if (p[pc] == '.' && p[pc+1] == ']')
break;
@@ -384,7 +384,7 @@
circumflex (`^') in its role in a `nonmatching list'. A bracket
expression starging with an unquoted circumflex character produces
unspecified results. This implementation treats the two identically. */
- if (not = (*p == '!' || *p == '^'))
+ if ((not = (*p == '!' || *p == '^')))
++p;
c = *p++;
@@ -460,7 +460,7 @@
continue;
}
}
-
+
/* POSIX.2 collating symbols. See POSIX.2 2.8.3.2. Find the end of
the symbol name, make sure it is terminated by `.]', translate
the name to a character using the external table, and do the
@@ -545,7 +545,8 @@
matched:
/* Skip the rest of the [...] that already matched. */
- brcnt = (c != ']') + (c == '[' && (*p == '=' || *p == ':' || *p == '.'));
+ c = *--p;
+ brcnt = 1;
while (brcnt > 0)
{
/* A `[' without a matching `]' is just another character to match. */
@@ -759,13 +760,13 @@
{
pnext = patscan (psub, pe, '|');
/* If one of the patterns matches, just bail immediately. */
- if (m1 = (gmatch (s, srest, psub, pnext - 1, flags) == 0))
+ if ((m1 = (gmatch (s, srest, psub, pnext - 1, flags) == 0)))
break;
if (pnext == prest)
break;
}
if (m1 == 0 && gmatch (srest, se, prest, pe, flags) == 0)
- return (0);
+ return (0);
}
return (FNM_NOMATCH);
}
Comments:
I was wondering why the libc and bash don't share the same source for
fnmatch. I can see there are extensions which are only in bash, but why
not moving them into glibc too?
Akim