#include "../../unity/unity.h" #include #include #include #include /* The following globals and functions are defined in dd.c and are visible here because this test file is included into the same translation unit. We simply use them. */ extern void alloc_ibuf(void); /* Globals from dd.c (file-scope static there, but visible here as we're included into the same translation unit): - static idx_t page_size; - static idx_t input_blocksize; - static int conversions_mask; - static char *ibuf; - static char *obuf; - enum conversion flags including C_SWAB - static char *swab_buffer(char *buf, idx_t *nread, int *saved_byte); */ /* Forward declarations to inform the compiler; definitions are above in dd.c */ extern char *swab_buffer(char *buf, idx_t *nread, int *saved_byte); /* From dd.c enum */ /* We don't redeclare C_SWAB; using it directly as it's an enum constant defined earlier in dd.c. */ static size_t get_page_size_fallback(void) { long ps = -1; #ifdef _SC_PAGESIZE ps = sysconf(_SC_PAGESIZE); #elif defined(_SC_PAGE_SIZE) ps = sysconf(_SC_PAGE_SIZE); #endif if (ps <= 0) return 4096; /* reasonable default */ return (size_t)ps; } void setUp(void) { /* Ensure a clean slate for each test. */ if (ibuf) { free(ibuf); } ibuf = NULL; /* obuf may alias ibuf in some modes; clear to avoid dangling pointer. */ obuf = NULL; /* Reasonable defaults for globals used by alloc_ibuf. */ page_size = (typeof(page_size))get_page_size_fallback(); input_blocksize = 64; /* small, safe size */ conversions_mask = 0; /* no special conversions by default */ } void tearDown(void) { if (ibuf) { free(ibuf); ibuf = NULL; } obuf = NULL; } static void assert_pointer_aligned(void *p, size_t align) { /* Unity doesn't have direct alignment assert; use generic assert. */ TEST_ASSERT_NOT_NULL_MESSAGE(p, "Pointer is NULL; expected an allocated buffer"); TEST_ASSERT_EQUAL_UINT64_MESSAGE(0ULL, ((uintptr_t)p) % align, "Allocated buffer is not aligned to page_size"); } void test_alloc_ibuf_basic_allocation_and_alignment(void) { /* Given defaults from setUp, allocate ibuf. */ alloc_ibuf(); /* Then ibuf should be non-NULL and page aligned. */ assert_pointer_aligned(ibuf, (size_t)page_size); /* We can touch within input_blocksize range safely. */ ibuf[0] = (char)0xAA; ibuf[input_blocksize - 1] = (char)0x55; TEST_ASSERT_EQUAL_HEX8((char)0xAA, ibuf[0]); TEST_ASSERT_EQUAL_HEX8((char)0x55, ibuf[input_blocksize - 1]); } void test_alloc_ibuf_idempotent_no_realloc(void) { /* First allocation */ alloc_ibuf(); char *first = ibuf; TEST_ASSERT_NOT_NULL(first); /* Change globals to values that would cause a different allocation if alloc_ibuf() didn't early return, then call again. */ input_blocksize = 128; /* different size */ conversions_mask = C_SWAB; /* request extra byte */ alloc_ibuf(); /* Expect the same pointer; function should return early if ibuf is set. */ TEST_ASSERT_EQUAL_PTR(first, ibuf); } void test_alloc_ibuf_with_swab_extra_byte_supports_swab_buffer(void) { /* Ensure conv=swab set so alloc_ibuf allocates an extra byte. */ conversions_mask = C_SWAB; input_blocksize = 6; /* Small even size to exercise swab */ alloc_ibuf(); assert_pointer_aligned(ibuf, (size_t)page_size); /* Fill buffer with known pattern: A B C D E F */ const char pattern[6] = { 'A', 'B', 'C', 'D', 'E', 'F' }; memcpy(ibuf, pattern, sizeof(pattern)); /* swab_buffer writes to buf[*nread] when prev_saved<0 and *nread is even, which requires the extra byte allocated by alloc_ibuf() when C_SWAB set. */ int saved_byte = -1; typeof(input_blocksize) nread = input_blocksize; /* 6 */ char *start = swab_buffer(ibuf, &nread, &saved_byte); /* For even nread=6 and no previous saved byte, swab_buffer returns buf+1. The 6 bytes starting at start should be BA DC FE. */ TEST_ASSERT_EQUAL_PTR(ibuf + 1, start); TEST_ASSERT_EQUAL_INT64(6, nread); TEST_ASSERT_EQUAL_INT(-1, saved_byte); const char expected[6] = { 'B', 'A', 'D', 'C', 'F', 'E' }; TEST_ASSERT_EQUAL_MEMORY(expected, start, sizeof(expected)); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_alloc_ibuf_basic_allocation_and_alignment); RUN_TEST(test_alloc_ibuf_idempotent_no_realloc); RUN_TEST(test_alloc_ibuf_with_swab_extra_byte_supports_swab_buffer); return UNITY_END(); }