zlib / tests /tests_gzlib_gzclearerr.c
AryaWu's picture
Upload folder using huggingface_hub
e996a55 verified
#include "unity/unity.h"
#include "zlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Unity setUp/tearDown */
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* Helpers */
static char *make_temp_filename(char *buf, size_t buflen) {
/* Use tmpnam to generate a unique name. */
if (buf == NULL || buflen < L_tmpnam) return NULL;
char *res = tmpnam(buf);
if (res == NULL) return NULL;
/* Ensure it's a normal C string path in buf */
/* tmpnam writes into buf when provided */
return buf;
}
static int write_gzip_file(const char *path, const void *data, unsigned len) {
gzFile gz = gzopen(path, "wb");
if (gz == NULL) return -1;
int written = gzwrite(gz, data, (unsigned)len);
int close_ret = gzclose(gz);
if (written != (int)len) return -2;
if (close_ret != Z_OK) return -3;
return 0;
}
static int corrupt_file_last_byte(const char *path) {
FILE *fp = fopen(path, "rb+");
if (!fp) return -1;
if (fseek(fp, 0, SEEK_END) != 0) { fclose(fp); return -2; }
long sz = ftell(fp);
if (sz <= 0) { fclose(fp); return -3; }
if (fseek(fp, -1L, SEEK_END) != 0) { fclose(fp); return -4; }
int c = fgetc(fp);
if (c == EOF) { fclose(fp); return -5; }
if (fseek(fp, -1L, SEEK_END) != 0) { fclose(fp); return -6; }
if (fputc((c ^ 0xFF) & 0xFF, fp) == EOF) { fclose(fp); return -7; }
if (fclose(fp) != 0) return -8;
return 0;
}
/* Tests */
void test_gzclearerr_null_does_not_crash(void) {
/* Just ensure it doesn't crash */
gzclearerr(NULL);
TEST_ASSERT_TRUE(1); /* If we reached here, no crash */
}
void test_gzclearerr_clears_eof_and_past_after_read_past_end(void) {
char path[L_tmpnam];
TEST_ASSERT_NOT_NULL(make_temp_filename(path, sizeof(path)));
const char *payload = "Hello, world!";
TEST_ASSERT_EQUAL_INT(0, write_gzip_file(path, payload, (unsigned)strlen(payload)));
gzFile gz = gzopen(path, "rb");
TEST_ASSERT_NOT_NULL(gz);
/* Read until EOF using gzgetc to ensure we step past end and set 'past' */
int ch;
while ((ch = gzgetc(gz)) != -1) {
/* consume */
}
/* At this point, either EOF or error; for a valid gzip, should be EOF */
int errnum_before = Z_OK;
const char *msg_before = gzerror(gz, &errnum_before);
(void)msg_before; /* not strictly needed */
TEST_ASSERT_EQUAL_INT(Z_OK, errnum_before); /* should be OK at EOF */
TEST_ASSERT_EQUAL_INT(1, gzeof(gz)); /* 'past' should be true after EOF */
/* Now clear error/eof */
gzclearerr(gz);
int errnum_after = -1;
const char *msg_after = gzerror(gz, &errnum_after);
TEST_ASSERT_EQUAL_INT(Z_OK, errnum_after);
TEST_ASSERT_NOT_NULL(msg_after);
TEST_ASSERT_EQUAL_STRING("", msg_after);
TEST_ASSERT_EQUAL_INT(0, gzeof(gz)); /* eof/past cleared */
TEST_ASSERT_EQUAL_INT(Z_OK, gzclose(gz));
remove(path);
}
void test_gzclearerr_clears_error_and_message_after_crc_error(void) {
char path[L_tmpnam];
TEST_ASSERT_NOT_NULL(make_temp_filename(path, sizeof(path)));
const char *payload = "This will be corrupted.";
TEST_ASSERT_EQUAL_INT(0, write_gzip_file(path, payload, (unsigned)strlen(payload)));
/* Corrupt the file to induce a CRC/data error on read */
TEST_ASSERT_EQUAL_INT(0, corrupt_file_last_byte(path));
gzFile gz = gzopen(path, "rb");
TEST_ASSERT_NOT_NULL(gz);
/* Read until error */
unsigned char buf[64];
int ret;
int saw_error = 0;
while ((ret = gzread(gz, buf, sizeof(buf))) > 0) {
/* consume */
}
if (ret == -1) {
saw_error = 1;
}
TEST_ASSERT_EQUAL_INT(1, saw_error);
int errnum_before = Z_OK;
const char *msg_before = gzerror(gz, &errnum_before);
TEST_ASSERT_NOT_NULL(msg_before);
TEST_ASSERT_NOT_EQUAL(Z_OK, errnum_before);
TEST_ASSERT_TRUE(msg_before[0] != '\0'); /* should have a message */
/* Now clear error */
gzclearerr(gz);
int errnum_after = -1;
const char *msg_after = gzerror(gz, &errnum_after);
TEST_ASSERT_EQUAL_INT(Z_OK, errnum_after);
TEST_ASSERT_NOT_NULL(msg_after);
TEST_ASSERT_EQUAL_STRING("", msg_after);
/* gzeof() should be 0; error cleared and not at EOF */
TEST_ASSERT_EQUAL_INT(0, gzeof(gz));
/* Cleanup */
TEST_ASSERT_EQUAL_INT(Z_OK, gzclose(gz));
remove(path);
}
void test_gzclearerr_on_write_mode_noop_and_ok(void) {
char path[L_tmpnam];
TEST_ASSERT_NOT_NULL(make_temp_filename(path, sizeof(path)));
gzFile gz = gzopen(path, "wb");
TEST_ASSERT_NOT_NULL(gz);
/* Ensure starting state is OK */
int errnum_before = -1;
const char *msg_before = gzerror(gz, &errnum_before);
TEST_ASSERT_EQUAL_INT(Z_OK, errnum_before);
TEST_ASSERT_NOT_NULL(msg_before);
/* Call gzclearerr; in write mode it should simply ensure err is Z_OK (no eof flags to clear) */
gzclearerr(gz);
int errnum_after = -1;
const char *msg_after = gzerror(gz, &errnum_after);
TEST_ASSERT_EQUAL_INT(Z_OK, errnum_after);
TEST_ASSERT_NOT_NULL(msg_after);
TEST_ASSERT_TRUE(msg_after[0] == '\0' || msg_after == msg_before);
/* Cleanup */
TEST_ASSERT_EQUAL_INT(Z_OK, gzclose(gz));
remove(path);
}
/* Main */
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_gzclearerr_null_does_not_crash);
RUN_TEST(test_gzclearerr_clears_eof_and_past_after_read_past_end);
RUN_TEST(test_gzclearerr_clears_error_and_message_after_crc_error);
RUN_TEST(test_gzclearerr_on_write_mode_noop_and_ok);
return UNITY_END();
}