File size: 5,325 Bytes
78d2150 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
#include "../../unity/unity.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/* Unity setUp/tearDown */
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* Helper: decode a full Z85 buffer in one shot and verify result */
static void helper_decode_all(const char *enc, idx_t enc_len,
unsigned char *out, idx_t *out_len)
{
struct base_decode_context ctx;
z85_decode_ctx_init(&ctx);
idx_t produced = 0;
bool ok = z85_decode_ctx(&ctx, enc, enc_len, (char*)out, &produced);
TEST_ASSERT_TRUE_MESSAGE(ok, "z85_decode_ctx failed on full buffer");
/* Flush (inlen == 0) should succeed with no extra output. */
idx_t flushn = 0;
ok = z85_decode_ctx(&ctx, "", 0, (char*)out, &flushn);
TEST_ASSERT_TRUE_MESSAGE(ok, "z85_decode_ctx flush failed");
TEST_ASSERT_EQUAL_UINT64_MESSAGE(0, (uint64_t)flushn, "Unexpected flush output");
*out_len = produced;
}
/* Test: empty input should produce no output and not crash */
void test_z85_encode_empty(void)
{
char outbuf[1] = { (char)0xAB };
idx_t outlen = z85_length(0);
TEST_ASSERT_EQUAL_UINT64(0, (uint64_t)outlen);
z85_encode((const char*)"", 0, outbuf, outlen);
/* Nothing else to assert; absence of crash is success. */
TEST_PASS();
}
/* Test: known vector 0x86 0x4F 0xD2 0x6F -> "Hello" */
void test_z85_encode_known_hello(void)
{
const unsigned char in[4] = { 0x86, 0x4F, 0xD2, 0x6F };
idx_t outlen = z85_length(4);
TEST_ASSERT_EQUAL_UINT64(5, (uint64_t)outlen);
char out[5];
z85_encode((const char*)in, 4, out, outlen);
const char expected[5] = { 'H','e','l','l','o' };
TEST_ASSERT_EQUAL_MEMORY(expected, out, 5);
}
/* Test: known vector 8 bytes -> "HelloWorld" */
void test_z85_encode_known_helloworld(void)
{
const unsigned char in[8] = {
0x86, 0x4F, 0xD2, 0x6F, /* "Hello" */
0xB5, 0x59, 0xF7, 0x5B /* "World" */
};
idx_t outlen = z85_length(8);
TEST_ASSERT_EQUAL_UINT64(10, (uint64_t)outlen);
char out[10];
z85_encode((const char*)in, 8, out, outlen);
const char expected[10] = {
'H','e','l','l','o','W','o','r','l','d'
};
TEST_ASSERT_EQUAL_MEMORY(expected, out, 10);
}
/* Test: all zero input -> should encode to "00000" */
void test_z85_encode_all_zero_block(void)
{
const unsigned char in[4] = { 0x00, 0x00, 0x00, 0x00 };
idx_t outlen = z85_length(4);
TEST_ASSERT_EQUAL_UINT64(5, (uint64_t)outlen);
char out[5];
z85_encode((const char*)in, 4, out, outlen);
const char expected[5] = { '0','0','0','0','0' };
TEST_ASSERT_EQUAL_MEMORY(expected, out, 5);
}
/* Test: all 0xFF input -> expected from manual computation "%nSc0" */
void test_z85_encode_all_ff_block(void)
{
const unsigned char in[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
idx_t outlen = z85_length(4);
TEST_ASSERT_EQUAL_UINT64(5, (uint64_t)outlen);
char out[5];
z85_encode((const char*)in, 4, out, outlen);
const char expected[5] = { '%','n','S','c','0' };
TEST_ASSERT_EQUAL_MEMORY(expected, out, 5);
}
/* Test: round-trip encode -> decode for various inputs */
void test_z85_encode_roundtrip_various(void)
{
const unsigned char v1[4] = { 0x00, 0x01, 0x02, 0x03 };
const unsigned char v2[4] = { 0xFF, 0xEE, 0xDD, 0xCC };
const unsigned char v3[8] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70 };
const unsigned char v4[12] = {
0x12,0x34,0x56,0x78, 0x9A,0xBC,0xDE,0xF0, 0x11,0x22,0x33,0x44
};
const struct { const unsigned char *in; idx_t inlen; } cases[] = {
{ v1, 4 }, { v2, 4 }, { v3, 8 }, { v4, 12 }
};
for (size_t i = 0; i < sizeof(cases)/sizeof(cases[0]); i++) {
const unsigned char *in = cases[i].in;
idx_t inlen = cases[i].inlen;
idx_t enc_len = z85_length(inlen);
char *enc = (char*)malloc((size_t)enc_len);
TEST_ASSERT_NOT_NULL(enc);
z85_encode((const char*)in, inlen, enc, enc_len);
unsigned char *dec = (unsigned char*)malloc((size_t)inlen);
TEST_ASSERT_NOT_NULL(dec);
idx_t produced = 0;
helper_decode_all(enc, enc_len, dec, &produced);
TEST_ASSERT_EQUAL_UINT64((uint64_t)inlen, (uint64_t)produced);
TEST_ASSERT_EQUAL_MEMORY(in, dec, (size_t)inlen);
free(enc);
free(dec);
}
}
/* Test: ensure no overwrite occurs beyond provided outlen */
void test_z85_encode_no_overwrite_beyond_outlen(void)
{
const unsigned char in[4] = { 0x86, 0x4F, 0xD2, 0x6F }; /* "Hello" */
idx_t outlen = z85_length(4); /* 5 */
size_t bufsize = (size_t)outlen + 8; /* extra padding */
unsigned char *buf = (unsigned char*)malloc(bufsize);
TEST_ASSERT_NOT_NULL(buf);
memset(buf, 0xAA, bufsize);
z85_encode((const char*)in, 4, (char*)buf, outlen);
const unsigned char expected[5] = { 'H','e','l','l','o' };
TEST_ASSERT_EQUAL_MEMORY(expected, buf, 5);
for (size_t i = (size_t)outlen; i < bufsize; i++) {
TEST_ASSERT_EQUAL_HEX8_MESSAGE(0xAA, buf[i], "Buffer overwrite beyond outlen detected");
}
free(buf);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_z85_encode_empty);
RUN_TEST(test_z85_encode_known_hello);
RUN_TEST(test_z85_encode_known_helloworld);
RUN_TEST(test_z85_encode_all_zero_block);
RUN_TEST(test_z85_encode_all_ff_block);
RUN_TEST(test_z85_encode_roundtrip_various);
RUN_TEST(test_z85_encode_no_overwrite_beyond_outlen);
return UNITY_END();
} |