libc/#40: memchr() fails to handle corner case where size=1
const char * const str = "X";
memchr((void *)str, 'X', 1) returns NULL.
And more generally, if we look for the last byte of a memory area, memchr() fails at finding it.
Fix:
diff --git a/string.c b/string.c
index dd67c45..8b26d96 100644
--- a/string.c
+++ b/string.c
@@ -31,9 +31,13 @@ void * memchr(void const * s, int c, size_t n)
unsigned char const * ls = s;
unsigned char lc = c;
- while(n-- && *ls != lc)
+ while(n--)
+ {
+ if (*ls == lc)
+ return (void*)ls;
ls++;
- return n != 0 ? (void*)ls : NULL; /* XXX */
+ }
+ return NULL;
}
memchr((void *)str, 'X', 1) returns NULL.
And more generally, if we look for the last byte of a memory area, memchr() fails at finding it.
Fix:
diff --git a/string.c b/string.c
index dd67c45..8b26d96 100644
--- a/string.c
+++ b/string.c
@@ -31,9 +31,13 @@ void * memchr(void const * s, int c, size_t n)
unsigned char const * ls = s;
unsigned char lc = c;
- while(n-- && *ls != lc)
+ while(n--)
+ {
+ if (*ls == lc)
+ return (void*)ls;
ls++;
- return n != 0 ? (void*)ls : NULL; /* XXX */
+ }
+ return NULL;
}
TitleUsernameDatePreview
I have applied your patch (src/string.c 1.35), simply changing the while loop into a for, with ls++ as post-condition.
Thanks a lot!
Thanks a lot!
You're absolutely right...
Even worse, in my code I think the value of n is undefined once it exits the loop: decrementing an unsigned value of 0 does not sound good.
Even worse, in my code I think the value of n is undefined once it exits the loop: decrementing an unsigned value of 0 does not sound good.