mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
strcmp: fix overflow and possibly signedness error
Doing the strcmp return value as signed char __res = *cs - *ct; is wrong for two reasons. The subtraction can overflow because __res doesn't use a type big enough. Moreover the compared bytes should be interpreted as unsigned char as specified by POSIX. The same problem is fixed in strncmp. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Cc: Michael Buesch <mb@bu3sch.de> Cc: Andreas Schwab <schwab@linux-m68k.org> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
6602b355c2
commit
a414f01ac2
1 changed files with 14 additions and 6 deletions
20
lib/string.c
20
lib/string.c
|
@ -246,13 +246,17 @@ EXPORT_SYMBOL(strlcat);
|
||||||
#undef strcmp
|
#undef strcmp
|
||||||
int strcmp(const char *cs, const char *ct)
|
int strcmp(const char *cs, const char *ct)
|
||||||
{
|
{
|
||||||
signed char __res;
|
unsigned char c1, c2;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
c1 = *cs++;
|
||||||
|
c2 = *ct++;
|
||||||
|
if (c1 != c2)
|
||||||
|
return c1 < c2 ? -1 : 1;
|
||||||
|
if (!c1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return __res;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(strcmp);
|
EXPORT_SYMBOL(strcmp);
|
||||||
#endif
|
#endif
|
||||||
|
@ -266,14 +270,18 @@ EXPORT_SYMBOL(strcmp);
|
||||||
*/
|
*/
|
||||||
int strncmp(const char *cs, const char *ct, size_t count)
|
int strncmp(const char *cs, const char *ct, size_t count)
|
||||||
{
|
{
|
||||||
signed char __res = 0;
|
unsigned char c1, c2;
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
c1 = *cs++;
|
||||||
|
c2 = *ct++;
|
||||||
|
if (c1 != c2)
|
||||||
|
return c1 < c2 ? -1 : 1;
|
||||||
|
if (!c1)
|
||||||
break;
|
break;
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
return __res;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(strncmp);
|
EXPORT_SYMBOL(strncmp);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue