Module Name: src
Committed By: martin
Date: Sun Nov 24 08:24:06 UTC 2019
Modified Files:
src/bin/sh [netbsd-9]: expand.c
Log Message:
Pull up following revision(s) (requested by kre in ticket #467):
bin/sh/expand.c: revision 1.133
Open code the validity test & copy of the character class name in
a bracket expression in a pattern (ie: [[:THISNAME:]]). Previously
the code used strspn() to look for invalid chars in the name, and
then memcpy(), now we do the test and copy a character at a time.
This might, or might not, be faster, but it now correctly handles
\ quoted characters in the name (' and " quoting were already
dealt with, \ was too in an earlier version, but when the \ handling
changes were made, this piece of code broke).
Not exactly a vital bug fix (who writes [[:\alpha:]] or similar?)
but it should work correctly regardless of how obscure the usage is.
Problem noted by Harald van Dijk
XXX pullup -9
To generate a diff of this commit:
cvs rdiff -u -r1.132 -r1.132.2.1 src/bin/sh/expand.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/bin/sh/expand.c
diff -u src/bin/sh/expand.c:1.132 src/bin/sh/expand.c:1.132.2.1
--- src/bin/sh/expand.c:1.132 Wed Apr 10 08:13:11 2019
+++ src/bin/sh/expand.c Sun Nov 24 08:24:06 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: expand.c,v 1.132 2019/04/10 08:13:11 kre Exp $ */
+/* $NetBSD: expand.c,v 1.132.2.1 2019/11/24 08:24:06 martin Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95";
#else
-__RCSID("$NetBSD: expand.c,v 1.132 2019/04/10 08:13:11 kre Exp $");
+__RCSID("$NetBSD: expand.c,v 1.132.2.1 2019/11/24 08:24:06 martin Exp $");
#endif
#endif /* not lint */
@@ -1792,24 +1792,44 @@ match_charclass(const char *p, wchar_t c
char name[20];
char *nameend;
wctype_t cclass;
+ char *q;
*end = NULL;
p++;
+ q = &name[0];
nameend = strstr(p, ":]");
if (nameend == NULL || nameend == p) /* not a valid class */
return 0;
- if (!is_alpha(*p) || strspn(p, /* '_' is a local extension */
- "0123456789" "_"
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ") != (size_t)(nameend - p))
+ if (*p == CTLESC) {
+ if (*++p == CTLESC)
+ return 0;
+ if (p == nameend)
+ return 0;
+ }
+ if (!is_alpha(*p))
return 0;
+ while (p < nameend) {
+ if (*p == CTLESC) {
+ p++;
+ if (p == nameend)
+ return 0;
+ }
+ if (!is_in_name(*p)) /* '_' is a local extension */
+ return 0;
+ if (q < &name[sizeof name])
+ *q++ = *p++;
+ else
+ p++;
+ }
*end = nameend + 2; /* committed to it being a char class */
- if ((size_t)(nameend - p) >= sizeof(name)) /* but too long */
- return 0; /* so no match */
- memcpy(name, p, nameend - p);
- name[nameend - p] = '\0';
+
+ if (q < &name[sizeof name]) /* a usable name found */
+ *q++ = '\0';
+ else /* too long, valid, but no match */
+ return 0;
+
cclass = wctype(name);
/* An unknown class matches nothing but is valid nevertheless. */
if (cclass == 0)