File size: 4,188 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 |
#include "../../unity/unity.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
/* The test file is included into the same translation unit as the
basenc implementation, so we can access internal symbols directly. */
void setUp(void) {
/* Ensure base58_encode uses the correct length function. */
base_length = base58_length;
}
void tearDown(void) {
/* nothing */
}
static void check_encode(const unsigned char *data, size_t data_len,
const char *expected)
{
idx_t cap = base58_length((idx_t)data_len);
char *out = (char *)malloc((size_t)cap);
TEST_ASSERT_NOT_NULL(out);
memset(out, 0xAA, (size_t)cap);
idx_t outlen = cap;
base58_encode((const char *)data, data_len, out, &outlen);
size_t exp_len = strlen(expected);
TEST_ASSERT_EQUAL_UINT64(exp_len, (uint64_t)outlen);
if (exp_len > 0)
TEST_ASSERT_EQUAL_INT(0, memcmp(out, expected, exp_len));
/* Ensure no bytes beyond returned length were modified. */
for (idx_t i = outlen; i < cap; i++)
TEST_ASSERT_EQUAL_HEX8(0xAA, (unsigned char)out[i]);
free(out);
}
static size_t count_leading_zero_bytes(const unsigned char *p, size_t n)
{
size_t i = 0;
while (i < n && p[i] == 0x00) i++;
return i;
}
static void test_base58_encode_empty(void)
{
check_encode(NULL, 0, "");
}
static void test_base58_encode_only_zeros(void)
{
/* 1 to 4 leading zeros */
unsigned char z1[] = {0x00};
unsigned char z2[] = {0x00, 0x00};
unsigned char z3[] = {0x00, 0x00, 0x00};
unsigned char z4[] = {0x00, 0x00, 0x00, 0x00};
check_encode(z1, sizeof z1, "1");
check_encode(z2, sizeof z2, "11");
check_encode(z3, sizeof z3, "111");
check_encode(z4, sizeof z4, "1111");
}
static void test_base58_encode_single_bytes(void)
{
unsigned char v1[] = {0x01}; /* value 1 -> "2" */
unsigned char vff[] = {0xFF}; /* value 255 -> "5Q" */
check_encode(v1, sizeof v1, "2");
check_encode(vff, sizeof vff, "5Q");
}
static void test_base58_encode_prefix_zeros_then_value(void)
{
unsigned char a[] = {0x00, 0x01}; /* 0x00,1 => "12" */
unsigned char b[] = {0x00, 0x00, 0xFF};/* two zeros then 255 => "115Q" */
check_encode(a, sizeof a, "12");
check_encode(b, sizeof b, "115Q");
}
static void test_base58_encode_small_multibyte_examples(void)
{
/* 0x0100 = 256 => base58 digits 4,24 => "5R" */
unsigned char v256[] = {0x01, 0x00};
check_encode(v256, sizeof v256, "5R");
/* 0x01 0x02 0x03 = 66051 => digits 19,36,47 => "Ldp" */
unsigned char v123[] = {0x01, 0x02, 0x03};
check_encode(v123, sizeof v123, "Ldp");
}
static bool is_forbidden_base58_char(char c)
{
/* Base58 alphabet excludes these visually ambiguous characters */
return (c == '0' || c == 'O' || c == 'I' || c == 'l');
}
static void test_base58_encode_long_input_properties(void)
{
/* Create a non-zero-leading buffer: 0x01, 0x02, ..., 0xFF, 0x00, 0x01 */
size_t n = 300;
unsigned char *buf = (unsigned char *)malloc(n);
TEST_ASSERT_NOT_NULL(buf);
for (size_t i = 0; i < n; i++)
buf[i] = (unsigned char)((i + 1) & 0xFF);
buf[0] = 0x01; /* ensure no leading zero */
idx_t cap = base58_length((idx_t)n);
char *out = (char *)malloc((size_t)cap);
TEST_ASSERT_NOT_NULL(out);
memset(out, 0xAA, (size_t)cap);
idx_t outlen = cap;
base58_encode((const char *)buf, n, out, &outlen);
TEST_ASSERT_TRUE(outlen > 0);
/* Since first byte != 0x00, output must not start with '1' (value 0 digit). */
TEST_ASSERT_NOT_EQUAL('1', out[0]);
/* Check that no forbidden characters appear in output. */
for (idx_t i = 0; i < outlen; i++)
TEST_ASSERT_FALSE(is_forbidden_base58_char(out[i]));
/* Ensure no writes past returned length. */
for (idx_t i = outlen; i < cap; i++)
TEST_ASSERT_EQUAL_HEX8(0xAA, (unsigned char)out[i]);
free(out);
free(buf);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_base58_encode_empty);
RUN_TEST(test_base58_encode_only_zeros);
RUN_TEST(test_base58_encode_single_bytes);
RUN_TEST(test_base58_encode_prefix_zeros_then_value);
RUN_TEST(test_base58_encode_small_multibyte_examples);
RUN_TEST(test_base58_encode_long_input_properties);
return UNITY_END();
} |