This is an automated email from the ASF dual-hosted git repository. jerpelea pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit c119a0c0fded475c99f6949a102898bbdc392fed Author: Bowen Wang <[email protected]> AuthorDate: Tue Mar 17 11:34:26 2026 +0800 libs/libc/string: Fix sign extension in memset word fill pattern. When the 'c' parameter has bit 7 set (e.g. 0x80), the int value gets sign extended (to 0xffffff80 on the signed char platforms). The word sized fill pattern was built without truncating to unsigned char first, so the fast word aligned path wrote the wrong bytes. Fix both lib_memset.c and lib_bsdmemset.c by casting 'c' to unsigned char before building the fill pattern, as required by C11 7.24.6.1 which states that memset converts 'c' to unsigned char. Assisted-by: Claude:claude-opus-5 Signed-off-by: Bowen Wang <[email protected]> --- libs/libc/string/lib_bsdmemset.c | 3 ++- libs/libc/string/lib_memset.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/libc/string/lib_bsdmemset.c b/libs/libc/string/lib_bsdmemset.c index 399774e1ced..1a0b0ecabd2 100644 --- a/libs/libc/string/lib_bsdmemset.c +++ b/libs/libc/string/lib_bsdmemset.c @@ -48,6 +48,7 @@ FAR void *memset(FAR void *m, int c, size_t n) { FAR libc_data_t *aligned_addr; FAR char *s = (FAR char *)m; + unsigned int d = (unsigned char)c; libc_data_t buffer; int i; @@ -70,7 +71,7 @@ FAR void *memset(FAR void *m, int c, size_t n) /* If we get this far, we know that n is large and s is word-aligned. */ aligned_addr = (FAR libc_data_t *)s; - buffer = ((unsigned int)c << 8) | c; + buffer = (d << 8) | d; buffer |= (buffer << 16); for (i = 32; i < LITTLEBLOCKSIZE * 8; i <<= 1) { diff --git a/libs/libc/string/lib_memset.c b/libs/libc/string/lib_memset.c index d19ed89e42d..facfae69ebf 100644 --- a/libs/libc/string/lib_memset.c +++ b/libs/libc/string/lib_memset.c @@ -50,7 +50,8 @@ FAR void *memset(FAR void *s, int c, size_t n) */ uintptr_t addr = (uintptr_t)s; - uint16_t val16 = ((uint16_t)c << 8) | (uint16_t)c; + uint8_t val8 = (uint8_t)c; + uint16_t val16 = ((uint16_t)val8 << 8) | (uint16_t)val8; uint32_t val32 = ((uint32_t)val16 << 16) | (uint32_t)val16; #ifdef CONFIG_LIBC_MEMSET_64BIT uint64_t val64 = ((uint64_t)val32 << 32) | (uint64_t)val32;
