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 <wchar.h>
 #include <wctype.h>
 
+#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 <unistd.h>
 #include <wchar.h>
 
+#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 <string.h>
+#include <wchar.h>
+#include <xlocale.h>
 #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 <limits.h>
 #include <stdlib.h>
 #include <regex.h>
+#include <runetype.h>
 #include <wchar.h>
 #include <wctype.h>
 
+#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 <wctype.h>
 #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'.
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to