mirror of
https://github.com/apache/nuttx.git
synced 2026-08-17 17:43:22 +08:00
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 <wangbowen6@xiaomi.com>
This commit is contained in:
committed by
Alin Jerpelea
parent
7f5f0f5e53
commit
c119a0c0fd
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user