diff --git a/lib/libc/locale/collate.c b/lib/libc/locale/collate.c --- a/lib/libc/locale/collate.c +++ b/lib/libc/locale/collate.c @@ -300,7 +300,7 @@ while (low <= high) { next = (low + high) / 2; p = tab + next; - compar = key - p->val; + compar = (uint32_t)key - p->val; if (compar == 0) return (p); if (compar > 0) @@ -359,7 +359,7 @@ *len = l; *pri = p; - } else if (*t <= UCHAR_MAX) { + } else if (*t >= 0 && *t <= UCHAR_MAX) { /* * Character is a small (8-bit) character. @@ -699,12 +699,17 @@ struct xlocale_collate *table = (struct xlocale_collate*)locale->components[XLC_COLLATE]; - if (table->__collate_load_error) - return ((len == 1 && *str <= UCHAR_MAX) ? *str : -1); + if (table->__collate_load_error) { + if (len != 1) + return (-1); + if (*str < 0 || *str > UCHAR_MAX) + return (-1); + return (*str); + } if (len == 1) { e = -1; - if (*str <= UCHAR_MAX) + if (*str >= 0 && *str <= UCHAR_MAX) e = table->char_pri_table[*str].pri[0]; else if (table->info->large_count > 0) { collate_large_t *match_large; @@ -781,7 +786,7 @@ if (len == 0 || len > dlen) return ((size_t)-1); if (len == 1) { - if (*wname <= UCHAR_MAX) { + if (*wname >= 0 && *wname <= UCHAR_MAX) { if (table->char_pri_table[*wname].pri[0] >= 0) { if (dlen > 0) *dst = *wname; @@ -853,7 +858,7 @@ return (-1); if (len == 1) { e = -1; - if (*wname <= UCHAR_MAX) + if (*wname >= 0 && *wname <= UCHAR_MAX) e = table->char_pri_table[*wname].pri[0]; else if (table->info->large_count > 0) { collate_large_t *match; @@ -946,7 +951,7 @@ } /* try single character */ i = 1; - if (*buf <= UCHAR_MAX) { + if (*buf >= 0 && *buf <= UCHAR_MAX) { if (equiv_class == table->char_pri_table[*buf].pri[0]) goto found; } else if (table->info->large_count > 0) {