unittests: Cover the decompression API with tests
This commit is contained in:
parent
90aaa9e083
commit
a4cd265e7c
|
@ -7,6 +7,7 @@ clean-local: code-coverage-clean
|
||||||
distclean-local: code-coverage-dist-clean
|
distclean-local: code-coverage-dist-clean
|
||||||
|
|
||||||
noinst_PROGRAMS = asn1
|
noinst_PROGRAMS = asn1
|
||||||
|
TESTS = asn1
|
||||||
|
|
||||||
noinst_HEADERS = torture.h
|
noinst_HEADERS = torture.h
|
||||||
|
|
||||||
|
@ -17,7 +18,16 @@ asn1_CFLAGS = $(CMOCKA_CFLAGS) $(CODE_COVERAGE_CFLAGS)
|
||||||
asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la \
|
asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la \
|
||||||
$(CMOCKA_LIBS) $(CODE_COVERAGE_LIBS) $(OPTIONAL_OPENSSL_LIBS)
|
$(CMOCKA_LIBS) $(CODE_COVERAGE_LIBS) $(OPTIONAL_OPENSSL_LIBS)
|
||||||
|
|
||||||
|
if ENABLE_ZLIB
|
||||||
|
noinst_PROGRAMS += compression
|
||||||
|
TESTS += compression
|
||||||
|
|
||||||
|
compression_SOURCES = compression.c
|
||||||
|
compression_CFLAGS = $(CMOCKA_CFLAGS) $(CODE_COVERAGE_CFLAGS)
|
||||||
|
compression_LDADD = $(top_builddir)/src/libopensc/libopensc.la \
|
||||||
|
$(CMOCKA_LIBS) $(CODE_COVERAGE_LIBS) $(OPTIONAL_ZLIB_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
TESTS = asn1
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
TOPDIR = ..\..\..
|
TOPDIR = ..\..\..
|
||||||
|
|
||||||
TARGETS = asn1
|
TARGETS = asn1 compression
|
||||||
|
|
||||||
OBJECTS = asn1.obj \
|
OBJECTS = asn1.obj \
|
||||||
|
compression.obj
|
||||||
$(TOPDIR)\win32\versioninfo.res
|
$(TOPDIR)\win32\versioninfo.res
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
/*
|
||||||
|
* compression.c: Unit tests for compression API
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Author: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "torture.h"
|
||||||
|
#include "libopensc/log.c"
|
||||||
|
#include "libopensc/compression.c"
|
||||||
|
|
||||||
|
/* The data from fuzzer has valid header (0x1f, 0x8b), but anything
|
||||||
|
* after that is just garbage. The first call to inflate()
|
||||||
|
* returns Z_STREAM_END, calculated number of processed bytes 0, while
|
||||||
|
* keeping the allocated buffers.
|
||||||
|
*/
|
||||||
|
u8 invalid_data[] = {
|
||||||
|
0x1f, 0x8b, 0x08, 0x10, 0x08, 0x78, 0x10, 0x1f,
|
||||||
|
0x8b, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x8b, 0x08,
|
||||||
|
0x10, 0x08, 0x78, 0x10, 0x1f, 0x8b, 0x08, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1f, 0x8b, 0x08, 0x10, 0x08, 0x78,
|
||||||
|
0x10, 0x1f, 0x8b, 0x08, 0x61, 0x61, 0x61, 0x61,
|
||||||
|
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
|
||||||
|
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
|
||||||
|
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x08, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1f, 0x8b, 0x08, 0x10, 0x08, 0x78,
|
||||||
|
0x10, 0x1f, 0x8b};
|
||||||
|
|
||||||
|
/* Generated using
|
||||||
|
* $ echo "test" > /tmp/test
|
||||||
|
* $ gzip -c /tmp/test > /tmp/test.gz
|
||||||
|
* $ hexdump -C /tmp/test.gz
|
||||||
|
*/
|
||||||
|
u8 valid_data[] = {
|
||||||
|
0x1f, 0x8b, 0x08, 0x08, 0x5d, 0xd8, 0xcb, 0x5d,
|
||||||
|
0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x00, 0x2b,
|
||||||
|
0x49, 0x2d, 0x2e, 0xe1, 0x02, 0x00, 0xc6, 0x35,
|
||||||
|
0xb9, 0x3b, 0x05, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
/* Generated as in the previous test case with some added mess on the end
|
||||||
|
*/
|
||||||
|
u8 invalid_suffix_data[] = {
|
||||||
|
0x1f, 0x8b, 0x08, 0x08, 0x5d, 0xd8, 0xcb, 0x5d,
|
||||||
|
0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x00, 0x2b,
|
||||||
|
0x49, 0x2d, 0x2e, 0xe1, 0x02, 0x00, 0xc6, 0x35,
|
||||||
|
0xb9, 0x3b, 0x05, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff};
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_empty(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
u8 *data = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = 0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
assert_null(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_gzip_empty(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
u8 *data = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = 0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, data, datalen, COMPRESSION_GZIP);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
assert_null(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_zlib_empty(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
u8 *data = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = 0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, data, datalen, COMPRESSION_ZLIB);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
assert_null(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_header(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
u8 data[] = {0x1f, 0x8b};
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = sizeof(data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
assert_null(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_header_invalid(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
u8 data[] = {0x1e, 0x8a};
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = sizeof(data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
assert_null(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_invalid(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = sizeof(invalid_data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, invalid_data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
assert_null(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_valid(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = sizeof(valid_data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, valid_data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_SUCCESS);
|
||||||
|
assert_int_equal(buflen, 5);
|
||||||
|
assert_memory_equal(buf, "test\x0a", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_alloc_invalid_suffix(void **state)
|
||||||
|
{
|
||||||
|
u8 *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t datalen = sizeof(invalid_suffix_data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress_alloc(&buf, &buflen, invalid_suffix_data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_SUCCESS); /* TODO Is this fine? */
|
||||||
|
assert_int_equal(buflen, 5);
|
||||||
|
assert_memory_equal(buf, "test\x0a", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Decompress without allocation */
|
||||||
|
static void torture_compression_decompress_empty(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
u8 *data = NULL;
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = 0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, sizeof(buf)); /* Was not touched */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_gzip_empty(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
u8 *data = NULL;
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = 0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, data, datalen, COMPRESSION_GZIP);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_zlib_empty(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
u8 *data = NULL;
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = 0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, data, datalen, COMPRESSION_ZLIB);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_header(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
u8 data[] = {0x1f, 0x8b};
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = sizeof(data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_header_invalid(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
u8 data[] = {0x1e, 0x8a};
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = sizeof(data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_invalid(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = sizeof(invalid_data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, invalid_data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
assert_int_equal(buflen, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_valid(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = sizeof(valid_data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, valid_data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_SUCCESS);
|
||||||
|
assert_int_equal(buflen, 5);
|
||||||
|
assert_memory_equal(buf, "test\x0a", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_compression_decompress_invalid_suffix(void **state)
|
||||||
|
{
|
||||||
|
u8 buf[1024];
|
||||||
|
size_t buflen = sizeof(buf);
|
||||||
|
size_t datalen = sizeof(invalid_suffix_data);
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = sc_decompress(buf, &buflen, invalid_suffix_data, datalen, COMPRESSION_AUTO);
|
||||||
|
assert_int_equal(rv, SC_SUCCESS); /* TODO Is this fine? */
|
||||||
|
assert_int_equal(buflen, 5);
|
||||||
|
assert_memory_equal(buf, "test\x0a", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct CMUnitTest tests[] = {
|
||||||
|
/* Decompress alloc */
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_empty),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_gzip_empty),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_zlib_empty),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_header),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_header_invalid),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_invalid),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_invalid_suffix),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_alloc_valid),
|
||||||
|
/* Decompress */
|
||||||
|
cmocka_unit_test(torture_compression_decompress_empty),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_gzip_empty),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_zlib_empty),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_header),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_header_invalid),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_invalid),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_invalid_suffix),
|
||||||
|
cmocka_unit_test(torture_compression_decompress_valid),
|
||||||
|
};
|
||||||
|
|
||||||
|
rc = cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
return rc;
|
||||||
|
}
|
Loading…
Reference in New Issue