Is the implementation of strnlen
that follows invalid?
size_t strnlen(const char *str, size_t maxlen)
{
char *nul = memchr(str, '\0', maxlen);
return nul ? (size_t)(nul - str) : maxlen;
}
I assume that memchr
may always look at maxlen
bytes no matter the contents of those bytes. Does the contract of strnlen
only allow it to look at all maxlen
bytes if there is no NUL terminator? If so, the size in memory of str
may be less than maxlen
bytes, in which case memchr
might try to read invalid memory locations. Is this correct?
Yes, the implementation posted is conforming: memchr()
is not supposed to read bytes from str
beyond the first occurrence of '\0'
.
C17 7.24.5.1 The
memchr
functionSynopsis
#include <string.h> void *memchr(const void *s, int c, size_t n);
Description
The
memchr
function locates the first occurrence ofc
(converted to anunsigned char
) in the initialn
characters (each interpreted asunsigned char
) of the object pointed to bys
. The implementation shall behave as if it reads the characters sequentially and stops as soon as a matching character is found.Returns
The
memchr
function returns a pointer to the located character, or a null pointer if the character does not occur in the object.
memchr
may be implemented with efficient techniques that test multiple bytes at a time, potentially reading beyond the first matching byte, but only if this does not cause any visible side effects.