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)