about summary refs log tree commit diff
path: root/src/regex
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-04-26 12:24:44 -0400
committerRich Felker <dalias@aerifal.cx>2012-04-26 12:24:44 -0400
commit2b87a5db82833c6d148b70d29a33cd51fff491e3 (patch)
tree52983138a2f743eb652386367b5f8313f7317b50 /src/regex
parent0bd7ac05d1c6691a7ff33c0145adcafb4f4803df (diff)
downloadmusl-2b87a5db82833c6d148b70d29a33cd51fff491e3.tar.gz
musl-2b87a5db82833c6d148b70d29a33cd51fff491e3.tar.xz
musl-2b87a5db82833c6d148b70d29a33cd51fff491e3.zip
update fnmatch to POSIX 2008 semantics
an invalid bracket expression must be treated as if the opening
bracket were just a literal character. this is to fix a bug whereby
POSIX left the behavior of the "[" shell command undefined due to it
being an invalid bracket expression.
Diffstat (limited to 'src/regex')
-rw-r--r--src/regex/fnmatch.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/regex/fnmatch.c b/src/regex/fnmatch.c
index c0856f99..81f0c7bd 100644
--- a/src/regex/fnmatch.c
+++ b/src/regex/fnmatch.c
@@ -53,6 +53,7 @@ int fnmatch(const char *p, const char *s, int flags)
 	int first;
 	int no_slash = (flags & FNM_PATHNAME) ? '/' : 0;
 	int no_period = (flags & FNM_PERIOD) && !(flags & __FNM_CONT) ? '.' : 0x100;
+	const char *p1;
 
 	flags |= __FNM_CONT;
 
@@ -84,6 +85,7 @@ int fnmatch(const char *p, const char *s, int flags)
 					break;
 			return FNM_NOMATCH;
 		case '[':
+			p1 = p-1;
 			not = (*p == '!' || *p == '^');
 			if (not) p++;
 			k = next(&s);
@@ -92,7 +94,7 @@ int fnmatch(const char *p, const char *s, int flags)
 			match = 0;
 			first = 1;
 			for (;;) {
-				if (!*p) return FNM_NOMATCH;
+				if (!*p) goto literal_bracket;
 				if (*p == ']' && !first) break;
 				first = 0;
 				if (*p == '[' && *(p+1) == ':') {
@@ -112,15 +114,20 @@ int fnmatch(const char *p, const char *s, int flags)
 					continue;
 				}
 				c = bracket_next(&p);
-				if (c == BRACKET_ERROR)
-					return FNM_NOMATCH;
+				if (c == BRACKET_ERROR) {
+literal_bracket:
+					match = (k=='[');
+					p = p1;
+					not = 0;
+					break;
+				}
 				if (c == BRACKET_NOCHAR)
 					continue;
 				if (*p == '-' && *(p+1) != ']') {
 					p++;
 					d = bracket_next(&p);
 					if (d == BRACKET_ERROR)
-						return FNM_NOMATCH;
+						goto literal_bracket;
 					if (d == BRACKET_NOCHAR)
 						continue;
 					if (k >= c && k <= d)