diff --git a/sys/include/string_utils.h b/sys/include/string_utils.h index 5c7da82a8d..004e284aaf 100644 --- a/sys/include/string_utils.h +++ b/sys/include/string_utils.h @@ -7,8 +7,7 @@ */ /** - * @defgroup sys_string_utils Utility functions that are missing in - * `string.h` + * @defgroup sys_string_utils Utility functions that are missing in `string.h` * @ingroup sys * * This header provides utility functions that the standard C libs `string.h` @@ -92,6 +91,18 @@ static inline void explicit_bzero(void *dest, size_t n_bytes) */ ssize_t strscpy(char *dest, const char *src, size_t count); +/** + * @brief Check if the entire buffer is filled with the same byte. + * + * @param[in] data The buffer to probe + * @param[in] c The byte to check of + * @param[in] len Size of the buffer + * + * @return NULL if the entire buffer is filled with @p c + * @return pointer to the first non-matching byte + */ +const void *memchk(const void *data, uint8_t c, size_t len); + #ifdef __cplusplus } #endif diff --git a/sys/libc/string.c b/sys/libc/string.c index c3c1cc661a..7a8b4ba047 100644 --- a/sys/libc/string.c +++ b/sys/libc/string.c @@ -37,4 +37,17 @@ ssize_t strscpy(char *dest, const char *src, size_t count) return -E2BIG; } } + +const void *memchk(const void *data, uint8_t c, size_t len) +{ + const uint8_t *end = (uint8_t *)data + len; + for (const uint8_t *d = data; d != end; ++d) { + if (c != *d) { + return d; + } + } + + return NULL; +} + /** @} */ diff --git a/sys/net/gnrc/pktbuf_static/gnrc_pktbuf_static.c b/sys/net/gnrc/pktbuf_static/gnrc_pktbuf_static.c index 5ac2708886..7498390e45 100644 --- a/sys/net/gnrc/pktbuf_static/gnrc_pktbuf_static.c +++ b/sys/net/gnrc/pktbuf_static/gnrc_pktbuf_static.c @@ -30,6 +30,7 @@ #include "net/gnrc/pktbuf.h" #include "net/gnrc/nettype.h" #include "net/gnrc/pkt.h" +#include "string_utils.h" #include "pktbuf_internal.h" #include "pktbuf_static.h" @@ -61,18 +62,6 @@ static gnrc_pktsnip_t *_create_snip(gnrc_pktsnip_t *next, const void *data, size gnrc_nettype_t type); static void *_pktbuf_alloc(size_t size); -static const void *mem_is_set(const void *data, uint8_t c, size_t len) -{ - const uint8_t *end = (uint8_t *)data + len; - for (const uint8_t *d = data; d != end; ++d) { - if (c != *d) { - return d; - } - } - - return NULL; -} - static inline void _set_pktsnip(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *next, void *data, size_t size, gnrc_nettype_t type) { @@ -440,7 +429,7 @@ static void *_pktbuf_alloc(size_t size) const void *mismatch; if (CONFIG_GNRC_PKTBUF_CHECK_USE_AFTER_FREE && - (mismatch = mem_is_set(ptr + 1, CANARY, size - sizeof(_unused_t)))) { + (mismatch = memchk(ptr + 1, CANARY, size - sizeof(_unused_t)))) { printf("[%p] mismatch at offset %"PRIuPTR"/%u (ignoring %u initial bytes that were repurposed)\n", (void *)ptr, (uintptr_t)mismatch - (uintptr_t)ptr, (unsigned)size, (unsigned)sizeof(_unused_t)); #ifdef MODULE_OD diff --git a/tests/unittests/tests-core/tests-core-atomic.c b/tests/unittests/tests-core/tests-core-atomic.c index 98f6f6cc84..7089f9edfa 100644 --- a/tests/unittests/tests-core/tests-core-atomic.c +++ b/tests/unittests/tests-core/tests-core-atomic.c @@ -26,11 +26,6 @@ static void test_atomic_flag(void) TEST_ASSERT_EQUAL_INT(0, atomic_flag_test_and_set(&flag)); } -/* Prevent compiler optimization for SAML1X because of gcc internal bug */ -#ifdef CPU_CORE_CORTEX_M23 -#pragma GCC push_options -#pragma GCC optimize ("O0") -#endif /* Test atomic_fetch_add */ static void test_atomic_inc_positive(void) { @@ -72,9 +67,7 @@ static void test_atomic_inc_rollover(void) TEST_ASSERT_EQUAL_INT(INT_MIN + 1, atomic_fetch_add(&res, 1)); TEST_ASSERT_EQUAL_INT(INT_MIN + 2, atomic_load(&res)); } -#ifdef CPU_SAML1X -#pragma GCC pop_options -#endif + /* Test atomic_fetch_sub */ static void test_atomic_dec_negative(void) { diff --git a/tests/unittests/tests-libc/tests-libc.c b/tests/unittests/tests-libc/tests-libc.c index 3d4a714ed3..1f0a081919 100644 --- a/tests/unittests/tests-libc/tests-libc.c +++ b/tests/unittests/tests-libc/tests-libc.c @@ -29,10 +29,21 @@ static void test_libc_strscpy(void) TEST_ASSERT_EQUAL_INT(strscpy(buffer, "empty", 0), -E2BIG); } +static void test_libc_memchk(void) +{ + char buffer[32]; + memset(buffer, 0xff, sizeof(buffer)); + TEST_ASSERT_NULL(memchk(buffer, 0xff, sizeof(buffer))); + + buffer[5] = 5; + TEST_ASSERT(memchk(buffer, 0xff, sizeof(buffer)) == &buffer[5]); +} + Test *tests_libc_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(test_libc_strscpy), + new_TestFixture(test_libc_memchk), }; EMB_UNIT_TESTCALLER(libc_tests, NULL, NULL, fixtures);