From owner-svn-src-head@freebsd.org Thu Jul 14 08:18:13 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E2542B93F15; Thu, 14 Jul 2016 08:18:13 +0000 (UTC) (envelope-from ache@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A1CBC1F38; Thu, 14 Jul 2016 08:18:13 +0000 (UTC) (envelope-from ache@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u6E8ICwh001970; Thu, 14 Jul 2016 08:18:12 GMT (envelope-from ache@FreeBSD.org) Received: (from ache@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u6E8ICRo001964; Thu, 14 Jul 2016 08:18:12 GMT (envelope-from ache@FreeBSD.org) Message-Id: <201607140818.u6E8ICRo001964@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ache set sender to ache@FreeBSD.org using -f From: "Andrey A. Chernov" Date: Thu, 14 Jul 2016 08:18:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r302820 - in head/lib/libc: gen locale regex stdio X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jul 2016 08:18:14 -0000 Author: ache Date: Thu Jul 14 08:18:12 2016 New Revision: 302820 URL: https://svnweb.freebsd.org/changeset/base/302820 Log: Back out non-collating [a-z] ranges. Instead of changing whole course to another POSIX-permitted way for consistency and uniformity I decide to completely ignore missing regex fucntionality and concentrace on fixing bugs in what we have now, too many small obstacles instead, counting ports. Modified: head/lib/libc/gen/fnmatch.c head/lib/libc/gen/glob.c head/lib/libc/locale/collate.h head/lib/libc/locale/collcmp.c head/lib/libc/regex/regcomp.c head/lib/libc/stdio/vfscanf.c Modified: head/lib/libc/gen/fnmatch.c ============================================================================== --- head/lib/libc/gen/fnmatch.c Thu Jul 14 08:15:13 2016 (r302819) +++ head/lib/libc/gen/fnmatch.c Thu Jul 14 08:18:12 2016 (r302820) @@ -63,6 +63,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "collate.h" + #define EOS '\0' #define RANGE_MATCH 1 @@ -236,6 +238,8 @@ rangematch(const char *pattern, wchar_t wchar_t c, c2; size_t pclen; const char *origpat; + struct xlocale_collate *table = + (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; /* * A bracket expression starting with an unquoted circumflex @@ -290,7 +294,11 @@ rangematch(const char *pattern, wchar_t if (flags & FNM_CASEFOLD) c2 = towlower(c2); - if (c <= test && test <= c2) + if (table->__collate_load_error ? + c <= test && test <= c2 : + __wcollate_range_cmp(table, c, test) <= 0 + && __wcollate_range_cmp(table, test, c2) <= 0 + ) ok = 1; } else if (c == test) ok = 1; Modified: head/lib/libc/gen/glob.c ============================================================================== --- head/lib/libc/gen/glob.c Thu Jul 14 08:15:13 2016 (r302819) +++ head/lib/libc/gen/glob.c Thu Jul 14 08:18:12 2016 (r302820) @@ -92,6 +92,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "collate.h" + /* * glob(3) expansion limits. Stop the expansion if any of these limits * is reached. This caps the runtime in the face of DoS attacks. See @@ -802,6 +804,8 @@ match(Char *name, Char *pat, Char *paten { int ok, negate_range; Char c, k; + struct xlocale_collate *table = + (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; while (pat < patend) { c = *pat++; @@ -826,7 +830,11 @@ match(Char *name, Char *pat, Char *paten ++pat; while (((c = *pat++) & M_MASK) != M_END) if ((*pat & M_MASK) == M_RNG) { - if (CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1])) + if (table->__collate_load_error ? + CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) : + __wcollate_range_cmp(table, CHAR(c), CHAR(k)) <= 0 + && __wcollate_range_cmp(table, CHAR(k), CHAR(pat[1])) <= 0 + ) ok = 1; pat += 2; } else if (c == k) Modified: head/lib/libc/locale/collate.h ============================================================================== --- head/lib/libc/locale/collate.h Thu Jul 14 08:15:13 2016 (r302819) +++ head/lib/libc/locale/collate.h Thu Jul 14 08:18:12 2016 (r302820) @@ -128,7 +128,8 @@ int __collate_load_tables(const char *); int __collate_equiv_value(locale_t, const wchar_t *, size_t); void _collate_lookup(struct xlocale_collate *,const wchar_t *, int *, int *, int, const int **); -int __collate_range_cmp(int, int); +int __collate_range_cmp(struct xlocale_collate *, char, char); +int __wcollate_range_cmp(struct xlocale_collate *, wchar_t, wchar_t); size_t _collate_wxfrm(struct xlocale_collate *, const wchar_t *, wchar_t *, size_t); size_t _collate_sxfrm(struct xlocale_collate *, const wchar_t *, char *, Modified: head/lib/libc/locale/collcmp.c ============================================================================== --- head/lib/libc/locale/collcmp.c Thu Jul 14 08:15:13 2016 (r302819) +++ head/lib/libc/locale/collcmp.c Thu Jul 14 08:18:12 2016 (r302820) @@ -33,13 +33,15 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include "collate.h" /* * Compare two characters using collate */ -int __collate_range_cmp(int c1, int c2) +int __collate_range_cmp(struct xlocale_collate *table, char c1, char c2) { char s1[2], s2[2]; @@ -47,5 +49,20 @@ int __collate_range_cmp(int c1, int c2) s1[1] = '\0'; s2[0] = c2; s2[1] = '\0'; - return (strcoll(s1, s2)); + struct _xlocale l = {{0}}; + l.components[XLC_COLLATE] = (struct xlocale_component *)table; + return (strcoll_l(s1, s2, &l)); +} + +int __wcollate_range_cmp(struct xlocale_collate *table, wchar_t c1, wchar_t c2) +{ + wchar_t s1[2], s2[2]; + + s1[0] = c1; + s1[1] = L'\0'; + s2[0] = c2; + s2[1] = L'\0'; + struct _xlocale l = {{0}}; + l.components[XLC_COLLATE] = (struct xlocale_component *)table; + return (wcscoll_l(s1, s2, &l)); } Modified: head/lib/libc/regex/regcomp.c ============================================================================== --- head/lib/libc/regex/regcomp.c Thu Jul 14 08:15:13 2016 (r302819) +++ head/lib/libc/regex/regcomp.c Thu Jul 14 08:18:12 2016 (r302820) @@ -51,9 +51,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include "collate.h" + #include "utils.h" #include "regex2.h" @@ -764,6 +767,9 @@ p_b_term(struct parse *p, cset *cs) { char c; wint_t start, finish; + wint_t i; + struct xlocale_collate *table = + (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; /* classify what we've got */ switch ((MORE()) ? PEEK() : '\0') { @@ -811,8 +817,18 @@ p_b_term(struct parse *p, cset *cs) if (start == finish) CHadd(p, cs, start); else { - (void)REQUIRE(start <= finish, REG_ERANGE); - CHaddrange(p, cs, start, finish); + if (table->__collate_load_error) { + (void)REQUIRE((uch)start <= (uch)finish, REG_ERANGE); + CHaddrange(p, cs, start, finish); + } else { + (void)REQUIRE(__wcollate_range_cmp(table, start, finish) <= 0, REG_ERANGE); + for (i = 0; i <= UCHAR_MAX; i++) { + if ( __wcollate_range_cmp(table, start, i) <= 0 + && __wcollate_range_cmp(table, i, finish) <= 0 + ) + CHadd(p, cs, i); + } + } } break; } Modified: head/lib/libc/stdio/vfscanf.c ============================================================================== --- head/lib/libc/stdio/vfscanf.c Thu Jul 14 08:15:13 2016 (r302819) +++ head/lib/libc/stdio/vfscanf.c Thu Jul 14 08:18:12 2016 (r302820) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include "un-namespace.h" +#include "collate.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" @@ -815,7 +816,9 @@ match_failure: static const u_char * __sccl(char *tab, const u_char *fmt) { - int c, n, v; + int c, n, v, i; + struct xlocale_collate *table = + (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; /* first `clear' the whole table */ c = *fmt++; /* first char hat => negated scanset */ @@ -868,15 +871,29 @@ doswitch: * we just stored in the table (c). */ n = *fmt; - if (n == ']' || n < c) { + if (n == ']' + || (table->__collate_load_error ? n < c : + __wcollate_range_cmp(table, n, c) < 0 + ) + ) { c = '-'; break; /* resume the for(;;) */ } fmt++; - do { /* fill in the range */ - tab[++c] = v; - } while (c < n); + /* fill in the range */ + if (table->__collate_load_error) { + do { + tab[++c] = v; + } while (c < n); + } else { + for (i = 0; i < 256; i ++) + if (__wcollate_range_cmp(table, c, i) < 0 && + __wcollate_range_cmp(table, i, n) <= 0 + ) + tab[i] = v; + } #if 1 /* XXX another disgusting compatibility hack */ + c = n; /* * Alas, the V7 Unix scanf also treats formats * such as [a-c-e] as `the letters a through e'.