Skip to content
This repository has been archived by the owner on Sep 3, 2020. It is now read-only.

Commit

Permalink
longest_match: avoid using negative indices
Browse files Browse the repository at this point in the history
  • Loading branch information
iii-i authored and Dead2 committed Jul 18, 2019
1 parent d4b927b commit bca4862
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 6 deletions.
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,9 @@ if (ZLIB_ENABLE_TESTS)
add_executable(minigzip test/minigzip.c)
configure_test_executable(minigzip)

add_executable(switchlevels test/switchlevels.c)
configure_test_executable(switchlevels)

if(HAVE_OFF64_T)
add_executable(example64 test/example.c)
configure_test_executable(example64)
Expand Down Expand Up @@ -866,6 +869,13 @@ if (ZLIB_ENABLE_TESTS)
"-DCOMMAND=${GH_361_COMMAND}"
-DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/GH-361/test.txt
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake)

set(GH_364_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:switchlevels> 1 5 9 3)
add_test(NAME GH-364
COMMAND ${CMAKE_COMMAND}
"-DCOMMAND=${GH_364_COMMAND}"
-DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/GH-364/test.bin
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake)
endif()

FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES)
Expand Down
1 change: 1 addition & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@ sed < $SRCDIR/test/Makefile.in "
/^COMPATTESTS *=/s#=.*#=$COMPATTESTS#
/^QEMU_RUN *=/s#=.*#=$QEMU_RUN#
/^WITH_FUZZERS *=/s#=.*#=$with_fuzzers#
/^LIBNAME *=/s#=.*#=$LIBNAME#
" > test/Makefile

# create zlib.pc with the configure results
Expand Down
6 changes: 3 additions & 3 deletions match_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static inline unsigned longest_match(deflate_state *const s, IPos cur_match) {
/*
* Do not waste too much time if we already have a good match
*/
best_len = s->prev_length;
best_len = s->prev_length ? s->prev_length : 1;
chain_length = s->max_chain_length;
if (best_len >= s->good_match)
chain_length >>= 2;
Expand Down Expand Up @@ -186,7 +186,7 @@ static inline unsigned longest_match(deflate_state *const s, IPos cur_match) {
/*
* Do not waste too much time if we already have a good match
*/
best_len = s->prev_length;
best_len = s->prev_length ? s->prev_length : 1;
chain_length = s->max_chain_length;
if (best_len >= s->good_match)
chain_length >>= 2;
Expand Down Expand Up @@ -385,7 +385,7 @@ static inline unsigned longest_match(deflate_state *const s, IPos cur_match) {
register unsigned char *scan = window + strstart; /* current string */
register unsigned char *match; /* matched string */
register unsigned int len; /* length of current match */
unsigned int best_len = s->prev_length; /* best match length so far */
unsigned int best_len = s->prev_length ? s->prev_length : 1; /* best match length so far */
unsigned int nice_match = s->nice_match; /* stop if match long enough */
IPos limit = strstart > (IPos)MAX_DIST(s) ?
strstart - (IPos)MAX_DIST(s) : NIL;
Expand Down
3 changes: 3 additions & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# ignore Makefiles; they're all automatically generated
Makefile
/switchlevels
/switchlevels.dSYM/
/switchlevels.exe
Binary file added test/GH-364/test.bin
Binary file not shown.
2 changes: 2 additions & 0 deletions test/INDEX
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ CVE-2005-1849 :
CVE-2005-2096 : test cases for the relevant CVEs
GH-361 : test case for overlapping matches
https://github.com/zlib-ng/zlib-ng/issues/361
GH-364 : test case for switching compression levels
https://github.com/zlib-ng/zlib-ng/issues/364

testCVEinputs.sh: script to run tests for CVEs where input data is supplied

14 changes: 11 additions & 3 deletions test/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ CFLAGS=
EXE=
SRCDIR=
SRCTOP=
TEST_LDFLAGS=-L.. ../libz.a
LIBNAME=
TEST_LDFLAGS=-L.. ../$(LIBNAME).a
WITH_FUZZERS=

COMPATTESTS =
Expand Down Expand Up @@ -97,15 +98,22 @@ CVE-2003-0107$(EXE): CVE-2003-0107.o
$(CC) $(CFLAGS) -o $@ CVE-2003-0107.o $(TEST_LDFLAGS)

.PHONY: ghtests
ghtests: testGH-361
ghtests: testGH-361 testGH-364

.PHONY: testGH-361
testGH-361:
$(QEMU_RUN) ../minigzip$(EXE) -4 <$(SRCDIR)/GH-361/test.txt >/dev/null

switchlevels$(EXE): $(SRCDIR)/switchlevels.c
$(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS)

.PHONY: testGH-364
testGH-364: switchlevels$(EXE)
$(QEMU_RUN) ./switchlevels$(EXE) 1 5 9 3 <$(SRCDIR)/GH-364/test.bin >/dev/null

clean:
rm -f *.o *.gcda *.gcno *.gcov
rm -f CVE-2003-0107$(EXE)
rm -f CVE-2003-0107$(EXE) switchlevels$(EXE)

distclean:
rm -f Makefile
112 changes: 112 additions & 0 deletions test/switchlevels.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* Compresses a user-specified number of chunks from stdin into stdout as a single gzip stream.
* Each chunk is compressed with a user-specified level.
*/

#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
#else
# include "zlib-ng.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int read_all(unsigned char *buf, size_t size)
{
for (size_t total_read = 0; total_read < size;) {
size_t n_read = fread(buf + total_read, 1, size - total_read, stdin);
if (ferror(stdin)) {
perror("fread\n");
return 1;
}
if (n_read == 0) {
fprintf(stderr, "Premature EOF\n");
return 1;
}
total_read += n_read;
}
return 0;
}

static int write_all(unsigned char *buf, size_t size)
{
for (size_t total_written = 0; total_written < size;) {
size_t n_written = fwrite(buf + total_written, 1, size - total_written, stdout);
if (ferror(stdout)) {
perror("fwrite\n");
return 1;
}
total_written += n_written;
}
return 0;
}

static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last)
{
int ret = 1;
int err = PREFIX(deflateParams)(strm, level, Z_DEFAULT_STRATEGY);
if (err != Z_OK) {
fprintf(stderr, "deflateParams() failed with code %d\n", err);
goto done;
}
unsigned long compsize = 100 + 2 * PREFIX(deflateBound)(strm, size);
unsigned char *buf = malloc(size + compsize);
if (buf == NULL) {
fprintf(stderr, "Out of memory\n");
goto done;
}
if (read_all(buf, size) != 0) {
goto free_buf;
}
strm->next_in = buf;
strm->avail_in = size;
strm->next_out = buf + size;
strm->avail_out = compsize;
err = PREFIX(deflate)(strm, last ? Z_FINISH : Z_SYNC_FLUSH);
if ((!last && err != Z_OK) || (last && err != Z_STREAM_END)) {
fprintf(stderr, "deflate() failed with code %d\n", err);
goto free_buf;
}
if (strm->avail_in != 0) {
fprintf(stderr, "deflate() did not consume %d bytes of input\n", strm->avail_in);
goto free_buf;
}
if (write_all(buf + size, compsize - strm->avail_out) != 0) {
goto free_buf;
}
ret = 0;
free_buf:
free(buf);
done:
return ret;
}

/* ===========================================================================
* Usage: switchlevels level1 size1 [level2 size2 ...]
*/

int main(int argc, char **argv)
{
int ret = EXIT_FAILURE;
PREFIX3(stream) strm;
memset(&strm, 0, sizeof(strm));
int err = PREFIX(deflateInit2)(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK) {
fprintf(stderr, "deflateInit() failed with code %d\n", err);
goto done;
}
for (int i = 1; i < argc - 1; i += 2) {
int level = atoi(argv[i]);
int size = atoi(argv[i + 1]);
if (compress_chunk(&strm, level, size, i + 2 >= argc - 1) != 0) {
goto deflate_end;
}
}
ret = EXIT_SUCCESS;
deflate_end:
PREFIX(deflateEnd)(&strm);
done:
return ret;
}

0 comments on commit bca4862

Please sign in to comment.