Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh Open code the validity test & copy of the character c...



details:   https://anonhg.NetBSD.org/src/rev/60e3a2a8594d
branches:  trunk
changeset: 464471:60e3a2a8594d
user:      kre <kre%NetBSD.org@localhost>
date:      Tue Oct 08 03:52:44 2019 +0000

description:
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

diffstat:

 bin/sh/expand.c |  42 +++++++++++++++++++++++++++++++-----------
 1 files changed, 31 insertions(+), 11 deletions(-)

diffs (72 lines):

diff -r 885bf6fb600e -r 60e3a2a8594d bin/sh/expand.c
--- a/bin/sh/expand.c   Tue Oct 08 03:16:21 2019 +0000
+++ b/bin/sh/expand.c   Tue Oct 08 03:52:44 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: expand.c,v 1.132 2019/04/10 08:13:11 kre Exp $ */
+/*     $NetBSD: expand.c,v 1.133 2019/10/08 03:52:44 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.132 2019/04/10 08:13:11 kre Exp $");
+__RCSID("$NetBSD: expand.c,v 1.133 2019/10/08 03:52:44 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -1792,24 +1792,44 @@
        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 (q < &name[sizeof name])     /* a usable name found */
+               *q++ = '\0';
+       else                            /* too long, valid, but no match */
                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';
        cclass = wctype(name);
        /* An unknown class matches nothing but is valid nevertheless. */
        if (cclass == 0)



Home | Main Index | Thread Index | Old Index