diff options
| author | Gabriel Ravier <gabravier@gmail.com> | 2023-01-04 16:07:19 +0100 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2023-02-12 17:50:59 -0500 | 
| commit | 07616721f1fa6cb215ffbef23441cae80412484f (patch) | |
| tree | 58c92a1039672246f43cc776bbbf5d93ad561169 | |
| parent | 35fdfe62a4ff471074ca53b7626ec80e83d244bd (diff) | |
| download | musl-07616721f1fa6cb215ffbef23441cae80412484f.tar.gz | |
fix return value of wcs{,n}cmp for extreme wchar_t values
As a result of using simple subtraction to implement the return values
for wcscmp and wcsncmp, integer overflow can occur (producing
undefined behavior, and in practice, a wrong comparison result). This
does not occur for meaningful character values (21-bit range) but the
functions are specified to work on arbitrary wchar_t arrays.
This patch replaces the subtraction with a little bit of code that
orders the characters correctly, returning -1 if the character from
the first string is smaller than the one from the second, 0 if they
are equal and 1 if the character from the first string is larger than
the one from the second.
| -rw-r--r-- | src/string/wcscmp.c | 2 | ||||
| -rw-r--r-- | src/string/wcsncmp.c | 2 | 
2 files changed, 2 insertions, 2 deletions
| diff --git a/src/string/wcscmp.c b/src/string/wcscmp.c index 26eeee70..286ec3ea 100644 --- a/src/string/wcscmp.c +++ b/src/string/wcscmp.c @@ -3,5 +3,5 @@  int wcscmp(const wchar_t *l, const wchar_t *r)  {  	for (; *l==*r && *l && *r; l++, r++); -	return *l - *r; +	return *l < *r ? -1 : *l > *r;  } diff --git a/src/string/wcsncmp.c b/src/string/wcsncmp.c index 4ab32a92..2b3558bf 100644 --- a/src/string/wcsncmp.c +++ b/src/string/wcsncmp.c @@ -3,5 +3,5 @@  int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)  {  	for (; n && *l==*r && *l && *r; n--, l++, r++); -	return n ? *l - *r : 0; +	return n ? (*l < *r ? -1 : *l > *r) : 0;  } | 
