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;

Reply via email to