#include "../../unity/unity.h" #include #include #include #include /* Unity setUp/tearDown */ void setUp(void) { /* no-op */ } void tearDown(void) { /* no-op */ } /* Helper: build expected uppercase hex string for input bytes. */ static void build_expected_hex(const unsigned char *in, size_t inlen, char *out) { static const char hex[16] = "0123456789ABCDEF"; for (size_t i = 0; i < inlen; i++) { unsigned char c = in[i]; out[2*i] = hex[(c >> 4) & 0x0F]; out[2*i + 1] = hex[c & 0x0F]; } } /* Tests start here. */ void test_base16_encode_empty_input(void) { char out[4]; memset(out, 'X', sizeof out); /* inlen = 0, outlen arbitrary (even) */ base16_encode("", 0, out, 4); /* Ensure output is unchanged */ TEST_ASSERT_EQUAL_UINT8('X', (unsigned char)out[0]); TEST_ASSERT_EQUAL_UINT8('X', (unsigned char)out[1]); TEST_ASSERT_EQUAL_UINT8('X', (unsigned char)out[2]); TEST_ASSERT_EQUAL_UINT8('X', (unsigned char)out[3]); } void test_base16_encode_single_zero(void) { unsigned char inb[1] = { 0x00 }; char out[2]; base16_encode((const char*)inb, 1, out, 2); TEST_ASSERT_EQUAL_MEMORY("00", out, 2); } void test_base16_encode_single_ff(void) { unsigned char inb[1] = { 0xFF }; char out[2]; base16_encode((const char*)inb, 1, out, 2); TEST_ASSERT_EQUAL_MEMORY("FF", out, 2); } void test_base16_encode_mixed_bytes(void) { unsigned char inb[] = { 0x12, 0xAB, 0xCD, 0xEF, 0x00, 0x90 }; char out[12]; char expected[12]; build_expected_hex(inb, sizeof inb, expected); base16_encode((const char*)inb, (idx_t)(sizeof inb), out, (idx_t)sizeof out); TEST_ASSERT_EQUAL_MEMORY(expected, out, sizeof out); /* Explicit known expectation as an additional check */ TEST_ASSERT_EQUAL_MEMORY("12ABCDEF0090", out, 12); } void test_base16_encode_partial_output_even(void) { unsigned char inb[] = { 0x01, 0x02, 0x03, 0x04 }; char out[10]; memset(out, '?', sizeof out); /* Provide outlen for only 2 bytes (4 hex chars) */ base16_encode((const char*)inb, 4, out, 4); /* Only first 2 input bytes should be encoded */ TEST_ASSERT_EQUAL_MEMORY("0102", out, 4); /* Ensure no writes beyond the allowed region */ for (size_t i = 4; i < sizeof out; i++) { TEST_ASSERT_EQUAL_UINT8('?', (unsigned char)out[i]); } } void test_base16_encode_full_range_0_to_255(void) { unsigned char inb[256]; for (size_t i = 0; i < 256; i++) inb[i] = (unsigned char)i; char out[512]; char expected[512]; build_expected_hex(inb, 256, expected); base16_encode((const char*)inb, (idx_t)256, out, (idx_t)512); TEST_ASSERT_EQUAL_MEMORY(expected, out, 512); } void test_base16_encode_large_deterministic_pattern(void) { enum { N = 1024 }; unsigned char *inb = (unsigned char*)malloc(N); TEST_ASSERT_NOT_NULL(inb); for (size_t i = 0; i < N; i++) inb[i] = (unsigned char)((i * 37u + 11u) & 0xFFu); char *out = (char*)malloc(2 * N); char *expected = (char*)malloc(2 * N); TEST_ASSERT_NOT_NULL(out); TEST_ASSERT_NOT_NULL(expected); build_expected_hex(inb, N, expected); base16_encode((const char*)inb, (idx_t)N, out, (idx_t)(2 * N)); TEST_ASSERT_EQUAL_MEMORY(expected, out, 2 * N); free(expected); free(out); free(inb); } void test_base16_encode_no_trailing_nul_added(void) { unsigned char inb[] = { 0xDE, 0xAD, 0xBE, 0xEF }; size_t outbytes = sizeof(inb) * 2; /* exact */ char *out = (char*)malloc(outbytes + 1); TEST_ASSERT_NOT_NULL(out); out[outbytes] = '#'; /* sentinel after the valid region */ base16_encode((const char*)inb, (idx_t)sizeof inb, out, (idx_t)outbytes); /* Verify correct encoding and that sentinel is untouched */ TEST_ASSERT_EQUAL_MEMORY("DEADBEEF", out, outbytes); TEST_ASSERT_EQUAL_UINT8('#', (unsigned char)out[outbytes]); free(out); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_base16_encode_empty_input); RUN_TEST(test_base16_encode_single_zero); RUN_TEST(test_base16_encode_single_ff); RUN_TEST(test_base16_encode_mixed_bytes); RUN_TEST(test_base16_encode_partial_output_even); RUN_TEST(test_base16_encode_full_range_0_to_255); RUN_TEST(test_base16_encode_large_deterministic_pattern); RUN_TEST(test_base16_encode_no_trailing_nul_added); return UNITY_END(); }