From 0366f1b52787fc04c4e16927e2a5d2d9b9920673 Mon Sep 17 00:00:00 2001 From: pfg Date: Sun, 5 Jun 2016 19:12:52 +0000 Subject: [PATCH] libc/locale: Fix type breakage in __collate_range_cmp(). When collation support was brought in, the second and third arguments in __collate_range_cmp() were changed from int to wchar_t, breaking the ABI. Change them to a "char" type which makes more sense and keeps the ABI compatible. Also introduce __wcollate_range_cmp() which does work with wide characters. This function is used only internally in libc so we don't export it. Use the new function in glob(3), fnmatch(3), and regexec(3). PR: 179721 Suggested by: ache. jilles MFC after: 3 weeks (perhaps partial only) --- lib/libc/gen/fnmatch.c | 4 ++-- lib/libc/gen/glob.c | 4 ++-- lib/libc/locale/collate.h | 3 ++- lib/libc/locale/collcmp.c | 19 ++++++++++++++++--- lib/libc/regex/regcomp.c | 6 +++--- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index 2f240a81491..8cdcaf1fbd3 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -296,8 +296,8 @@ rangematch(const char *pattern, wchar_t test, int flags, char **newp, 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(table, c, test) <= 0 + && __wcollate_range_cmp(table, test, c2) <= 0 ) ok = 1; } else if (c == test) diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c index 971d616e43e..62aa8ad75f4 100644 --- a/lib/libc/gen/glob.c +++ b/lib/libc/gen/glob.c @@ -832,8 +832,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(table, CHAR(c), CHAR(k)) <= 0 + && __wcollate_range_cmp(table, 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 981258949fc..3253d9cb67d 100644 --- a/lib/libc/locale/collate.h +++ b/lib/libc/locale/collate.h @@ -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(struct xlocale_collate *, wchar_t, wchar_t); +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 *, diff --git a/lib/libc/locale/collcmp.c b/lib/libc/locale/collcmp.c index 102fbfb4e07..b90c379cb19 100644 --- a/lib/libc/locale/collcmp.c +++ b/lib/libc/locale/collcmp.c @@ -41,14 +41,27 @@ __FBSDID("$FreeBSD$"); * Compare two characters using collate */ -int __collate_range_cmp(struct xlocale_collate *table, wchar_t c1, wchar_t c2) +int __collate_range_cmp(struct xlocale_collate *table, char c1, char c2) +{ + char s1[2], s2[2]; + + s1[0] = c1; + s1[1] = '\0'; + s2[0] = c2; + s2[1] = '\0'; + 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] = 0; + s1[1] = L'\0'; s2[0] = c2; - s2[1] = 0; + s2[1] = L'\0'; struct _xlocale l = {{0}}; l.components[XLC_COLLATE] = (struct xlocale_component *)table; return (wcscoll_l(s1, s2, &l)); diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c index aa9ca9e902a..53332334fed 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -821,10 +821,10 @@ p_b_term(struct parse *p, cset *cs) (void)REQUIRE((uch)start <= (uch)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(table, 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(table, start, i) <= 0 + && __wcollate_range_cmp(table, i, finish) <= 0 ) CHadd(p, cs, i); } -- 2.11.4.GIT