To check if the buffer contains a null terminator within a maximum number of characters, the memchr function can be used. The following function safe_strlen behaves like the strlen_s function defined by Annex K of the C specification, and uses memchr to find the position of the first (if any) null terminator in the buffer.
#include <stdint.h> #include <string.h> /** * Get the length of a possibly null terminated string, clamped to a maximum. * * If \p s is not NULL, searches up to \p maxsize bytes from \p s to find the * first null terminator, if any. * * \param s Start of string. * \param maxsize Maximum number of bytes to search. * * \return 0 if \p s is \c NULL. * \return \p maxsize if null terminator not found. * \return length of null terminated string if null terminator found. */ size_t safe_strlen(const char *s, size_t maxsize) { size_t length = 0; if (s) { #if PTRDIFF_MAX < SIZE_MAX /* May need to search the buffer in chunks. */ while (maxsize) #endif { const char *e; size_t pos; #if PTRDIFF_MAX < SIZE_MAX if (maxsize > PTRDIFF_MAX) { /* Limit size of chunk. */ pos = PTRDIFF_MAX; } else #endif { /* This is the final chunk. */ pos = maxsize; } /* Search for null terminator in chunk. */ e = memchr(s, 0, pos); if (e) { /* Null terminator found. */ pos = e - s; /* position of null terminator in chunk */ #if PTRDIFF_MAX < SIZE_MAX /* Make this the final chunk. */ maxsize = pos; #endif } /* Update returned length. */ length += pos; #if PTRDIFF_MAX < SIZE_MAX /* Advance to next chunk. */ s += pos; maxsize -= pos; #endif } } return length; }
The code is complicated by the necessity to deal with buffer sizes larger than PTRDIFF_MAX if PTRDIFF_MAX is less than SIZE_MAX. The core functionality without the extra safety checks is as follows:
/* less safe version of the above - may result in undefined behavior. */ size_t less_safe_strlen(const char *s, size_t maxsize) { size_t length = 0; if (s) { const char *e = memchr(s, 0, maxsize); if (e) { length = e - s; } else { length = maxsize; } } return length; }
int count = 0; while (*ptr++ != '0') ++count;, so all you'd need to do is turn that into afor(int pos = 0; *ptr++ != 0 && pos < MAXSIZE; ++pos) ++count;and you're good.strlen().