Yu-Ping Wu has submitted this change. ( https://review.coreboot.org/c/coreboot/+/83830?usp=email )
Change subject: commonlib/bsd: Add strlen() and strnlen() functions ......................................................................
commonlib/bsd: Add strlen() and strnlen() functions
Add strlen() and strnlen() to commonlib/bsd by rewriting them from scratch, and remove the same functions from coreboot and libpayload.
Note that in the existing libpayload implementation, these functions return 0 for NULL strings. Given that POSIX doesn't require the NULL check and that other major libc implementations (e.g. glibc [1]) don't seem to do that, the new functions also don't perform the NULL check.
[1] https://github.com/bminor/glibc/blob/master/sysdeps/i386/strlen.c
Change-Id: I1203ec9affabe493bd14b46662d212b08240cced Signed-off-by: Yu-Ping Wu yupingso@chromium.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/83830 Reviewed-by: Maximilian Brune maximilian.brune@9elements.com Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Julius Werner jwerner@chromium.org --- M payloads/libpayload/include/string.h M payloads/libpayload/libc/string.c M src/commonlib/bsd/include/commonlib/bsd/string.h M src/commonlib/bsd/string.c M src/include/string.h M src/lib/string.c M tests/commonlib/bsd/string-test.c M tests/lib/string-test.c 8 files changed, 70 insertions(+), 103 deletions(-)
Approvals: Julius Werner: Looks good to me, approved Maximilian Brune: Looks good to me, approved build bot (Jenkins): Verified
diff --git a/payloads/libpayload/include/string.h b/payloads/libpayload/include/string.h index f4ce41f..7762c36 100644 --- a/payloads/libpayload/include/string.h +++ b/payloads/libpayload/include/string.h @@ -47,8 +47,6 @@ * @defgroup string String functions * @{ */ -size_t strnlen(const char *str, size_t maxlen); -size_t strlen(const char *str); int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t maxlen); int strcasecmp(const char *s1, const char *s2); diff --git a/payloads/libpayload/libc/string.c b/payloads/libpayload/libc/string.c index b3e1c8df..f9805e3 100644 --- a/payloads/libpayload/libc/string.c +++ b/payloads/libpayload/libc/string.c @@ -36,50 +36,6 @@ #include <errno.h>
/** - * Calculate the length of a fixed-size string. - * - * @param str The input string. - * @param maxlen Return at most maxlen characters as length of the string. - * @return The length of the string, not including the final NUL character. - * The maximum length returned is maxlen. - */ -size_t strnlen(const char *str, size_t maxlen) -{ - size_t len = 0; - - /* NULL and empty strings have length 0. */ - if (!str) - return 0; - - /* Loop until we find a NUL character, or maxlen is reached. */ - while ((*str++ != '\0') && (len < maxlen)) - len++; - - return len; -} - -/** - * Calculate the length of a string. - * - * @param str The input string. - * @return The length of the string, not including the final NUL character. - */ -size_t strlen(const char *str) -{ - size_t len = 0; - - /* NULL and empty strings have length 0. */ - if (!str) - return 0; - - /* Loop until we find a NUL character. */ - while (*str++ != '\0') - len++; - - return len; -} - -/** * Compare two strings. * * @param s1 The first string. diff --git a/src/commonlib/bsd/include/commonlib/bsd/string.h b/src/commonlib/bsd/include/commonlib/bsd/string.h index bbd4754..8e8b896 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/string.h +++ b/src/commonlib/bsd/include/commonlib/bsd/string.h @@ -3,8 +3,12 @@ #ifndef _COMMONLIB_BSD_STRING_H_ #define _COMMONLIB_BSD_STRING_H_
+#include <stddef.h> #include <stdint.h>
+size_t strlen(const char *src); +size_t strnlen(const char *str, size_t maxlen); + unsigned int skip_atoi(char **ptr);
#endif /* _COMMONLIB_BSD_STRING_H_ */ diff --git a/src/commonlib/bsd/string.c b/src/commonlib/bsd/string.c index 3286d41..a9dce39 100644 --- a/src/commonlib/bsd/string.c +++ b/src/commonlib/bsd/string.c @@ -2,6 +2,26 @@
#include <commonlib/bsd/string.h> #include <ctype.h> +#include <stddef.h> + +size_t strlen(const char *str) +{ + const char *ptr = str; + + while (*ptr++) + ; + return ptr - str - 1; +} + +size_t strnlen(const char *str, size_t maxlen) +{ + const char *ptr = str; + const char *end = str + maxlen + 1; + + while (*ptr++ && ptr < end) + ; + return ptr - str - 1; +}
unsigned int skip_atoi(char **ptr) { diff --git a/src/include/string.h b/src/include/string.h index 30d014a..bbf1c3a 100644 --- a/src/include/string.h +++ b/src/include/string.h @@ -13,8 +13,6 @@ void *memchr(const void *s, int c, size_t n); char *strdup(const char *s); char *strconcat(const char *s1, const char *s2); -size_t strnlen(const char *src, size_t max); -size_t strlen(const char *src); char *strchr(const char *s, int c); char *strncpy(char *to, const char *from, size_t count); char *strcpy(char *dst, const char *src); diff --git a/src/lib/string.c b/src/lib/string.c index a7f8074..25d37b68 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -33,22 +33,6 @@ return d; }
-size_t strnlen(const char *src, size_t max) -{ - size_t i = 0; - while ((*src++) && (i < max)) - i++; - return i; -} - -size_t strlen(const char *src) -{ - size_t i = 0; - while (*src++) - i++; - return i; -} - char *strchr(const char *s, int c) { do { diff --git a/tests/commonlib/bsd/string-test.c b/tests/commonlib/bsd/string-test.c index d94b82e..29e3977 100644 --- a/tests/commonlib/bsd/string-test.c +++ b/tests/commonlib/bsd/string-test.c @@ -1,24 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <commonlib/bsd/string.h> +#include <stddef.h> #include <tests/test.h>
-/* Used to test skip_atoi */ -struct str_with_u_val_t { - char *str; - uint32_t value; - uint32_t offset; -} str_with_u_val[] = { - {"42aa", 42, 2}, - {"a", 0, 0}, - {"0", 0, 1}, - {"4a2", 4, 1}, -}; +static void test_strlen(void **state) +{ + const char *str; + + str = "coreboot"; + assert_int_equal(__builtin_strlen(str), strlen(str)); + + str = "is\0very"; + assert_int_equal(__builtin_strlen(str), strlen(str)); + + str = "nice\n"; + assert_int_equal(__builtin_strlen(str), strlen(str)); + + assert_int_equal(0, strlen("")); +} + +static void test_strnlen(void **state) +{ + /* maxlen larger than string len */ + assert_int_equal(8, strnlen("coreboot", 100)); + + /* maxlen equal to string len */ + assert_int_equal(8, strnlen("coreboot", 8)); + + /* maxlen smaller than string len */ + assert_int_equal(5, strnlen("coreboot", 5)); + + /* maxlen is 0 */ + assert_int_equal(0, strnlen("coreboot", 0)); + + /* Empty string */ + assert_int_equal(0, strnlen("", 3)); +}
static void test_skip_atoi(void **state) { int i; char *ptr, *copy; + const struct str_with_u_val_t { + char *str; + uint32_t value; + uint32_t offset; + } str_with_u_val[] = { + {"42aa", 42, 2}, + {"a", 0, 0}, + {"0", 0, 1}, + {"4a2", 4, 1}, + };
for (i = 0; i < ARRAY_SIZE(str_with_u_val); i++) { ptr = str_with_u_val[i].str; @@ -31,6 +64,8 @@ int main(void) { const struct CMUnitTest tests[] = { + cmocka_unit_test(test_strlen), + cmocka_unit_test(test_strnlen), cmocka_unit_test(test_skip_atoi), };
diff --git a/tests/lib/string-test.c b/tests/lib/string-test.c index 17bb69a..5271353 100644 --- a/tests/lib/string-test.c +++ b/tests/lib/string-test.c @@ -23,12 +23,6 @@ {"", ""}, };
-const char *strings[] = { - "coreboot", - "is\0very", - "nice\n" -}; - /* Used to test atol */ struct str_with_l_val_t { char *str; @@ -76,26 +70,6 @@ } }
-static void test_strnlen(void **state) -{ - int i, n = 5; - size_t str_len, limited_len; - - for (i = 0; i < ARRAY_SIZE(strings); i++) { - str_len = __builtin_strlen(strings[i]); - limited_len = MIN(n, str_len); - assert_int_equal(limited_len, strnlen(strings[i], n)); - } -} - -static void test_strlen(void **state) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(strings); i++) - assert_int_equal(__builtin_strlen(strings[i]), strlen(strings[i])); -} - static void test_strchr(void **state) { char str[] = "Abracadabra!\n"; @@ -227,8 +201,6 @@ const struct CMUnitTest tests[] = { cmocka_unit_test(test_strdup), cmocka_unit_test(test_strconcat), - cmocka_unit_test(test_strnlen), - cmocka_unit_test(test_strlen), cmocka_unit_test(test_strchr), cmocka_unit_test(test_strrchr), cmocka_unit_test(test_strncpy),