commit d80109dd5e960ab007911b73a77161e3e8047798
parent b305911cbaa6d902c01d8db85a41696c6e4a78fc
Author: Benno Schulenberg <bensberg@justemail.net>
Date: Wed, 27 Jul 2016 22:15:34 +0200
chars: properly compare strings of different lengths
That is: don't run towlower() on the two differing bytes when having
reached the end of one of the strings.
This fixes https://savannah.gnu.org/bugs/?48700.
In the bargain, don't do the conversion to lowercase twice.
Furthermore, persist when encountering invalid byte sequences --
until finding bytes that differ.
Diffstat:
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/chars.c b/src/chars.c
@@ -514,28 +514,37 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n)
while (*s1 != '\0' && *s2 != '\0' && n > 0) {
bool bad1 = FALSE, bad2 = FALSE;
+ int difference;
if (mbtowc(&wc1, s1, MB_CUR_MAX) < 0) {
mbtowc_reset();
- wc1 = (unsigned char)*s1;
bad1 = TRUE;
}
if (mbtowc(&wc2, s2, MB_CUR_MAX) < 0) {
mbtowc_reset();
- wc2 = (unsigned char)*s2;
bad2 = TRUE;
}
- if (bad1 != bad2 || towlower(wc1) != towlower(wc2))
- break;
+ if (bad1 || bad2) {
+ if (*s1 != *s2)
+ return (unsigned char)*s1 - (unsigned char)*s2;
+
+ s1++; s2++; n--;
+ continue;
+ }
+
+ difference = towlower(wc1) - towlower(wc2);
+
+ if (difference != 0)
+ return difference;
s1 += move_mbright(s1, 0);
s2 += move_mbright(s2, 0);
n--;
}
- return (n > 0) ? towlower(wc1) - towlower(wc2) : 0;
+ return (n > 0) ? ((unsigned char)*s1 - (unsigned char)*s2) : 0;
} else
#endif
return strncasecmp(s1, s2, n);