mirror of
https://github.com/GerbilSoft/zlib-ng.git
synced 2025-06-18 11:35:35 -04:00
Added regression test for deflateEnd returning -3 when using deflate quick. #382
This commit is contained in:
parent
959eda5c15
commit
b6136c629c
@ -1029,6 +1029,10 @@ if(ZLIB_ENABLE_TESTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(minideflate test/minideflate.c)
|
||||
configure_test_executable(minideflate)
|
||||
target_link_libraries(minideflate zlib)
|
||||
|
||||
add_executable(switchlevels test/switchlevels.c)
|
||||
configure_test_executable(switchlevels)
|
||||
target_link_libraries(switchlevels zlib)
|
||||
@ -1220,6 +1224,27 @@ if(ZLIB_ENABLE_TESTS)
|
||||
-DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/GH-364/test.bin
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake)
|
||||
|
||||
set(GH_382_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:minideflate> -c -m 1 -w -15 -1 -s 4)
|
||||
add_test(NAME GH-382-deflate COMMAND
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DCOMMAND=${GH_382_COMMAND}"
|
||||
-DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/GH-382/defneg3.dat
|
||||
-DOUTPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/GH-382/defneg3.dat.zz
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake)
|
||||
|
||||
set(GH_382_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:minideflate> -c -d -m 1 -w -15)
|
||||
add_test(NAME GH-382-inflate COMMAND
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DCOMMAND=${GH_382_COMMAND}"
|
||||
-DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/GH-382/defneg3.dat.zz
|
||||
-DOUTPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/GH-382/defneg3.dat.out
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake)
|
||||
|
||||
add_test(NAME GH-382-cmp
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/GH-382/defneg3.dat
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/GH-382/defneg3.dat.out)
|
||||
|
||||
set(GH_536_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:switchlevels> 6 9744 1 91207)
|
||||
add_test(NAME GH-536-segfault
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
|
1
test/GH-382/defneg3.dat
Normal file
1
test/GH-382/defneg3.dat
Normal file
@ -0,0 +1 @@
|
||||
oフ厠?フOフテフhファフユフ>フフフ猯變ケフ侘ヤフEフsフ領採4フ厠体「フ6フフリフ賣\フフフ5フェフイフ蔑mフフ摸醂コフ慘ルファフフ﨓﨓摸フ<>mフ<6D>ホフオフGフ<47>Oフロフ フテフ<EFBE83>ホフ<EFBE8E><EFBE8C>;フ販<EFBE8C>フ栂モフタフラフ,フムフ「フ睥Aフ9フサフ賣のツフsフ<73>フシフンフフュフeフ<65>ンフUフuフ﨓アフヒフwフ<77>蔑Dプフ粁スフtフ槊」フケフ<EFBDB9><EFBE8C>Oフ閒﨓<E99692>pフGフ<47>ーフタフ(フフフフ、フ{フ椴゚フ<EFBE9F>ユフフ<>フMフ#フ變﨓オフdフキフIプフhフ_フpフJフヌフ「フホフフoフ⇔<EFBE8C>チフ;フ<フ侘ZフネフムフoフWフ<57>ソフ}フ睥フフ:フ睥ァフ蔑サフeフFフtフ(フEフoフ猯pフフ「フ(フ;フ<>フ<EFBFBD><EFBE8C>!フケフケフノフフ慘閒ヨフ4フネフ3フ<33>粁Bフ捨ニフuフPフ6フ椴<EFBE8C>フ&フヲフウフ蔑チフ<EFBE81>サフフフTフタファフbフフメフユフ<EFBE95>{フニフ。フハフNフ9フヌフフBフム
|
@ -10,24 +10,27 @@ Contents
|
||||
|[CVE-2005-2096](https://nvd.nist.gov/vuln/detail/CVE-2005-2096)|Buffer overflow when incomplete code description
|
||||
|[GH-361](https://github.com/zlib-ng/zlib-ng/issues/361)|Test case for overlapping matches|
|
||||
|[GH-364](https://github.com/zlib-ng/zlib-ng/issues/364)|Test case for switching compression levels|
|
||||
|[GH-382](https://github.com/zlib-ng/zlib-ng/issues/382)|Test case for deflateEnd returning -3 in deflate quick|
|
||||
|
||||
Copying
|
||||
-------
|
||||
|
||||
Some of the test data in test/data is licensed differently:
|
||||
Some of the files in _test_ are licensed differently:
|
||||
|
||||
- fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and
|
||||
- test/data/fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and
|
||||
is licensed under the Creative Commons Attribution 3.0 license
|
||||
(CC-BY-3.0). See https://creativecommons.org/licenses/by/3.0/
|
||||
for more information.
|
||||
|
||||
- paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper
|
||||
- test/data/paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper
|
||||
“Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA
|
||||
Replication Timing in _Drosophila_” by Federico Comoglio and Renato Paro,
|
||||
which is licensed under the CC-BY license. See
|
||||
http://www.ploscompbiol.org/static/license for more information.
|
||||
|
||||
- lcet10.txt is from Project
|
||||
Gutenberg. It does not have expired copyright, but is still in the
|
||||
public domain according to the license information.
|
||||
(http://www.gutenberg.org/ebooks/53).
|
||||
- test/data/lcet10.txt is from Project Gutenberg. It does not have expired
|
||||
copyright, but is still in the public domain according to the license information.
|
||||
(http://www.gutenberg.org/ebooks/53).
|
||||
|
||||
- test/GH-382/defneg3.dat was the smallest file generated by Nathan Moinvaziri
|
||||
that reproduced GH-382. It is licensed under the terms of the zlib license.
|
||||
|
307
test/minideflate.c
Normal file
307
test/minideflate.c
Normal file
@ -0,0 +1,307 @@
|
||||
/* minideflate.c -- test deflate/inflate under specific conditions
|
||||
* Copyright (C) 2020 Nathan Moinvaziri
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "zbuild.h"
|
||||
#ifdef ZLIB_COMPAT
|
||||
# include "zlib.h"
|
||||
#else
|
||||
# include "zlib-ng.h"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
|
||||
#else
|
||||
# define SET_BINARY_MODE(file)
|
||||
#endif
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
|
||||
#define CHECK_ERR(err, msg) { \
|
||||
if (err != Z_OK) { \
|
||||
fprintf(stderr, "%s error: %d\n", msg, err); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* deflate() using specialized parameters
|
||||
*/
|
||||
void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t level,
|
||||
int32_t window_bits, int32_t mem_level, int32_t strategy, int32_t flush) {
|
||||
PREFIX3(stream) c_stream; /* compression stream */
|
||||
uint8_t *read_buf;
|
||||
uint8_t *write_buf;
|
||||
int32_t read;
|
||||
int err;
|
||||
|
||||
read_buf = (uint8_t *)malloc(read_buf_size);
|
||||
if (read_buf == NULL) {
|
||||
fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size);
|
||||
return;
|
||||
}
|
||||
write_buf = (uint8_t *)malloc(write_buf_size);
|
||||
if (write_buf == NULL) {
|
||||
fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size);
|
||||
free(read_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
c_stream.zalloc = NULL;
|
||||
c_stream.zfree = NULL;
|
||||
c_stream.opaque = (void *)0;
|
||||
c_stream.total_in = 0;
|
||||
c_stream.total_out = 0;
|
||||
|
||||
err = PREFIX(deflateInit2)(&c_stream, level, Z_DEFLATED, window_bits, mem_level, strategy);
|
||||
CHECK_ERR(err, "deflateInit2");
|
||||
|
||||
/* Process input using our read buffer and flush type,
|
||||
* output to stdout only once write buffer is full */
|
||||
do {
|
||||
read = (int32_t)fread(read_buf, 1, read_buf_size, fin);
|
||||
if (read <= 0)
|
||||
break;
|
||||
|
||||
c_stream.next_in = (const uint8_t *)read_buf;
|
||||
c_stream.next_out = write_buf;
|
||||
c_stream.avail_in = read;
|
||||
|
||||
do {
|
||||
c_stream.avail_out = write_buf_size;
|
||||
err = PREFIX(deflate)(&c_stream, flush);
|
||||
if (err == Z_STREAM_END) break;
|
||||
CHECK_ERR(err, "deflate");
|
||||
|
||||
if (c_stream.next_out == write_buf + write_buf_size) {
|
||||
fwrite(write_buf, 1, write_buf_size, fout);
|
||||
c_stream.next_out = write_buf;
|
||||
}
|
||||
} while (c_stream.next_in < read_buf + read);
|
||||
} while (err == Z_OK);
|
||||
|
||||
/* Finish the stream if necessary */
|
||||
if (flush != Z_FINISH) {
|
||||
c_stream.avail_in = 0;
|
||||
do {
|
||||
if (c_stream.next_out == write_buf + write_buf_size) {
|
||||
fwrite(write_buf, 1, write_buf_size, fout);
|
||||
c_stream.next_out = write_buf;
|
||||
}
|
||||
|
||||
c_stream.avail_out = write_buf_size;
|
||||
err = PREFIX(deflate)(&c_stream, Z_FINISH);
|
||||
if (err == Z_STREAM_END) break;
|
||||
CHECK_ERR(err, "deflate");
|
||||
} while (err == Z_OK);
|
||||
}
|
||||
|
||||
/* Output remaining data in write buffer */
|
||||
if (c_stream.next_out != write_buf) {
|
||||
fwrite(write_buf, 1, c_stream.next_out - write_buf, fout);
|
||||
}
|
||||
|
||||
err = PREFIX(deflateEnd)(&c_stream);
|
||||
CHECK_ERR(err, "deflateEnd");
|
||||
|
||||
free(read_buf);
|
||||
free(write_buf);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* inflate() using specialized parameters
|
||||
*/
|
||||
void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t window_bits,
|
||||
int32_t flush) {
|
||||
PREFIX3(stream) d_stream; /* decompression stream */
|
||||
uint8_t *read_buf;
|
||||
uint8_t *write_buf;
|
||||
int32_t read;
|
||||
int err;
|
||||
|
||||
|
||||
read_buf = (uint8_t *)malloc(read_buf_size);
|
||||
if (read_buf == NULL) {
|
||||
fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size);
|
||||
return;
|
||||
}
|
||||
write_buf = (uint8_t *)malloc(write_buf_size);
|
||||
if (write_buf == NULL) {
|
||||
fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size);
|
||||
free(read_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
d_stream.zalloc = NULL;
|
||||
d_stream.zfree = NULL;
|
||||
d_stream.opaque = (void *)0;
|
||||
d_stream.total_in = 0;
|
||||
d_stream.total_out = 0;
|
||||
|
||||
err = PREFIX(inflateInit2)(&d_stream, window_bits);
|
||||
CHECK_ERR(err, "inflateInit2");
|
||||
|
||||
/* Process input using our read buffer and flush type,
|
||||
* output to stdout only once write buffer is full */
|
||||
do {
|
||||
read = (int32_t)fread(read_buf, 1, read_buf_size, fin);
|
||||
if (read <= 0)
|
||||
break;
|
||||
|
||||
d_stream.next_in = (const uint8_t *)read_buf;
|
||||
d_stream.next_out = write_buf;
|
||||
d_stream.avail_in = read;
|
||||
|
||||
do {
|
||||
d_stream.avail_out = write_buf_size;
|
||||
err = PREFIX(inflate)(&d_stream, flush);
|
||||
if (err == Z_STREAM_END) break;
|
||||
CHECK_ERR(err, "deflate");
|
||||
|
||||
if (d_stream.next_out == write_buf + write_buf_size) {
|
||||
fwrite(write_buf, 1, write_buf_size, fout);
|
||||
d_stream.next_out = write_buf;
|
||||
}
|
||||
} while (d_stream.next_in < read_buf + read);
|
||||
} while (err == Z_OK);
|
||||
|
||||
/* Finish the stream if necessary */
|
||||
if (flush != Z_FINISH) {
|
||||
d_stream.avail_in = 0;
|
||||
do {
|
||||
if (d_stream.next_out == write_buf + write_buf_size) {
|
||||
fwrite(write_buf, 1, write_buf_size, fout);
|
||||
d_stream.next_out = write_buf;
|
||||
}
|
||||
|
||||
d_stream.avail_out = write_buf_size;
|
||||
err = PREFIX(inflate)(&d_stream, Z_FINISH);
|
||||
if (err == Z_STREAM_END) break;
|
||||
CHECK_ERR(err, "inflate");
|
||||
} while (err == Z_OK);
|
||||
}
|
||||
|
||||
/* Output remaining data in write buffer */
|
||||
if (d_stream.next_out != write_buf) {
|
||||
fwrite(write_buf, 1, d_stream.next_out - write_buf, fout);
|
||||
}
|
||||
|
||||
err = PREFIX(inflateEnd)(&d_stream);
|
||||
CHECK_ERR(err, "inflateEnd");
|
||||
|
||||
free(read_buf);
|
||||
free(write_buf);
|
||||
}
|
||||
|
||||
void show_help(void) {
|
||||
printf("Usage: minideflate [-c] [-f|-h|-R|-F] [-m level] [-r/-t size] [-s flush] [-w bits] [-0 to -9] [input file]\n\n" \
|
||||
" -c : write to standard output\n" \
|
||||
" -d : decompress\n" \
|
||||
" -f : compress with Z_FILTERED\n" \
|
||||
" -h : compress with Z_HUFFMAN_ONLY\n" \
|
||||
" -R : compress with Z_RLE\n" \
|
||||
" -F : compress with Z_FIXED\n" \
|
||||
" -m : memory level (1 to 8)\n" \
|
||||
" -w : window bits (8 to 15 for gzip, -8 to -15 for zlib)\n" \
|
||||
" -s : flush type (0 to 5)\n" \
|
||||
" -r : read buffer size\n" \
|
||||
" -t : write buffer size\n" \
|
||||
" -0 to -9 : compression level\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int32_t i;
|
||||
int32_t mem_level = DEF_MEM_LEVEL;
|
||||
int32_t window_bits = MAX_WBITS;
|
||||
int32_t strategy = Z_DEFAULT_STRATEGY;
|
||||
int32_t level = Z_DEFAULT_COMPRESSION;
|
||||
int32_t read_buf_size = 4096;
|
||||
int32_t write_buf_size = 4096;
|
||||
int32_t flush = Z_NO_FLUSH;
|
||||
uint8_t copyout = 0;
|
||||
uint8_t uncompr = 0;
|
||||
char out_file[320];
|
||||
FILE *fin = stdin;
|
||||
FILE *fout = stdout;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if ((strcmp(argv[i], "-m") == 0) && (i + 1 < argc))
|
||||
mem_level = atoi(argv[++i]);
|
||||
else if ((strcmp(argv[i], "-w") == 0) && (i + 1 < argc))
|
||||
window_bits = atoi(argv[++i]);
|
||||
else if ((strcmp(argv[i], "-r") == 0) && (i + 1 < argc))
|
||||
read_buf_size = atoi(argv[++i]);
|
||||
else if ((strcmp(argv[i], "-t") == 0) && (i + 1 < argc))
|
||||
write_buf_size = atoi(argv[++i]);
|
||||
else if ((strcmp(argv[i], "-s") == 0) && (i + 1 < argc))
|
||||
flush = atoi(argv[++i]);
|
||||
else if (strcmp(argv[i], "-c") == 0)
|
||||
copyout = 1;
|
||||
else if (strcmp(argv[i], "-d") == 0)
|
||||
uncompr = 1;
|
||||
else if (strcmp(argv[i], "-f") == 0)
|
||||
strategy = Z_FILTERED;
|
||||
else if (strcmp(argv[i], "-h") == 0)
|
||||
strategy = Z_HUFFMAN_ONLY;
|
||||
else if (strcmp(argv[i], "-R") == 0)
|
||||
strategy = Z_RLE;
|
||||
else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0)
|
||||
level = argv[i][1] - '0';
|
||||
else if (strcmp(argv[i], "--help") == 0) {
|
||||
show_help();
|
||||
return 0;
|
||||
} else if (argv[i][0] == '-') {
|
||||
show_help();
|
||||
return 64; /* EX_USAGE */
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
SET_BINARY_MODE(stdin);
|
||||
SET_BINARY_MODE(stdout);
|
||||
if (i != argc) {
|
||||
fin = fopen(argv[i], "rb+");
|
||||
if (fin == NULL) {
|
||||
fprintf(stderr, "Failed to open file: %s\n", argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
if (!copyout) {
|
||||
snprintf(out_file, sizeof(out_file), "%s%s", argv[i], (window_bits < 0) ? ".zz" : ".gz");
|
||||
fout = fopen(out_file, "wb");
|
||||
if (fout == NULL) {
|
||||
fprintf(stderr, "Failed to open file: %s\n", out_file);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uncompr) {
|
||||
inflate_params(fin, fout, read_buf_size, write_buf_size, window_bits, flush);
|
||||
} else {
|
||||
deflate_params(fin, fout, read_buf_size, write_buf_size, level, window_bits, mem_level, strategy, flush);
|
||||
}
|
||||
|
||||
if (fin != stdin) {
|
||||
fclose(fin);
|
||||
}
|
||||
if (fout != stdout) {
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user