zlib / tests /tests_adler32_adler32_z.c
AryaWu's picture
Upload folder using huggingface_hub
e996a55 verified
#include "unity/unity.h"
#include "zlib.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/* Independent naive Adler-32 for expected values.
Does per-byte modulo with BASE = 65521. */
static uLong adler32_naive(uLong adler, const Bytef *buf, size_t len) {
const unsigned long BASE = 65521UL;
unsigned long sum1 = adler & 0xFFFFUL;
unsigned long sum2 = (adler >> 16) & 0xFFFFUL;
for (size_t i = 0; i < len; i++) {
sum1 += buf[i];
if (sum1 >= BASE) sum1 -= BASE; /* one subtraction is sufficient */
sum2 += sum1;
if (sum2 >= BASE) sum2 -= BASE; /* one subtraction is sufficient */
}
return (uLong)(sum1 | (sum2 << 16));
}
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* buf == Z_NULL should return 1 regardless of adler or len (as long as len != 1). */
void test_adler32_z_null_buf_len_nonzero_returns_one(void) {
uLong start = 0xDEADBEEFul;
uLong got = adler32_z(start, Z_NULL, (z_size_t)100);
TEST_ASSERT_EQUAL_HEX32(1UL, got);
}
void test_adler32_z_null_buf_len_zero_returns_one(void) {
uLong start = 0x12345678ul;
uLong got = adler32_z(start, Z_NULL, (z_size_t)0);
TEST_ASSERT_EQUAL_HEX32(1UL, got);
}
/* len == 1 fast path: simple single byte from initial adler 1. */
void test_adler32_z_single_byte_from_initial(void) {
const unsigned char b = 'A'; /* 65 */
uLong got = adler32_z(1UL, (const Bytef *)&b, (z_size_t)1);
uLong exp = adler32_naive(1UL, (const Bytef *)&b, 1);
TEST_ASSERT_EQUAL_HEX32(exp, got); /* expected 0x00420042 */
}
/* len == 1 fast path with wrap of sum1 (start sum1 near BASE). */
void test_adler32_z_single_byte_wrap_sum1(void) {
/* Start with sum1 = 65520, sum2 = 0 */
uLong start = ((uLong)0 << 16) | 65520UL;
const unsigned char b = 10; /* pushes sum1 over BASE */
uLong got = adler32_z(start, (const Bytef *)&b, (z_size_t)1);
uLong exp = adler32_naive(start, (const Bytef *)&b, 1);
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
/* len < 16 path: small string */
void test_adler32_z_small_string_lt_16(void) {
const char *msg = "Hello, world!"; /* 13 bytes */
size_t len = strlen(msg);
uLong got = adler32_z(1UL, (const Bytef *)msg, (z_size_t)len);
uLong exp = adler32_naive(1UL, (const Bytef *)msg, len);
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
/* len < 16 with wrap scenario: start sum1 near BASE to force a wrap */
void test_adler32_z_small_len_wrap_sum1(void) {
unsigned char data[4] = {10, 20, 30, 40};
/* Start with sum1 = 65520, sum2 = 1234 (arbitrary) */
uLong start = ((uLong)1234 << 16) | 65520UL;
uLong got = adler32_z(start, (const Bytef *)data, (z_size_t)sizeof(data));
uLong exp = adler32_naive(start, (const Bytef *)data, sizeof(data));
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
/* len == 0 with non-null buf should normalize start sums: check 0xFFFFFFFF -> 0x000E000E */
void test_adler32_z_len_zero_normalizes_state(void) {
uLong start = 0xFFFFFFFFUL; /* sum1 = 65535, sum2 = 65535 */
unsigned char dummy = 0;
uLong got = adler32_z(start, (const Bytef *)&dummy, (z_size_t)0);
/* Expect normalization: sum1 = 65535 - 65521 = 14, sum2 = 65535 % 65521 = 14 */
uLong exp = ((uLong)14 << 16) | 14;
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
/* len >= NMAX path: pick length > 5552 to trigger block processing */
void test_adler32_z_large_len_over_NMAX(void) {
const size_t len = 6000; /* > NMAX (5552) */
unsigned char *buf = (unsigned char *)malloc(len);
TEST_ASSERT_NOT_NULL(buf);
for (size_t i = 0; i < len; i++) {
buf[i] = (unsigned char)(i % 251);
}
uLong start = 1UL;
uLong got = adler32_z(start, (const Bytef *)buf, (z_size_t)len);
uLong exp = adler32_naive(start, (const Bytef *)buf, len);
free(buf);
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
/* Multiple full blocks plus remainder: 2*NMAX + 123 (with NMAX = 5552) */
void test_adler32_z_multiple_blocks_plus_remainder(void) {
const size_t NMAX_VAL = 5552;
const size_t len = NMAX_VAL * 2 + 123;
unsigned char *buf = (unsigned char *)malloc(len);
TEST_ASSERT_NOT_NULL(buf);
for (size_t i = 0; i < len; i++) {
buf[i] = (unsigned char)(i % 13);
}
uLong start = ((uLong)0x1357 << 16) | 0x2468; /* arbitrary non-initial start */
uLong got = adler32_z(start, (const Bytef *)buf, (z_size_t)len);
uLong exp = adler32_naive(start, (const Bytef *)buf, len);
free(buf);
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_adler32_z_null_buf_len_nonzero_returns_one);
RUN_TEST(test_adler32_z_null_buf_len_zero_returns_one);
RUN_TEST(test_adler32_z_single_byte_from_initial);
RUN_TEST(test_adler32_z_single_byte_wrap_sum1);
RUN_TEST(test_adler32_z_small_string_lt_16);
RUN_TEST(test_adler32_z_small_len_wrap_sum1);
RUN_TEST(test_adler32_z_len_zero_normalizes_state);
RUN_TEST(test_adler32_z_large_len_over_NMAX);
RUN_TEST(test_adler32_z_multiple_blocks_plus_remainder);
return UNITY_END();
}