diff --git a/file.c b/file.c index 049b18e..038dcd4 100644 --- a/file.c +++ b/file.c @@ -162,7 +162,7 @@ base16384_err_t base16384_encode_file_detailed(const char* input, const char* ou if(fd < 0) { goto_base16384_file_detailed_cleanup(encode, base16384_err_open_input_file, {}); } - char *input_file = mmap(NULL, (size_t)inputsize+16, PROT_READ, MAP_PRIVATE, fd, 0); + char *input_file = mmap(NULL, (size_t)inputsize, PROT_READ, MAP_PRIVATE, fd, 0); if(input_file == MAP_FAILED) { goto_base16384_file_detailed_cleanup(encode, base16384_err_map_input_file, close(fd)); } @@ -173,11 +173,11 @@ base16384_err_t base16384_encode_file_detailed(const char* input, const char* ou int n = base16384_encode_safe(input_file, (int)inputsize, decbuf); if(n && fwrite(decbuf, n, 1, fpo) <= 0) { goto_base16384_file_detailed_cleanup(encode, base16384_err_write_file, { - munmap(input_file, (size_t)inputsize+16); + munmap(input_file, (size_t)inputsize); close(fd); }); } - munmap(input_file, (size_t)inputsize+16); + munmap(input_file, (size_t)inputsize); close(fd); } #endif @@ -313,7 +313,7 @@ base16384_err_t base16384_decode_file_detailed(const char* input, const char* ou if(fd < 0) { goto_base16384_file_detailed_cleanup(decode, base16384_err_open_input_file, {}); } - char *input_file = mmap(NULL, (size_t)inputsize+16, PROT_READ, MAP_PRIVATE, fd, 0); + char *input_file = mmap(NULL, (size_t)inputsize, PROT_READ, MAP_PRIVATE, fd, 0); if(input_file == MAP_FAILED) { goto_base16384_file_detailed_cleanup(decode, base16384_err_map_input_file, close(fd)); } @@ -321,11 +321,11 @@ base16384_err_t base16384_decode_file_detailed(const char* input, const char* ou n = base16384_decode_safe(input_file+n, inputsize-n, encbuf); if(n && fwrite(encbuf, n, 1, fpo) <= 0) { goto_base16384_file_detailed_cleanup(decode, base16384_err_write_file, { - munmap(input_file, (size_t)inputsize+16); + munmap(input_file, (size_t)inputsize); close(fd); }); } - munmap(input_file, (size_t)inputsize+16); + munmap(input_file, (size_t)inputsize); close(fd); } #endif diff --git a/test/file_test.c b/test/file_test.c new file mode 100644 index 0000000..b3565d3 --- /dev/null +++ b/test/file_test.c @@ -0,0 +1,188 @@ + +#ifdef _WIN32 + #include + #define ftruncate _chsize_s +#else + #define _POSIX1_SOURCE 2 + #include +#endif +#include +#include +#include +#include +#include +#include + +#include "base16384.h" +#include "binary.h" + +#define TEST_SIZE (4096) +#define TEST_INPUT_FILENAME "wrap_test_input.bin" +#define TEST_OUTPUT_FILENAME "wrap_test_output.bin" +#define TEST_VALIDATE_FILENAME "wrap_test_validate.bin" + +char encbuf[BASE16384_ENCBUFSZ]; +char decbuf[BASE16384_DECBUFSZ]; +char tstbuf[BASE16384_ENCBUFSZ]; + +#define ok(has_failed, reason) \ + if (has_failed) { \ + perror(reason); \ + return 1; \ + } + +#define loop_ok(has_failed, i, reason) \ + if (has_failed) { \ + fprintf(stderr, "loop @%d: ", i); \ + perror(reason); \ + return 1; \ + } + +#define reset_and_truncate(fd, i) { \ + fd = open(TEST_INPUT_FILENAME, O_RDWR); \ + ok(!fd, "open"); \ + loop_ok(lseek(fd, 0, SEEK_SET), i, "lseek"); \ + loop_ok(ftruncate(fd, i), i, "ftruncate"); \ +} + +#define base16384_loop_ok(err) \ + if (err) { \ + fprintf(stderr, "loop @%d: ", i); \ + base16384_perror(err); \ + return 1; \ + } + +#define validate_result() \ + uint64_t buf, sum_input = 0, sum_validate = 0; \ + fp = fopen(TEST_INPUT_FILENAME, "rb"); { \ + loop_ok(!fp, i, "fopen"); \ + while (fread(&buf, sizeof(sum_input), 1, fp) == 1) sum_input += buf; \ + buf = 0; \ + while (fread(&buf, 1, 1, fp) == 1) { \ + sum_input += buf; \ + sum_input = LEFTROTATE(sum_input, 4); \ + } \ + } fclose(fp); \ + fp = fopen(TEST_VALIDATE_FILENAME, "rb"); { \ + loop_ok(!fp, i, "fopen"); \ + while (fread(&buf, sizeof(sum_validate), 1, fp) == 1) sum_validate += buf; \ + buf = 0; \ + while (fread(&buf, 1, 1, fp) == 1) { \ + sum_validate += buf; \ + sum_validate = LEFTROTATE(sum_validate, 4); \ + } \ + } fclose(fp); \ + if (sum_input != sum_validate) { \ + fprintf(stderr, "loop @%d, expect: %016llx, got: %016llx: ", i, (unsigned long long)sum_input, (unsigned long long)sum_validate); \ + fputs(TEST_INPUT_FILENAME " and " TEST_VALIDATE_FILENAME " mismatch.", stderr); \ + return 1; \ + } + +#define init_input_file() \ + for(i = 0; i < TEST_SIZE; i += sizeof(int)) { \ + *(int*)(&encbuf[i]) = rand(); \ + } \ + fp = fopen(TEST_INPUT_FILENAME, "wb"); \ + ok(!fp, "fopen"); \ + ok(fwrite(encbuf, TEST_SIZE, 1, fp) != 1, "fwrite"); \ + ok(fclose(fp), "fclose"); \ + fputs("input file created.\n", stderr); + +#define test_file_detailed(flag) \ + fputs("testing base16384_en/decode_file with flag "#flag"...\n", stderr); \ + init_input_file(); \ + for(i = TEST_SIZE; i > 0; i--) { \ + reset_and_truncate(fd, i); \ + loop_ok(close(fd), i, "close"); \ + \ + err = base16384_encode_file_detailed(TEST_INPUT_FILENAME, TEST_OUTPUT_FILENAME, encbuf, decbuf, flag); \ + base16384_loop_ok(err); \ + \ + err = base16384_decode_file_detailed(TEST_OUTPUT_FILENAME, TEST_VALIDATE_FILENAME, encbuf, decbuf, flag); \ + base16384_loop_ok(err); \ + \ + validate_result(); \ + } + +#define test_fp_detailed(flag) \ + fputs("testing base16384_en/decode_fp...\n", stderr); \ + init_input_file(); \ + for(i = TEST_SIZE; i > 0; i--) { \ + reset_and_truncate(fd, i); \ + loop_ok(close(fd), i, "close"); \ + \ + FILE* fpin = fopen(TEST_INPUT_FILENAME, "rb"); \ + loop_ok(!fpin, i, "fopen"); \ + \ + FILE* fpout = fopen(TEST_OUTPUT_FILENAME, "wb+"); \ + loop_ok(!fpout, i, "fopen"); \ + \ + err = base16384_encode_fp_detailed(fpin, fpout, encbuf, decbuf, flag); \ + base16384_loop_ok(err); \ + \ + loop_ok(fclose(fpin), i, "fclose"); \ + \ + FILE* fpval = fopen(TEST_VALIDATE_FILENAME, "wb"); \ + loop_ok(!fpval, i, "fopen"); \ + \ + rewind(fpout); \ + \ + err = base16384_decode_fp_detailed(fpout, fpval, encbuf, decbuf, flag); \ + base16384_loop_ok(err); \ + \ + loop_ok(fclose(fpout), i, "fclose"); \ + loop_ok(fclose(fpval), i, "fclose"); \ + \ + validate_result(); \ + } + +#define test_fd_detailed(flag) \ + fputs("testing base16384_en/decode_fd...\n", stderr); \ + init_input_file(); \ + for(i = TEST_SIZE; i > 0; i--) { \ + reset_and_truncate(fd, i); \ + \ + int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND); \ + loop_ok(!fdout, i, "open"); \ + \ + err = base16384_encode_fd_detailed(fd, fdout, encbuf, decbuf, 0); \ + base16384_loop_ok(err); \ + loop_ok(close(fd), i, "close"); \ + \ + int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT); \ + loop_ok(!fdval, i, "open"); \ + \ + loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \ + \ + err = base16384_decode_fd_detailed(fdout, fdval, encbuf, decbuf, 0); \ + base16384_loop_ok(err); \ + \ + loop_ok(close(fdout), i, "close"); \ + loop_ok(close(fdval), i, "close"); \ + \ + validate_result(); \ + } + +#define test_detailed(name) \ + test_##name##_detailed(0); \ + test_##name##_detailed(BASE16384_FLAG_NOHEADER); \ + test_##name##_detailed(BASE16384_FLAG_SUM_CHECK_ON_REMAIN); \ + test_##name##_detailed(BASE16384_FLAG_NOHEADER|BASE16384_FLAG_SUM_CHECK_ON_REMAIN); + +int main() { + srand(time(NULL)); + + FILE* fp; + int fd, i; + base16384_err_t err; + + test_detailed(file); + test_detailed(fp); + test_detailed(fd); + + remove(TEST_INPUT_FILENAME); + remove(TEST_OUTPUT_FILENAME); + remove(TEST_VALIDATE_FILENAME); + + return 0; +}