diff --git a/payloads/libpayload/libc/lib.c b/payloads/libpayload/libc/lib.c index f1d85745ad..0475789c00 100644 --- a/payloads/libpayload/libc/lib.c +++ b/payloads/libpayload/libc/lib.c @@ -124,8 +124,6 @@ void __noreturn abort(void) halt(); } -int errno; - char *getenv(const char *name) { return NULL; diff --git a/payloads/libpayload/libc/string.c b/payloads/libpayload/libc/string.c index a1b7d4d59d..d641431e7d 100644 --- a/payloads/libpayload/libc/string.c +++ b/payloads/libpayload/libc/string.c @@ -290,7 +290,7 @@ char *strsep(char **stringp, const char *delim) { char *walk, *token; - if (!stringp || !*stringp || !**stringp) + if (!stringp || !*stringp) return NULL; token = walk = *stringp; @@ -302,11 +302,12 @@ char *strsep(char **stringp, const char *delim) if (*walk) { /* NUL terminate */ *walk = '\0'; - walk++; + *stringp = walk + 1; + } else { + /* Set to NULL after last token. */ + *stringp = NULL; } - *stringp = walk; - return token; } @@ -547,6 +548,10 @@ char *strtok(char *str, const char *delim) return strtok_r(str, delim, &strtok_ptr); } +/* errno isn't actually used anywhere other than perror() below, and just here + for compatibility with libc-targeting code wanting to incidentally print it. */ +int errno; + /** * Print error message and error number * @param s Error message to print diff --git a/payloads/libpayload/tests/libc/Makefile.mk b/payloads/libpayload/tests/libc/Makefile.mk index 5f92bdf0a8..8d88af9f30 100644 --- a/payloads/libpayload/tests/libc/Makefile.mk +++ b/payloads/libpayload/tests/libc/Makefile.mk @@ -1,3 +1,6 @@ -tests-y += fmap_locate_area-test +tests-y += fmap_locate_area-test string-test fmap_locate_area-test-srcs += tests/libc/fmap_locate_area-test.c + +string-test-srcs += tests/libc/string-test.c +string-test-srcs += libc/string.c diff --git a/payloads/libpayload/tests/libc/string-test.c b/payloads/libpayload/tests/libc/string-test.c new file mode 100644 index 0000000000..2fe7c6bace --- /dev/null +++ b/payloads/libpayload/tests/libc/string-test.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static void test_strsep(void **state) +{ + /* Use `char x[] = ` instead of `char *x = ` to avoid writing to .rodata. */ + char test1[] = "abc,def|ghi jklm,\no"; + const char *delim = ", \n"; + + char *stringp = test1; + assert_string_equal(strsep(&stringp, delim), "abc"); + assert_ptr_equal(stringp, test1 + 4); + assert_string_equal(strsep(&stringp, delim), "def|ghi"); + assert_ptr_equal(stringp, test1 + 12); + assert_string_equal(strsep(&stringp, delim), "jklm"); + assert_ptr_equal(stringp, test1 + 17); + assert_string_equal(strsep(&stringp, delim), ""); + assert_ptr_equal(stringp, test1 + 18); + assert_string_equal(strsep(&stringp, delim), "o"); + assert_null(stringp); + assert_null(strsep(&stringp, delim)); + assert_null(stringp); + + char test2[] = ""; + stringp = test2; + assert_string_equal(strsep(&stringp, delim), ""); + assert_null(strsep(&stringp, delim)); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_strsep), + }; + + return lp_run_group_tests(tests, NULL, NULL); +}