fix memmove large-length backward copy

F/1897
pull/745/head
Daniele Lacamera 2026-04-08 16:44:45 +02:00
parent a5ea3ff829
commit e22eade623
2 changed files with 35 additions and 3 deletions

View File

@ -288,14 +288,14 @@ void RAMFUNCTION *memcpy(void *dst, const void *src, size_t n)
!defined(__CCRX__)
void *memmove(void *dst, const void *src, size_t n)
{
int i;
size_t i;
if (dst == src)
return dst;
if (src < dst) {
const char *s = (const char *)src;
char *d = (char *)dst;
for (i = n - 1; i >= 0; i--) {
d[i] = s[i];
for (i = n; i > 0; i--) {
d[i - 1] = s[i - 1];
}
return dst;
} else {

View File

@ -25,8 +25,12 @@
#define FAST_MEMCPY
#include <check.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
#ifdef __linux__
#include <sys/mman.h>
#endif
#include "string.c"
@ -325,6 +329,31 @@ START_TEST(test_memcpy_memmove)
}
END_TEST
#if defined(__linux__) && (SIZE_MAX > INT_MAX)
START_TEST(test_memmove_large_overlap_length)
{
size_t n = (size_t)INT_MAX + 2U;
size_t len = n + 1U;
unsigned char *region = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ck_assert_ptr_ne(region, MAP_FAILED);
region[0] = 0x11;
region[1] = 0x22;
region[n - 1] = 0x33;
region[n] = 0x44;
memmove(region + 1, region, n);
ck_assert_uint_eq(region[1], 0x11);
ck_assert_uint_eq(region[n], 0x33);
ck_assert_int_eq(munmap(region, len), 0);
}
END_TEST
#endif
START_TEST(test_memcpy_aligned_buffers)
{
union {
@ -443,6 +472,9 @@ Suite *string_suite(void)
tcase_add_test(tcase_misc, test_strcpy_strncpy_strcat_strncat);
tcase_add_test(tcase_misc, test_strncmp);
tcase_add_test(tcase_misc, test_memcpy_memmove);
#if defined(__linux__) && (SIZE_MAX > INT_MAX)
tcase_add_test(tcase_misc, test_memmove_large_overlap_length);
#endif
tcase_add_test(tcase_misc, test_memcpy_aligned_buffers);
tcase_add_test(tcase_misc, test_uart_writenum_basic);
tcase_add_test(tcase_misc, test_uart_printf_formats);