2026-07-29 13:06:25 -04:00
|
|
|
/*
|
|
|
|
|
* Memory-wrapper behaviour that is deterministic today.
|
|
|
|
|
*
|
|
|
|
|
* TODO.md section 1.1 also calls out malloc(0), malloc(SIZE_MAX), and
|
|
|
|
|
* overlapping memcpy. Those are intentionally not pinned here yet: malloc(0)
|
|
|
|
|
* is platform-dependent under the current wrapper, huge allocations need
|
|
|
|
|
* sanitizer-safe handling, and overlapping memcpy is still an API-contract
|
|
|
|
|
* decision.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "aksl_capture.h"
|
|
|
|
|
|
|
|
|
|
static int test_malloc_writes_nonnull_pointer(void)
|
|
|
|
|
{
|
|
|
|
|
void *ptr = NULL;
|
|
|
|
|
|
|
|
|
|
AKSL_CHECK_OK(aksl_malloc(32, &ptr));
|
|
|
|
|
AKSL_CHECK(ptr != NULL);
|
|
|
|
|
AKSL_CHECK_OK(aksl_free(ptr));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_malloc_rejects_null_destination(void)
|
|
|
|
|
{
|
2026-07-29 15:47:17 -04:00
|
|
|
AKSL_CHECK_STATUS_MSG_CONTAINS(aksl_malloc(32, NULL),
|
|
|
|
|
AKERR_NULLPOINTER, "NULL");
|
2026-07-29 13:06:25 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_free_rejects_null_pointer(void)
|
|
|
|
|
{
|
2026-07-29 15:47:17 -04:00
|
|
|
AKSL_CHECK_STATUS_MSG_CONTAINS(aksl_free(NULL),
|
|
|
|
|
AKERR_NULLPOINTER, "NULL");
|
2026-07-29 13:06:25 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_malloc_free_round_trip(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned char *buf = NULL;
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
|
|
AKSL_CHECK_OK(aksl_malloc(64, (void **)&buf));
|
|
|
|
|
AKSL_CHECK(buf != NULL);
|
|
|
|
|
for ( i = 0; i < 64; i++ ) {
|
|
|
|
|
buf[i] = (unsigned char)i;
|
|
|
|
|
}
|
|
|
|
|
for ( i = 0; i < 64; i++ ) {
|
|
|
|
|
AKSL_CHECK(buf[i] == (unsigned char)i);
|
|
|
|
|
}
|
|
|
|
|
AKSL_CHECK_OK(aksl_free(buf));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_memset_fills_buffer(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned char buf[8];
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
|
|
memset((void *)buf, 0x00, sizeof(buf));
|
|
|
|
|
AKSL_CHECK_OK(aksl_memset(buf, 0x5a, sizeof(buf)));
|
|
|
|
|
for ( i = 0; i < sizeof(buf); i++ ) {
|
|
|
|
|
AKSL_CHECK(buf[i] == 0x5a);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_memset_zero_length_is_noop(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned char buf[4] = { 1, 2, 3, 4 };
|
|
|
|
|
|
|
|
|
|
AKSL_CHECK_OK(aksl_memset(buf, 0xff, 0));
|
|
|
|
|
AKSL_CHECK(buf[0] == 1);
|
|
|
|
|
AKSL_CHECK(buf[1] == 2);
|
|
|
|
|
AKSL_CHECK(buf[2] == 3);
|
|
|
|
|
AKSL_CHECK(buf[3] == 4);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_memset_rejects_null_buffer(void)
|
|
|
|
|
{
|
2026-07-29 15:47:17 -04:00
|
|
|
AKSL_CHECK_STATUS_MSG_CONTAINS(aksl_memset(NULL, 0x00, 4),
|
|
|
|
|
AKERR_NULLPOINTER, "s=");
|
2026-07-29 13:06:25 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_memcpy_copies_bytes(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned char src[6] = { 0, 1, 2, 3, 4, 5 };
|
|
|
|
|
unsigned char dst[6] = { 9, 9, 9, 9, 9, 9 };
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
|
|
AKSL_CHECK_OK(aksl_memcpy(dst, src, sizeof(src)));
|
|
|
|
|
for ( i = 0; i < sizeof(src); i++ ) {
|
|
|
|
|
AKSL_CHECK(dst[i] == src[i]);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_memcpy_zero_length_is_noop(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned char src[3] = { 1, 2, 3 };
|
|
|
|
|
unsigned char dst[3] = { 4, 5, 6 };
|
|
|
|
|
|
|
|
|
|
AKSL_CHECK_OK(aksl_memcpy(dst, src, 0));
|
|
|
|
|
AKSL_CHECK(dst[0] == 4);
|
|
|
|
|
AKSL_CHECK(dst[1] == 5);
|
|
|
|
|
AKSL_CHECK(dst[2] == 6);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_memcpy_rejects_null_destination(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned char src[1] = { 1 };
|
|
|
|
|
|
2026-07-29 15:47:17 -04:00
|
|
|
AKSL_CHECK_STATUS(aksl_memcpy(NULL, src, sizeof(src)),
|
|
|
|
|
AKERR_NULLPOINTER);
|
2026-07-29 13:06:25 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_memcpy_rejects_null_source(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned char dst[1] = { 0 };
|
|
|
|
|
|
2026-07-29 15:47:17 -04:00
|
|
|
AKSL_CHECK_STATUS(aksl_memcpy(dst, NULL, sizeof(dst)),
|
|
|
|
|
AKERR_NULLPOINTER);
|
2026-07-29 13:06:25 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
|
{
|
|
|
|
|
int failures = 0;
|
|
|
|
|
|
|
|
|
|
akerr_init();
|
|
|
|
|
|
|
|
|
|
AKSL_RUN(failures, test_malloc_writes_nonnull_pointer);
|
|
|
|
|
AKSL_RUN(failures, test_malloc_rejects_null_destination);
|
|
|
|
|
AKSL_RUN(failures, test_free_rejects_null_pointer);
|
|
|
|
|
AKSL_RUN(failures, test_malloc_free_round_trip);
|
|
|
|
|
|
|
|
|
|
AKSL_RUN(failures, test_memset_fills_buffer);
|
|
|
|
|
AKSL_RUN(failures, test_memset_zero_length_is_noop);
|
|
|
|
|
AKSL_RUN(failures, test_memset_rejects_null_buffer);
|
|
|
|
|
|
|
|
|
|
AKSL_RUN(failures, test_memcpy_copies_bytes);
|
|
|
|
|
AKSL_RUN(failures, test_memcpy_zero_length_is_noop);
|
|
|
|
|
AKSL_RUN(failures, test_memcpy_rejects_null_destination);
|
|
|
|
|
AKSL_RUN(failures, test_memcpy_rejects_null_source);
|
|
|
|
|
|
|
|
|
|
AKSL_REPORT(failures);
|
|
|
|
|
}
|