Module Name: src Committed By: kre Date: Fri Jun 22 18:19:41 UTC 2018
Modified Files: src/bin/sh: expand.c Log Message: When processing character classes ([:xxx:] inside []), treat a class name that is longer than we can handle the same way we treat an unknown class name (as a valid char class which contains nothing, so never matches). Previously a "too long" class name invalidated the class, so [:very-long-name:] would match any of '[' ':' 'v' ... (note: "very-long-name" is not long enough to trigger this, but you get the idea!) However, the name itself has a restricted syntax ([[:***:]] is not a character class, it is a match for one of a '[' ':' or '*', followed by a ']') which we did not implement - check the syntax of the name before treating it as a character class (but we do add '_' to alphanumerics as legal class name characters). To generate a diff of this commit: cvs rdiff -u -r1.122 -r1.123 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.122 src/bin/sh/expand.c:1.123 --- src/bin/sh/expand.c:1.122 Fri Jun 22 17:22:34 2018 +++ src/bin/sh/expand.c Fri Jun 22 18:19:41 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: expand.c,v 1.122 2018/06/22 17:22:34 kre Exp $ */ +/* $NetBSD: expand.c,v 1.123 2018/06/22 18:19:41 kre 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.122 2018/06/22 17:22:34 kre Exp $"); +__RCSID("$NetBSD: expand.c,v 1.123 2018/06/22 18:19:41 kre Exp $"); #endif #endif /* not lint */ @@ -1659,12 +1659,20 @@ match_charclass(const char *p, wchar_t c *end = NULL; p++; nameend = strstr(p, ":]"); - if (nameend == NULL || (size_t)(nameend - p) >= sizeof(name) || - nameend == 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)) + return 0; + + *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'; - *end = nameend + 2; cclass = wctype(name); /* An unknown class matches nothing but is valid nevertheless. */ if (cclass == 0) @@ -1673,7 +1681,6 @@ match_charclass(const char *p, wchar_t c } - /* * Returns true if the pattern matches the string. */