diff options
author | Julius Werner <jwerner@chromium.org> | 2024-08-15 13:43:12 -0700 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2024-08-19 13:25:05 +0000 |
commit | f9ab107d32f9a92841430866096a63746bb96fe2 (patch) | |
tree | 5879fbee8a699ff4caaea06faba05cacb666c4f7 /src/commonlib | |
parent | 82c0dd29099fc89826e332d2720f7e7e60f77f0e (diff) |
commonlib/bsd: Optimize strnlen()
This patch changes the strnlen() implementation to fix a small issue
where we would dereference once more byte than intended when not finding
a NUL-byte within the specified amount of characters. It also changes
the implementation to rely on a pre-calculated end pointer rather than a
running counter, since this seems to lead to slightly better assembly
(one less instruction in the inner loop) on most architectures.
Change-Id: Ic36768fd3a26e2b64143904e78cd0b52ba66898d
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/83933
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Diffstat (limited to 'src/commonlib')
-rw-r--r-- | src/commonlib/bsd/string.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/commonlib/bsd/string.c b/src/commonlib/bsd/string.c index 56670e8862..6482279713 100644 --- a/src/commonlib/bsd/string.c +++ b/src/commonlib/bsd/string.c @@ -15,10 +15,19 @@ size_t strlen(const char *str) size_t strnlen(const char *str, size_t maxlen) { - size_t len = 0; - while (*str++ && len < maxlen) - len++; - return len; + const char *ptr = str; + const char *end = str + maxlen; + + if (!maxlen) + return 0; + + while (*ptr++) { + /* Make sure this checks for ==, not >=, because the calculation + for `end` may overflow in some edge cases. */ + if (ptr == end) + return maxlen; + } + return ptr - str - 1; } char *strcat(char *dst, const char *src) |