summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2016-07-22 14:24:17 +0000
committerache <ache@FreeBSD.org>2016-07-22 14:24:17 +0000
commit3f56839b4888f5f2140b74ea536b9a0cee3a5084 (patch)
treede0154f18a175a32c0020a7fc90088448957417c /lib
parente3c997f56b8acb47dd382a8e4ced061d664ae7b2 (diff)
downloadFreeBSD-src-3f56839b4888f5f2140b74ea536b9a0cee3a5084.zip
FreeBSD-src-3f56839b4888f5f2140b74ea536b9a0cee3a5084.tar.gz
MFC: r302824
1) Eliminate possibility to call __*collate_range_cmp() with inclomplete locale (which cause core dump) by removing whole 'table' argument by which it passed. 2) Restore __collate_range_cmp() in __sccl(). 3) Collating [a-z] range in regcomp() works for single byte locales only (we can't do it for other ones). In previous state only first 256 wide chars are considered and all others are just silently dropped from the range.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/fnmatch.c4
-rw-r--r--lib/libc/gen/glob.c4
-rw-r--r--lib/libc/locale/collate.h3
-rw-r--r--lib/libc/locale/collcmp.c19
-rw-r--r--lib/libc/regex/regcomp.c11
-rw-r--r--lib/libc/stdio/vfscanf.c6
6 files changed, 28 insertions, 19 deletions
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c
index db0bf89..db15494 100644
--- a/lib/libc/gen/fnmatch.c
+++ b/lib/libc/gen/fnmatch.c
@@ -304,8 +304,8 @@ rangematch(pattern, test, flags, newp, patmbs)
if (table->__collate_load_error ?
c <= test && test <= c2 :
- __collate_range_cmp(table, c, test) <= 0
- && __collate_range_cmp(table, test, c2) <= 0
+ __wcollate_range_cmp(c, test) <= 0
+ && __wcollate_range_cmp(test, c2) <= 0
)
ok = 1;
} else if (c == test)
diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c
index 95a3a06..6c86297 100644
--- a/lib/libc/gen/glob.c
+++ b/lib/libc/gen/glob.c
@@ -836,8 +836,8 @@ match(Char *name, Char *pat, Char *patend)
if ((*pat & M_MASK) == M_RNG) {
if (table->__collate_load_error ?
CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) :
- __collate_range_cmp(table, CHAR(c), CHAR(k)) <= 0
- && __collate_range_cmp(table, CHAR(k), CHAR(pat[1])) <= 0
+ __wcollate_range_cmp(CHAR(c), CHAR(k)) <= 0
+ && __wcollate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0
)
ok = 1;
pat += 2;
diff --git a/lib/libc/locale/collate.h b/lib/libc/locale/collate.h
index ad034d4..496e0ac 100644
--- a/lib/libc/locale/collate.h
+++ b/lib/libc/locale/collate.h
@@ -72,7 +72,8 @@ u_char *__collate_strdup(u_char *);
u_char *__collate_substitute(struct xlocale_collate *, const u_char *);
int __collate_load_tables(const char *);
void __collate_lookup(struct xlocale_collate *, const u_char *, int *, int *, int *);
-int __collate_range_cmp(struct xlocale_collate *, int, int);
+int __collate_range_cmp(char, char);
+int __wcollate_range_cmp(wchar_t, wchar_t);
#ifdef COLLATE_DEBUG
void __collate_print_tables(void);
#endif
diff --git a/lib/libc/locale/collcmp.c b/lib/libc/locale/collcmp.c
index aa17afd..4921e71 100644
--- a/lib/libc/locale/collcmp.c
+++ b/lib/libc/locale/collcmp.c
@@ -33,20 +33,29 @@
__FBSDID("$FreeBSD$");
#include <string.h>
-#include <xlocale.h>
+#include <wchar.h>
#include "collate.h"
/*
* Compare two characters using collate
*/
-int __collate_range_cmp(struct xlocale_collate *table, int c1, int c2)
+int __collate_range_cmp(char c1, char c2)
{
static char s1[2], s2[2];
s1[0] = c1;
s2[0] = c2;
- struct _xlocale l = {{0}};
- l.components[XLC_COLLATE] = (struct xlocale_component *)table;
- return (strcoll_l(s1, s2, &l));
+ return (strcoll(s1, s2));
+}
+
+int __wcollate_range_cmp(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';
+ return (wcscoll(s1, s2));
}
diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c
index ae92f6a..9211f65 100644
--- a/lib/libc/regex/regcomp.c
+++ b/lib/libc/regex/regcomp.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <stdlib.h>
#include <regex.h>
-#include <runetype.h>
#include <wchar.h>
#include <wctype.h>
@@ -817,14 +816,14 @@ p_b_term(struct parse *p, cset *cs)
if (start == finish)
CHadd(p, cs, start);
else {
- if (table->__collate_load_error) {
- (void)REQUIRE((uch)start <= (uch)finish, REG_ERANGE);
+ if (table->__collate_load_error || MB_CUR_MAX > 1) {
+ (void)REQUIRE(start <= finish, REG_ERANGE);
CHaddrange(p, cs, start, finish);
} else {
- (void)REQUIRE(__collate_range_cmp(table, start, finish) <= 0, REG_ERANGE);
+ (void)REQUIRE(__wcollate_range_cmp(start, finish) <= 0, REG_ERANGE);
for (i = 0; i <= UCHAR_MAX; i++) {
- if ( __collate_range_cmp(table, start, i) <= 0
- && __collate_range_cmp(table, i, finish) <= 0
+ if ( __wcollate_range_cmp(start, i) <= 0
+ && __wcollate_range_cmp(i, finish) <= 0
)
CHadd(p, cs, i);
}
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index b537263..66dca1a 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -873,7 +873,7 @@ doswitch:
n = *fmt;
if (n == ']'
|| (table->__collate_load_error ? n < c :
- __collate_range_cmp (table, n, c) < 0
+ __collate_range_cmp(n, c) < 0
)
) {
c = '-';
@@ -887,8 +887,8 @@ doswitch:
} while (c < n);
} else {
for (i = 0; i < 256; i ++)
- if ( __collate_range_cmp (table, c, i) < 0
- && __collate_range_cmp (table, i, n) <= 0
+ if (__collate_range_cmp(c, i) <= 0 &&
+ __collate_range_cmp(i, n) <= 0
)
tab[i] = v;
}
OpenPOWER on IntegriCloud