| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: expand.c,v 1.132 2019/04/10 08:13:11 kre Exp $ */ | | 1 | /* $NetBSD: expand.c,v 1.133 2019/10/08 03:52:44 kre Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1991, 1993 | | 4 | * Copyright (c) 1991, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Kenneth Almquist. | | 8 | * Kenneth Almquist. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | * SUCH DAMAGE. | | 32 | * SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | #ifndef lint | | 36 | #ifndef lint |
37 | #if 0 | | 37 | #if 0 |
38 | static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; | | 38 | static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; |
39 | #else | | 39 | #else |
40 | __RCSID("$NetBSD: expand.c,v 1.132 2019/04/10 08:13:11 kre Exp $"); | | 40 | __RCSID("$NetBSD: expand.c,v 1.133 2019/10/08 03:52:44 kre Exp $"); |
41 | #endif | | 41 | #endif |
42 | #endif /* not lint */ | | 42 | #endif /* not lint */ |
43 | | | 43 | |
44 | #include <sys/types.h> | | 44 | #include <sys/types.h> |
45 | #include <sys/time.h> | | 45 | #include <sys/time.h> |
46 | #include <sys/stat.h> | | 46 | #include <sys/stat.h> |
47 | #include <errno.h> | | 47 | #include <errno.h> |
48 | #include <dirent.h> | | 48 | #include <dirent.h> |
49 | #include <unistd.h> | | 49 | #include <unistd.h> |
50 | #include <pwd.h> | | 50 | #include <pwd.h> |
51 | #include <limits.h> | | 51 | #include <limits.h> |
52 | #include <stdlib.h> | | 52 | #include <stdlib.h> |
53 | #include <stdio.h> | | 53 | #include <stdio.h> |
| @@ -1782,44 +1782,64 @@ msort(struct strlist *list, int len) | | | @@ -1782,44 +1782,64 @@ msort(struct strlist *list, int len) |
1782 | /* | | 1782 | /* |
1783 | * See if a character matches a character class, starting at the first colon | | 1783 | * See if a character matches a character class, starting at the first colon |
1784 | * of "[:class:]". | | 1784 | * of "[:class:]". |
1785 | * If a valid character class is recognized, a pointer to the next character | | 1785 | * If a valid character class is recognized, a pointer to the next character |
1786 | * after the final closing bracket is stored into *end, otherwise a null | | 1786 | * after the final closing bracket is stored into *end, otherwise a null |
1787 | * pointer is stored into *end. | | 1787 | * pointer is stored into *end. |
1788 | */ | | 1788 | */ |
1789 | static int | | 1789 | static int |
1790 | match_charclass(const char *p, wchar_t chr, const char **end) | | 1790 | match_charclass(const char *p, wchar_t chr, const char **end) |
1791 | { | | 1791 | { |
1792 | char name[20]; | | 1792 | char name[20]; |
1793 | char *nameend; | | 1793 | char *nameend; |
1794 | wctype_t cclass; | | 1794 | wctype_t cclass; |
| | | 1795 | char *q; |
1795 | | | 1796 | |
1796 | *end = NULL; | | 1797 | *end = NULL; |
1797 | p++; | | 1798 | p++; |
| | | 1799 | q = &name[0]; |
1798 | nameend = strstr(p, ":]"); | | 1800 | nameend = strstr(p, ":]"); |
1799 | if (nameend == NULL || nameend == p) /* not a valid class */ | | 1801 | if (nameend == NULL || nameend == p) /* not a valid class */ |
1800 | return 0; | | 1802 | return 0; |
1801 | | | 1803 | |
1802 | if (!is_alpha(*p) || strspn(p, /* '_' is a local extension */ | | 1804 | if (*p == CTLESC) { |
1803 | "0123456789" "_" | | 1805 | if (*++p == CTLESC) |
1804 | "abcdefghijklmnopqrstuvwxyz" | | 1806 | return 0; |
1805 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ") != (size_t)(nameend - p)) | | 1807 | if (p == nameend) |
| | | 1808 | return 0; |
| | | 1809 | } |
| | | 1810 | if (!is_alpha(*p)) |
1806 | return 0; | | 1811 | return 0; |
| | | 1812 | while (p < nameend) { |
| | | 1813 | if (*p == CTLESC) { |
| | | 1814 | p++; |
| | | 1815 | if (p == nameend) |
| | | 1816 | return 0; |
| | | 1817 | } |
| | | 1818 | if (!is_in_name(*p)) /* '_' is a local extension */ |
| | | 1819 | return 0; |
| | | 1820 | if (q < &name[sizeof name]) |
| | | 1821 | *q++ = *p++; |
| | | 1822 | else |
| | | 1823 | p++; |
| | | 1824 | } |
1807 | | | 1825 | |
1808 | *end = nameend + 2; /* committed to it being a char class */ | | 1826 | *end = nameend + 2; /* committed to it being a char class */ |
1809 | if ((size_t)(nameend - p) >= sizeof(name)) /* but too long */ | | 1827 | |
1810 | return 0; /* so no match */ | | 1828 | if (q < &name[sizeof name]) /* a usable name found */ |
1811 | memcpy(name, p, nameend - p); | | 1829 | *q++ = '\0'; |
1812 | name[nameend - p] = '\0'; | | 1830 | else /* too long, valid, but no match */ |
| | | 1831 | return 0; |
| | | 1832 | |
1813 | cclass = wctype(name); | | 1833 | cclass = wctype(name); |
1814 | /* An unknown class matches nothing but is valid nevertheless. */ | | 1834 | /* An unknown class matches nothing but is valid nevertheless. */ |
1815 | if (cclass == 0) | | 1835 | if (cclass == 0) |
1816 | return 0; | | 1836 | return 0; |
1817 | return iswctype(chr, cclass); | | 1837 | return iswctype(chr, cclass); |
1818 | } | | 1838 | } |
1819 | | | 1839 | |
1820 | | | 1840 | |
1821 | /* | | 1841 | /* |
1822 | * Returns true if the pattern matches the string. | | 1842 | * Returns true if the pattern matches the string. |
1823 | */ | | 1843 | */ |
1824 | | | 1844 | |
1825 | STATIC int | | 1845 | STATIC int |