From f9ab107d32f9a92841430866096a63746bb96fe2 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 15 Aug 2024 13:43:12 -0700 Subject: 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 Reviewed-on: https://review.coreboot.org/c/coreboot/+/83933 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu --- src/commonlib/bsd/string.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/commonlib') 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) -- cgit v1.2.3