summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am21
-rw-r--r--tests/Makefile.in65
-rw-r--r--tests/bcj_test.c65
-rw-r--r--tests/compress_prepared_bcj_sparcbin1240 -> 0 bytes
-rw-r--r--tests/compress_prepared_bcj_x86bin1388 -> 0 bytes
-rw-r--r--tests/create_compress_files.c5
-rw-r--r--tests/files/README30
-rw-r--r--tests/files/good-1-sparc-lzma2.xzbin612 -> 0 bytes
-rw-r--r--tests/files/good-1-x86-lzma2.xzbin716 -> 0 bytes
-rw-r--r--tests/ossfuzz/Makefile18
-rw-r--r--tests/ossfuzz/config/fuzz.dict2
-rw-r--r--tests/ossfuzz/config/fuzz.options2
-rw-r--r--tests/ossfuzz/config/fuzz_decode_alone.options5
-rw-r--r--tests/ossfuzz/config/fuzz_decode_stream.options4
-rw-r--r--tests/ossfuzz/config/fuzz_encode_stream.options4
-rw-r--r--tests/ossfuzz/config/fuzz_lzma.dict22
-rw-r--r--tests/ossfuzz/config/fuzz_xz.dict4
-rw-r--r--tests/ossfuzz/fuzz.c82
-rw-r--r--tests/ossfuzz/fuzz_common.h55
-rw-r--r--tests/ossfuzz/fuzz_decode_alone.c41
-rw-r--r--tests/ossfuzz/fuzz_decode_stream.c53
-rw-r--r--tests/ossfuzz/fuzz_encode_stream.c86
-rw-r--r--tests/test_bcj_exact_size.c5
-rw-r--r--tests/test_block_header.c7
-rw-r--r--tests/test_check.c5
-rwxr-xr-xtests/test_compress.sh68
-rwxr-xr-xtests/test_compress_generated_abc1
-rwxr-xr-xtests/test_compress_generated_random1
-rwxr-xr-xtests/test_compress_generated_text1
-rwxr-xr-xtests/test_compress_prepared_bcj_sparc3
-rwxr-xr-xtests/test_compress_prepared_bcj_x863
-rwxr-xr-xtests/test_files.sh29
-rw-r--r--tests/test_filter_flags.c42
-rw-r--r--tests/test_filter_str.c104
-rw-r--r--tests/test_hardware.c5
-rw-r--r--tests/test_index.c192
-rw-r--r--tests/test_index_hash.c5
-rw-r--r--tests/test_lzip_decoder.c85
-rw-r--r--tests/test_memlimit.c5
-rw-r--r--tests/test_microlzma.c568
-rwxr-xr-xtests/test_scripts.sh17
-rw-r--r--tests/test_stream_flags.c5
-rwxr-xr-xtests/test_suffix.sh192
-rw-r--r--tests/test_vli.c5
-rw-r--r--tests/tests.cmake198
-rw-r--r--tests/tests.h5
-rw-r--r--tests/tuktest.h18
47 files changed, 1709 insertions, 424 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ebc33a7..d85328d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,26 +1,19 @@
-##
+## SPDX-License-Identifier: 0BSD
## Author: Lasse Collin
-##
-## This file has been put into the public domain.
-## You can do whatever you want with this file.
-##
EXTRA_DIST = \
files \
ossfuzz \
+ tests.cmake \
tuktest.h \
tests.h \
test_files.sh \
test_compress.sh \
- test_compress_prepared_bcj_sparc \
- test_compress_prepared_bcj_x86 \
test_compress_generated_abc \
test_compress_generated_random \
test_compress_generated_text \
test_scripts.sh \
- bcj_test.c \
- compress_prepared_bcj_sparc \
- compress_prepared_bcj_x86 \
+ test_suffix.sh \
xzgrep_expected_output
AM_CPPFLAGS = \
@@ -61,12 +54,16 @@ TESTS = \
test_lzip_decoder \
test_vli \
test_files.sh \
- test_compress_prepared_bcj_sparc \
- test_compress_prepared_bcj_x86 \
+ test_suffix.sh \
test_compress_generated_abc \
test_compress_generated_random \
test_compress_generated_text
+if COND_MICROLZMA
+check_PROGRAMS += test_microlzma
+TESTS += test_microlzma
+endif
+
if COND_SCRIPTS
TESTS += test_scripts.sh
endif
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 46cf0f0..5c80f0b 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -93,22 +93,23 @@ check_PROGRAMS = create_compress_files$(EXEEXT) test_check$(EXEEXT) \
test_block_header$(EXEEXT) test_index$(EXEEXT) \
test_index_hash$(EXEEXT) test_bcj_exact_size$(EXEEXT) \
test_memlimit$(EXEEXT) test_lzip_decoder$(EXEEXT) \
- test_vli$(EXEEXT)
+ test_vli$(EXEEXT) $(am__EXEEXT_1)
TESTS = test_check$(EXEEXT) test_hardware$(EXEEXT) \
test_stream_flags$(EXEEXT) test_filter_flags$(EXEEXT) \
test_filter_str$(EXEEXT) test_block_header$(EXEEXT) \
test_index$(EXEEXT) test_index_hash$(EXEEXT) \
test_bcj_exact_size$(EXEEXT) test_memlimit$(EXEEXT) \
test_lzip_decoder$(EXEEXT) test_vli$(EXEEXT) test_files.sh \
- test_compress_prepared_bcj_sparc \
- test_compress_prepared_bcj_x86 test_compress_generated_abc \
+ test_suffix.sh test_compress_generated_abc \
test_compress_generated_random test_compress_generated_text \
- $(am__append_1)
-@COND_SCRIPTS_TRUE@am__append_1 = test_scripts.sh
+ $(am__EXEEXT_1) $(am__append_3)
+@COND_MICROLZMA_TRUE@am__append_1 = test_microlzma
+@COND_MICROLZMA_TRUE@am__append_2 = test_microlzma
+@COND_SCRIPTS_TRUE@am__append_3 = test_scripts.sh
subdir = tests
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_capsicum.m4 \
- $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/getopt.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/build-to-host.m4 $(top_srcdir)/m4/getopt.m4 \
$(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/host-cpu-c-abi.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
@@ -131,6 +132,7 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
+@COND_MICROLZMA_TRUE@am__EXEEXT_1 = test_microlzma$(EXEEXT)
create_compress_files_SOURCES = create_compress_files.c
create_compress_files_OBJECTS = create_compress_files.$(OBJEXT)
create_compress_files_LDADD = $(LDADD)
@@ -191,6 +193,11 @@ test_memlimit_OBJECTS = test_memlimit.$(OBJEXT)
test_memlimit_LDADD = $(LDADD)
test_memlimit_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \
$(am__DEPENDENCIES_1)
+test_microlzma_SOURCES = test_microlzma.c
+test_microlzma_OBJECTS = test_microlzma.$(OBJEXT)
+test_microlzma_LDADD = $(LDADD)
+test_microlzma_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \
+ $(am__DEPENDENCIES_1)
test_stream_flags_SOURCES = test_stream_flags.c
test_stream_flags_OBJECTS = test_stream_flags.$(OBJEXT)
test_stream_flags_LDADD = $(LDADD)
@@ -223,7 +230,8 @@ am__depfiles_remade = ./$(DEPDIR)/create_compress_files.Po \
./$(DEPDIR)/test_filter_str.Po ./$(DEPDIR)/test_hardware.Po \
./$(DEPDIR)/test_index.Po ./$(DEPDIR)/test_index_hash.Po \
./$(DEPDIR)/test_lzip_decoder.Po ./$(DEPDIR)/test_memlimit.Po \
- ./$(DEPDIR)/test_stream_flags.Po ./$(DEPDIR)/test_vli.Po
+ ./$(DEPDIR)/test_microlzma.Po ./$(DEPDIR)/test_stream_flags.Po \
+ ./$(DEPDIR)/test_vli.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -247,12 +255,12 @@ SOURCES = create_compress_files.c test_bcj_exact_size.c \
test_block_header.c test_check.c test_filter_flags.c \
test_filter_str.c test_hardware.c test_index.c \
test_index_hash.c test_lzip_decoder.c test_memlimit.c \
- test_stream_flags.c test_vli.c
+ test_microlzma.c test_stream_flags.c test_vli.c
DIST_SOURCES = create_compress_files.c test_bcj_exact_size.c \
test_block_header.c test_check.c test_filter_flags.c \
test_filter_str.c test_hardware.c test_index.c \
test_index_hash.c test_lzip_decoder.c test_memlimit.c \
- test_stream_flags.c test_vli.c
+ test_microlzma.c test_stream_flags.c test_vli.c
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -494,7 +502,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CAPSICUM_LIB = @CAPSICUM_LIB@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
@@ -623,6 +630,8 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
+localedir_c = @localedir_c@
+localedir_c_make = @localedir_c_make@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
@@ -644,19 +653,16 @@ xz = @xz@
EXTRA_DIST = \
files \
ossfuzz \
+ tests.cmake \
tuktest.h \
tests.h \
test_files.sh \
test_compress.sh \
- test_compress_prepared_bcj_sparc \
- test_compress_prepared_bcj_x86 \
test_compress_generated_abc \
test_compress_generated_random \
test_compress_generated_text \
test_scripts.sh \
- bcj_test.c \
- compress_prepared_bcj_sparc \
- compress_prepared_bcj_x86 \
+ test_suffix.sh \
xzgrep_expected_output
AM_CPPFLAGS = \
@@ -752,6 +758,10 @@ test_memlimit$(EXEEXT): $(test_memlimit_OBJECTS) $(test_memlimit_DEPENDENCIES) $
@rm -f test_memlimit$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_memlimit_OBJECTS) $(test_memlimit_LDADD) $(LIBS)
+test_microlzma$(EXEEXT): $(test_microlzma_OBJECTS) $(test_microlzma_DEPENDENCIES) $(EXTRA_test_microlzma_DEPENDENCIES)
+ @rm -f test_microlzma$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_microlzma_OBJECTS) $(test_microlzma_LDADD) $(LIBS)
+
test_stream_flags$(EXEEXT): $(test_stream_flags_OBJECTS) $(test_stream_flags_DEPENDENCIES) $(EXTRA_test_stream_flags_DEPENDENCIES)
@rm -f test_stream_flags$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_stream_flags_OBJECTS) $(test_stream_flags_LDADD) $(LIBS)
@@ -777,6 +787,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_index_hash.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lzip_decoder.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_memlimit.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_microlzma.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_stream_flags.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_vli.Po@am__quote@ # am--include-marker
@@ -1097,16 +1108,9 @@ test_files.sh.log: test_files.sh
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
-test_compress_prepared_bcj_sparc.log: test_compress_prepared_bcj_sparc
- @p='test_compress_prepared_bcj_sparc'; \
- b='test_compress_prepared_bcj_sparc'; \
- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
- --log-file $$b.log --trs-file $$b.trs \
- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
- "$$tst" $(AM_TESTS_FD_REDIRECT)
-test_compress_prepared_bcj_x86.log: test_compress_prepared_bcj_x86
- @p='test_compress_prepared_bcj_x86'; \
- b='test_compress_prepared_bcj_x86'; \
+test_suffix.sh.log: test_suffix.sh
+ @p='test_suffix.sh'; \
+ b='test_suffix.sh'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
@@ -1132,6 +1136,13 @@ test_compress_generated_text.log: test_compress_generated_text
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_microlzma.log: test_microlzma$(EXEEXT)
+ @p='test_microlzma$(EXEEXT)'; \
+ b='test_microlzma'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
test_scripts.sh.log: test_scripts.sh
@p='test_scripts.sh'; \
b='test_scripts.sh'; \
@@ -1242,6 +1253,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/test_index_hash.Po
-rm -f ./$(DEPDIR)/test_lzip_decoder.Po
-rm -f ./$(DEPDIR)/test_memlimit.Po
+ -rm -f ./$(DEPDIR)/test_microlzma.Po
-rm -f ./$(DEPDIR)/test_stream_flags.Po
-rm -f ./$(DEPDIR)/test_vli.Po
-rm -f Makefile
@@ -1300,6 +1312,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/test_index_hash.Po
-rm -f ./$(DEPDIR)/test_lzip_decoder.Po
-rm -f ./$(DEPDIR)/test_memlimit.Po
+ -rm -f ./$(DEPDIR)/test_microlzma.Po
-rm -f ./$(DEPDIR)/test_stream_flags.Po
-rm -f ./$(DEPDIR)/test_vli.Po
-rm -f Makefile
diff --git a/tests/bcj_test.c b/tests/bcj_test.c
deleted file mode 100644
index 05de38a..0000000
--- a/tests/bcj_test.c
+++ /dev/null
@@ -1,65 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-/// \file bcj_test.c
-/// \brief Source code of compress_prepared_bcj_*
-///
-/// This is a simple program that should make the compiler to generate
-/// PC-relative branches, jumps, and calls. The compiled files can then
-/// be used to test the branch conversion filters. Note that this program
-/// itself does nothing useful.
-///
-/// Compiling: gcc -std=c99 -fPIC -c bcj_test.c
-/// Don't optimize or strip.
-//
-// Author: Lasse Collin
-//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-extern int jump(int a, int b);
-
-
-extern int
-call(int a, int b)
-{
- if (a < b)
- a = jump(a, b);
-
- return a;
-}
-
-
-extern int
-jump(int a, int b)
-{
- // The loop generates conditional jump backwards.
- while (1) {
- if (a < b) {
- a *= 2;
- a += 3 * b;
- break;
- } else {
- // Put enough code here to prevent JMP SHORT on x86.
- a += b;
- a /= 2;
- b += b % 5;
- a -= b / 3;
- b = 2 * b + a - 1;
- a *= b + a + 1;
- b += a - 1;
- a += b * 2 - a / 5;
- }
- }
-
- return a;
-}
-
-
-int
-main(int argc, char **argv)
-{
- int a = call(argc, argc + 1);
- return a == 0;
-}
diff --git a/tests/compress_prepared_bcj_sparc b/tests/compress_prepared_bcj_sparc
deleted file mode 100644
index 86ea7dd..0000000
--- a/tests/compress_prepared_bcj_sparc
+++ /dev/null
Binary files differ
diff --git a/tests/compress_prepared_bcj_x86 b/tests/compress_prepared_bcj_x86
deleted file mode 100644
index bcc546f..0000000
--- a/tests/compress_prepared_bcj_x86
+++ /dev/null
Binary files differ
diff --git a/tests/create_compress_files.c b/tests/create_compress_files.c
index 76aa3e3..2106ac8 100644
--- a/tests/create_compress_files.c
+++ b/tests/create_compress_files.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file create_compress_files.c
@@ -8,9 +10,6 @@
//
// Author: Lasse Collin
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "sysdefs.h"
diff --git a/tests/files/README b/tests/files/README
index 119cac4..584e6ba 100644
--- a/tests/files/README
+++ b/tests/files/README
@@ -1,6 +1,6 @@
-.xz and .lzma Test Files
-------------------------
+.xz, .lzma, and .lz Test Files
+------------------------------
0. Introduction
@@ -8,7 +8,8 @@
.lzma (LZMA_Alone), and .lz (lzip) files in decoder implementations.
Many of the files have been created by hand with a hex editor, thus
there is no better "source code" than the files themselves. All the
- test files and this README have been put into the public domain.
+ test files and this README may be distributed under the terms of
+ the BSD Zero Clause License (0BSD).
1. File Types
@@ -65,20 +66,25 @@
good-1-delta-lzma2.tiff.xz is an image file that compresses
better with Delta+LZMA2 than with plain LZMA2.
- good-1-x86-lzma2.xz uses the x86 filter (BCJ) and LZMA2. The
- uncompressed file is compress_prepared_bcj_x86 found from the tests
- directory.
-
- good-1-sparc-lzma2.xz uses the SPARC filter and LZMA2. The
- uncompressed file is compress_prepared_bcj_sparc found from the tests
- directory.
-
good-1-arm64-lzma2-1.xz uses the ARM64 filter and LZMA2. The
uncompressed data is constructed so that it tests integer
- wrap around and sign extension.
+ wrap around and sign extension. To recreate the file, compress
+ using XZ Utils 5.4.x (newer may or may not work too):
+
+ ./debug/testfilegen-arm64 \
+ | xz -T1 -Ccrc32 --arm64 \
+ --lzma2=dict=64KiB,lp=2,lc=2 \
+ > good-1-arm64-lzma2-1.xz
good-1-arm64-lzma2-2.xz is like good-1-arm64-lzma2-1.xz but with
non-zero start offset. XZ Embedded doesn't support this file.
+ To recreate the file, compress using XZ Utils 5.4.x (newer may or
+ may not work too):
+
+ ./debug/testfilegen-arm64 \
+ | xz -T1 -Ccrc32 --arm64=start=4294963200 \
+ --lzma2=dict=64KiB,lp=2,lc=2 \
+ > good-1-arm64-lzma2-2.xz
good-1-lzma2-1.xz has two LZMA2 chunks, of which the second sets
new properties.
diff --git a/tests/files/good-1-sparc-lzma2.xz b/tests/files/good-1-sparc-lzma2.xz
deleted file mode 100644
index 4532bc6..0000000
--- a/tests/files/good-1-sparc-lzma2.xz
+++ /dev/null
Binary files differ
diff --git a/tests/files/good-1-x86-lzma2.xz b/tests/files/good-1-x86-lzma2.xz
deleted file mode 100644
index 8053917..0000000
--- a/tests/files/good-1-x86-lzma2.xz
+++ /dev/null
Binary files differ
diff --git a/tests/ossfuzz/Makefile b/tests/ossfuzz/Makefile
index 747fb66..742e063 100644
--- a/tests/ossfuzz/Makefile
+++ b/tests/ossfuzz/Makefile
@@ -1,7 +1,17 @@
-fuzz: fuzz.c
- $(CC) $(CFLAGS) -c fuzz.c -I ../../src/liblzma/api/
- $(CXX) $(CXXFLAGS) $(LIB_FUZZING_ENGINE) fuzz.o -o $(OUT)/fuzz \
- ../../src/liblzma/.libs/liblzma.a
+# SPDX-License-Identifier: 0BSD
+FUZZ_TARGET_SRCS = $(wildcard *.c)
+FUZZ_TARGET_BINS = $(FUZZ_TARGET_SRCS:.c=)
+
+all: $(FUZZ_TARGET_BINS)
+
+%: %.c
+ $(CC) $(CFLAGS) -c $< -I ../../src/liblzma/api/ ;
+ $(CXX) $(CXXFLAGS) $(LIB_FUZZING_ENGINE) $(<:.c=.o) -o $(OUT)/$@ \
+ ../../src/liblzma/.libs/liblzma.a ;
+
+# The generated binaries are not removed, just the object files. The
+# binaries are created to the $(OUT) directory and must be removed by the
+# fuzzing framework.
clean:
rm -f *.o
diff --git a/tests/ossfuzz/config/fuzz.dict b/tests/ossfuzz/config/fuzz.dict
deleted file mode 100644
index 932d67c..0000000
--- a/tests/ossfuzz/config/fuzz.dict
+++ /dev/null
@@ -1,2 +0,0 @@
-"\xFD7zXZ\x00"
-"YZ"
diff --git a/tests/ossfuzz/config/fuzz.options b/tests/ossfuzz/config/fuzz.options
deleted file mode 100644
index d59dfc1..0000000
--- a/tests/ossfuzz/config/fuzz.options
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-dict = fuzz.dict
diff --git a/tests/ossfuzz/config/fuzz_decode_alone.options b/tests/ossfuzz/config/fuzz_decode_alone.options
new file mode 100644
index 0000000..1351d96
--- /dev/null
+++ b/tests/ossfuzz/config/fuzz_decode_alone.options
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: 0BSD
+
+[libfuzzer]
+max_len = 4096
+dict = fuzz_lzma.dict
diff --git a/tests/ossfuzz/config/fuzz_decode_stream.options b/tests/ossfuzz/config/fuzz_decode_stream.options
new file mode 100644
index 0000000..bbf43ac
--- /dev/null
+++ b/tests/ossfuzz/config/fuzz_decode_stream.options
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: 0BSD
+
+[libfuzzer]
+dict = fuzz_xz.dict
diff --git a/tests/ossfuzz/config/fuzz_encode_stream.options b/tests/ossfuzz/config/fuzz_encode_stream.options
new file mode 100644
index 0000000..86d4f0c
--- /dev/null
+++ b/tests/ossfuzz/config/fuzz_encode_stream.options
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: 0BSD
+
+[libfuzzer]
+max_len = 4096
diff --git a/tests/ossfuzz/config/fuzz_lzma.dict b/tests/ossfuzz/config/fuzz_lzma.dict
new file mode 100644
index 0000000..b9d5dff
--- /dev/null
+++ b/tests/ossfuzz/config/fuzz_lzma.dict
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: 0BSD
+
+# first 5 header bytes of .lzma archives based on the info from
+# /doc/lzma-file-format.txt
+
+# byte 0 is created by encoding LZMA property values (lc, lp, pb)
+# using the algorithm described in the documentation above.
+
+# lc=3, lp=0, pb=2 and dictionary size = 0x00100000
+"\x5d\x00\x00\x10\x00"
+
+# lc=3, lp=1, pb=3 and dictionary size = 0x00100000
+"\x93\x00\x00\x10\x00"
+
+# lc=2, lp=2, pb=4 and dictionary size = 0x00100000
+"\xc8\x00\x00\x10\x00"
+
+# lc=1, lp=3, pb=1 and dictionary size = 0x00200000
+"\x49\x00\x00\x20\x00"
+
+# lc=0, lp=4, pb=0 and dictionary size = 0x00200000
+"\x24\x00\x00\x20\x00"
diff --git a/tests/ossfuzz/config/fuzz_xz.dict b/tests/ossfuzz/config/fuzz_xz.dict
new file mode 100644
index 0000000..6ba4f24
--- /dev/null
+++ b/tests/ossfuzz/config/fuzz_xz.dict
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: 0BSD
+
+"\xFD7zXZ\x00"
+"YZ"
diff --git a/tests/ossfuzz/fuzz.c b/tests/ossfuzz/fuzz.c
deleted file mode 100644
index 6d89930..0000000
--- a/tests/ossfuzz/fuzz.c
+++ /dev/null
@@ -1,82 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-/// \file fuzz.c
-/// \brief Fuzz test program for liblzma
-//
-// Author: Lasse Collin
-//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "lzma.h"
-
-
-// Output buffer for decompressed data. This is write only; nothing cares
-// about the actual data written here.
-static uint8_t outbuf[4096];
-
-
-extern int
-LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
-{
- // Some header values can make liblzma allocate a lot of RAM
- // (up to about 4 GiB with liblzma 5.2.x). We set a limit here to
- // prevent extreme allocations when fuzzing.
- const uint64_t memlimit = 300 << 20; // 300 MiB
-
- // Initialize a .xz decoder using the above memory usage limit.
- // Enable support for concatenated .xz files which is used when
- // decompressing regular .xz files (instead of data embedded inside
- // some other file format). Integrity checks on the uncompressed
- // data are ignored to make fuzzing more effective (incorrect check
- // values won't prevent the decoder from processing more input).
- //
- // The flag LZMA_IGNORE_CHECK doesn't disable verification of header
- // CRC32 values. Those checks are disabled when liblzma is built
- // with the #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.
- lzma_stream strm = LZMA_STREAM_INIT;
- lzma_ret ret = lzma_stream_decoder(&strm, memlimit,
- LZMA_CONCATENATED | LZMA_IGNORE_CHECK);
- if (ret != LZMA_OK) {
- // This should never happen unless the system has
- // no free memory or address space to allow the small
- // allocations that the initialization requires.
- fprintf(stderr, "lzma_stream_decoder() failed (%d)\n", ret);
- abort();
- }
-
- // Give the whole input buffer at once to liblzma.
- // Output buffer isn't initialized as liblzma only writes to it.
- strm.next_in = inbuf;
- strm.avail_in = inbuf_size;
- strm.next_out = outbuf;
- strm.avail_out = sizeof(outbuf);
-
- while ((ret = lzma_code(&strm, LZMA_FINISH)) == LZMA_OK) {
- if (strm.avail_out == 0) {
- // outbuf became full. We don't care about the
- // uncompressed data there, so we simply reuse
- // the outbuf and overwrite the old data.
- strm.next_out = outbuf;
- strm.avail_out = sizeof(outbuf);
- }
- }
-
- // LZMA_PROG_ERROR should never happen as long as the code calling
- // the liblzma functions is correct. Thus LZMA_PROG_ERROR is a sign
- // of a bug in either this function or in liblzma.
- if (ret == LZMA_PROG_ERROR) {
- fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
- abort();
- }
-
- // Free the allocated memory.
- lzma_end(&strm);
-
- return 0;
-}
diff --git a/tests/ossfuzz/fuzz_common.h b/tests/ossfuzz/fuzz_common.h
new file mode 100644
index 0000000..4537f1b
--- /dev/null
+++ b/tests/ossfuzz/fuzz_common.h
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: 0BSD
+
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file fuzz_common.h
+/// \brief Common macros and functions needed by the fuzz targets
+//
+// Authors: Maksym Vatsyk
+// Lasse Collin
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "lzma.h"
+
+// Some header values can make liblzma allocate a lot of RAM
+// (up to about 4 GiB with liblzma 5.2.x). We set a limit here to
+// prevent extreme allocations when fuzzing.
+#define MEM_LIMIT (300 << 20) // 300 MiB
+
+
+static void
+fuzz_code(lzma_stream *stream, const uint8_t *inbuf, size_t inbuf_size) {
+ // Output buffer for decompressed data. This is write only; nothing
+ // cares about the actual data written here.
+ uint8_t outbuf[4096];
+
+ // Give the whole input buffer at once to liblzma.
+ // Output buffer isn't initialized as liblzma only writes to it.
+ stream->next_in = inbuf;
+ stream->avail_in = inbuf_size;
+ stream->next_out = outbuf;
+ stream->avail_out = sizeof(outbuf);
+
+ lzma_ret ret;
+ while ((ret = lzma_code(stream, LZMA_FINISH)) == LZMA_OK) {
+ if (stream->avail_out == 0) {
+ // outbuf became full. We don't care about the
+ // uncompressed data there, so we simply reuse
+ // the outbuf and overwrite the old data.
+ stream->next_out = outbuf;
+ stream->avail_out = sizeof(outbuf);
+ }
+ }
+
+ // LZMA_PROG_ERROR should never happen as long as the code calling
+ // the liblzma functions is correct. Thus LZMA_PROG_ERROR is a sign
+ // of a bug in either this function or in liblzma.
+ if (ret == LZMA_PROG_ERROR) {
+ fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
+ abort();
+ }
+}
diff --git a/tests/ossfuzz/fuzz_decode_alone.c b/tests/ossfuzz/fuzz_decode_alone.c
new file mode 100644
index 0000000..1ef2f9e
--- /dev/null
+++ b/tests/ossfuzz/fuzz_decode_alone.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: 0BSD
+
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file fuzz_decode_alone.c
+/// \brief Fuzz test program for liblzma .lzma decoding
+//
+// Authors: Maksym Vatsyk
+// Lasse Collin
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "lzma.h"
+#include "fuzz_common.h"
+
+
+extern int
+LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ // Initialize a LZMA alone decoder using the memory usage limit
+ // defined in fuzz_common.h
+ lzma_ret ret = lzma_alone_decoder(&strm, MEM_LIMIT);
+
+ if (ret != LZMA_OK) {
+ // This should never happen unless the system has
+ // no free memory or address space to allow the small
+ // allocations that the initialization requires.
+ fprintf(stderr, "lzma_alone_decoder() failed (%d)\n", ret);
+ abort();
+ }
+
+ fuzz_code(&strm, inbuf, inbuf_size);
+
+ // Free the allocated memory.
+ lzma_end(&strm);
+ return 0;
+}
diff --git a/tests/ossfuzz/fuzz_decode_stream.c b/tests/ossfuzz/fuzz_decode_stream.c
new file mode 100644
index 0000000..d786061
--- /dev/null
+++ b/tests/ossfuzz/fuzz_decode_stream.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: 0BSD
+
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file fuzz_decode_stream.c
+/// \brief Fuzz test program for single threaded .xz decoding
+//
+// Authors: Lasse Collin
+// Maksym Vatsyk
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "lzma.h"
+#include "fuzz_common.h"
+
+
+extern int
+LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ // Initialize a .xz decoder using the memory usage limit
+ // defined in fuzz_common.h
+ //
+ // Enable support for concatenated .xz files which is used when
+ // decompressing regular .xz files (instead of data embedded inside
+ // some other file format). Integrity checks on the uncompressed
+ // data are ignored to make fuzzing more effective (incorrect check
+ // values won't prevent the decoder from processing more input).
+ //
+ // The flag LZMA_IGNORE_CHECK doesn't disable verification of
+ // header CRC32 values. Those checks are disabled when liblzma is
+ // built with the #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.
+ lzma_ret ret = lzma_stream_decoder(&strm, MEM_LIMIT,
+ LZMA_CONCATENATED | LZMA_IGNORE_CHECK);
+
+ if (ret != LZMA_OK) {
+ // This should never happen unless the system has
+ // no free memory or address space to allow the small
+ // allocations that the initialization requires.
+ fprintf(stderr, "lzma_stream_decoder() failed (%d)\n", ret);
+ abort();
+ }
+
+ fuzz_code(&strm, inbuf, inbuf_size);
+
+ // Free the allocated memory.
+ lzma_end(&strm);
+
+ return 0;
+}
diff --git a/tests/ossfuzz/fuzz_encode_stream.c b/tests/ossfuzz/fuzz_encode_stream.c
new file mode 100644
index 0000000..9438263
--- /dev/null
+++ b/tests/ossfuzz/fuzz_encode_stream.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: 0BSD
+
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file fuzz_encode_stream.c
+/// \brief Fuzz test program for .xz encoding
+//
+// Authors: Maksym Vatsyk
+// Lasse Collin
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "lzma.h"
+#include "fuzz_common.h"
+
+
+extern int
+LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
+{
+ if (inbuf_size == 0) {
+ fprintf(stderr, "no input data provided\n");
+ return 0;
+ }
+
+ // Set the LZMA options based on the first input byte. The fuzzer
+ // will learn through its mutational genetic algorithm with the
+ // code coverage feedback that the first byte must be one of the
+ // values with a switch case label. This allows us to have one fuzz
+ // target cover many critical code paths so the fuzz resources can
+ // be used efficiently.
+ uint32_t preset_level;
+ const uint8_t decider = inbuf[0];
+
+ switch (decider) {
+ case 0:
+ case 1:
+ case 5:
+ preset_level = (uint32_t)decider;
+ break;
+ case 6:
+ preset_level = 0 | LZMA_PRESET_EXTREME;
+ break;
+ case 7:
+ preset_level = 3 | LZMA_PRESET_EXTREME;
+ break;
+ default:
+ return 0;
+ }
+
+ // Initialize lzma_options with the above preset level
+ lzma_options_lzma opt_lzma;
+ if (lzma_lzma_preset(&opt_lzma, preset_level)){
+ fprintf(stderr, "lzma_lzma_preset() failed\n");
+ abort();
+ }
+
+ // Set the filter chain as only LZMA2.
+ lzma_filter filters[2] = {
+ {
+ .id = LZMA_FILTER_LZMA2,
+ .options = &opt_lzma,
+ }, {
+ .id = LZMA_VLI_UNKNOWN,
+ }
+ };
+
+ // initialize empty LZMA stream
+ lzma_stream strm = LZMA_STREAM_INIT;
+
+ // Initialize the stream encoder using the above
+ // stream, filter chain and CRC64.
+ lzma_ret ret = lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC64);
+ if (ret != LZMA_OK) {
+ fprintf(stderr, "lzma_stream_encoder() failed (%d)\n", ret);
+ abort();
+ }
+
+ fuzz_code(&strm, inbuf + 1, inbuf_size - 1);
+
+ // Free the allocated memory.
+ lzma_end(&strm);
+ return 0;
+}
diff --git a/tests/test_bcj_exact_size.c b/tests/test_bcj_exact_size.c
index 551166c..fa82f0d 100644
--- a/tests/test_bcj_exact_size.c
+++ b/tests/test_bcj_exact_size.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_bcj_exact_size.c
@@ -7,9 +9,6 @@
//
// Author: Lasse Collin
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
diff --git a/tests/test_block_header.c b/tests/test_block_header.c
index b310135..d8e6221 100644
--- a/tests/test_block_header.c
+++ b/tests/test_block_header.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_block_header.c
@@ -6,9 +8,6 @@
// Authors: Lasse Collin
// Jia Tan
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
@@ -320,7 +319,7 @@ test_lzma_block_header_encode(void)
uint8_t flags = out[1];
// Should have number of filters = 1
- assert_uint_eq((flags & 0x3) + 1, 1);
+ assert_uint_eq((flags & 0x3) + 1U, 1);
// Bits 2-7 must be empty not set
assert_uint_eq(flags & (0xFF - 0x3), 0);
diff --git a/tests/test_check.c b/tests/test_check.c
index cb1ad25..9d51aa0 100644
--- a/tests/test_check.c
+++ b/tests/test_check.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_check.c
@@ -6,9 +8,6 @@
// Authors: Lasse Collin
// Jia Tan
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
diff --git a/tests/test_compress.sh b/tests/test_compress.sh
index ff13cef..a10343a 100755
--- a/tests/test_compress.sh
+++ b/tests/test_compress.sh
@@ -1,26 +1,37 @@
#!/bin/sh
+# SPDX-License-Identifier: 0BSD
###############################################################################
#
# Author: Lasse Collin
#
-# This file has been put into the public domain.
-# You can do whatever you want with this file.
-#
###############################################################################
+# Mandatory argument:
+# $1 = test filename: compress_generated_<foo> or compress_prepared_<foo>
+#
+# Optional argument:
+# $2 = directory of the xz and xzdec executables
+
+XZ=${2:-../src/xz}/xz
+XZDEC=${2:-../src/xzdec}/xzdec
+
# If xz wasn't built, this test is skipped.
-if test -x ../src/xz/xz ; then
- :
-else
+if test ! -x "$XZ"; then
+ echo "xz was not built, skipping this test."
exit 77
fi
+# xzdec isn't mandatory for this script.
+test -x "$XZDEC" || XZDEC=
+
# If compression or decompression support is missing, this test is skipped.
# This isn't perfect as if only some compressors or decompressors are disabled
# then this script can still fail because for now this doesn't check the
# availability of each filter.
-if grep 'define HAVE_ENCODERS' ../config.h > /dev/null \
+if test ! -f ../config.h ; then
+ :
+elif grep 'define HAVE_ENCODERS' ../config.h > /dev/null \
&& grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then
:
else
@@ -76,12 +87,12 @@ test_xz() {
fi
}
-XZ="../src/xz/xz --memlimit-compress=48MiB --memlimit-decompress=5MiB \
- --no-adjust --threads=1 --check=crc32"
-grep "define HAVE_CHECK_CRC64" ../config.h > /dev/null \
- && XZ="$XZ --check=crc64"
-XZDEC="../src/xzdec/xzdec" # No memory usage limiter available
-test -x ../src/xzdec/xzdec || XZDEC=
+# Set memory usage limit for xz. xzdec has no memory usage limiter.
+# Force single-threaded mode as the test files are small
+# (so more than one thread wouldn't be used anyway) and
+# the tests are usually run in parallel.
+XZ="$XZ --memlimit-compress=48MiB --memlimit-decompress=5MiB \
+ --no-adjust --threads=1"
# Create the required input file if needed.
#
@@ -130,21 +141,26 @@ test_xz -4
test_filter()
{
- grep "define HAVE_ENCODER_$1 1" ../config.h > /dev/null || return
- grep "define HAVE_DECODER_$1 1" ../config.h > /dev/null || return
+ if test -f ../config.h ; then
+ grep "define HAVE_ENCODER_$1 1" ../config.h > /dev/null \
+ || return
+ grep "define HAVE_DECODER_$1 1" ../config.h > /dev/null \
+ || return
+ fi
shift
- test_xz "$@" --lzma2=dict=64KiB,nice=32,mode=fast
+ test_xz --filters="$* lzma2:dict=64KiB,nice=32,mode=fast"
}
-test_filter DELTA --delta=dist=1
-test_filter DELTA --delta=dist=4
-test_filter DELTA --delta=dist=256
-test_filter X86 --x86
-test_filter POWERPC --power
-test_filter IA64 --ia64
-test_filter ARM --arm
-test_filter ARMTHUMB --armthumb
-test_filter ARM64 --arm64
-test_filter SPARC --sparc
+test_filter DELTA delta:dist=1
+test_filter DELTA delta:dist=4
+test_filter DELTA delta:dist=256
+test_filter X86 x86
+test_filter POWERPC powerpc
+test_filter IA64 ia64
+test_filter ARM arm
+test_filter ARMTHUMB armthumb
+test_filter ARM64 arm64
+test_filter SPARC sparc
+test_filter RISCV riscv
exit 0
diff --git a/tests/test_compress_generated_abc b/tests/test_compress_generated_abc
index 43c6951..b31d631 100755
--- a/tests/test_compress_generated_abc
+++ b/tests/test_compress_generated_abc
@@ -1,3 +1,4 @@
#!/bin/sh
+# SPDX-License-Identifier: 0BSD
exec "$srcdir/test_compress.sh" compress_generated_abc
diff --git a/tests/test_compress_generated_random b/tests/test_compress_generated_random
index e47555d..c20f3da 100755
--- a/tests/test_compress_generated_random
+++ b/tests/test_compress_generated_random
@@ -1,3 +1,4 @@
#!/bin/sh
+# SPDX-License-Identifier: 0BSD
exec "$srcdir/test_compress.sh" compress_generated_random
diff --git a/tests/test_compress_generated_text b/tests/test_compress_generated_text
index 412ae0e..2c8c171 100755
--- a/tests/test_compress_generated_text
+++ b/tests/test_compress_generated_text
@@ -1,3 +1,4 @@
#!/bin/sh
+# SPDX-License-Identifier: 0BSD
exec "$srcdir/test_compress.sh" compress_generated_text
diff --git a/tests/test_compress_prepared_bcj_sparc b/tests/test_compress_prepared_bcj_sparc
deleted file mode 100755
index deb76ef..0000000
--- a/tests/test_compress_prepared_bcj_sparc
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-exec "$srcdir/test_compress.sh" compress_prepared_bcj_sparc
diff --git a/tests/test_compress_prepared_bcj_x86 b/tests/test_compress_prepared_bcj_x86
deleted file mode 100755
index 3452d7f..0000000
--- a/tests/test_compress_prepared_bcj_x86
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-exec "$srcdir/test_compress.sh" compress_prepared_bcj_x86
diff --git a/tests/test_files.sh b/tests/test_files.sh
index 60402e7..99c9f2f 100755
--- a/tests/test_files.sh
+++ b/tests/test_files.sh
@@ -1,17 +1,18 @@
#!/bin/sh
+# SPDX-License-Identifier: 0BSD
###############################################################################
#
# Author: Lasse Collin
#
-# This file has been put into the public domain.
-# You can do whatever you want with this file.
-#
###############################################################################
-# If both xz and xzdec were not build, skip this test.
-XZ=../src/xz/xz
-XZDEC=../src/xzdec/xzdec
+# Optional argument:
+# $1 = directory of the xz executable
+
+# If both xz and xzdec were not built, skip this test.
+XZ=${1:-../src/xz}/xz
+XZDEC=${2:-../src/xzdec}/xzdec
test -x "$XZ" || XZ=
test -x "$XZDEC" || XZDEC=
if test -z "$XZ$XZDEC"; then
@@ -23,7 +24,9 @@ fi
# This isn't perfect as if only some decompressors are disabled
# then some good files might not decompress and the test fails
# for a (kind of) wrong reason.
-if grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then
+if test ! -f ../config.h ; then
+ :
+elif grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then
:
else
echo "Decompression support is disabled, skipping this test."
@@ -35,6 +38,7 @@ fi
EXIT_STATUS=0
have_feature()
{
+ test -f ../config.h || return 0
grep "define HAVE_$1 1" ../config.h > /dev/null && return 0
printf '%s: Skipping because HAVE_%s is not enabled\n' "$2" "$1"
EXIT_STATUS=77
@@ -49,8 +53,10 @@ have_feature()
# If these integrity check types were disabled at build time,
# allow the tests to pass still.
NO_WARN=
-grep 'define HAVE_CHECK_CRC64' ../config.h > /dev/null || NO_WARN=-qQ
-grep 'define HAVE_CHECK_SHA256' ../config.h > /dev/null || NO_WARN=-qQ
+if test -f ../config.h ; then
+ grep 'define HAVE_CHECK_CRC64' ../config.h > /dev/null || NO_WARN=-qQ
+ grep 'define HAVE_CHECK_SHA256' ../config.h > /dev/null || NO_WARN=-qQ
+fi
for I in "$srcdir"/files/good-*.xz
do
@@ -80,6 +86,11 @@ do
have_feature DECODER_ARM64 "$I" || continue
;;
esac
+ case $I in
+ */good-1-riscv-lzma2-*.xz)
+ have_feature DECODER_RISCV "$I" || continue
+ ;;
+ esac
if test -z "$XZ" || "$XZ" $NO_WARN -dc "$I" > /dev/null; then
:
diff --git a/tests/test_filter_flags.c b/tests/test_filter_flags.c
index 6d9f0b9..9dfc16e 100644
--- a/tests/test_filter_flags.c
+++ b/tests/test_filter_flags.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_filter_flags.c
@@ -6,9 +8,6 @@
// Authors: Jia Tan
// Lasse Collin
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
@@ -48,6 +47,10 @@ static lzma_filter bcj_filters_encoders[] = {
#ifdef HAVE_ENCODER_SPARC
{ LZMA_FILTER_SPARC, NULL },
#endif
+#ifdef HAVE_ENCODER_RISCV
+ { LZMA_FILTER_RISCV, NULL },
+#endif
+ { LZMA_VLI_UNKNOWN, NULL }
};
// HAVE_ENCODERS ifdef not terminated here because decoders are
@@ -77,6 +80,10 @@ static lzma_filter bcj_filters_decoders[] = {
#ifdef HAVE_DECODER_SPARC
{ LZMA_FILTER_SPARC, NULL },
#endif
+#ifdef HAVE_DECODER_RISCV
+ { LZMA_FILTER_RISCV, NULL },
+#endif
+ { LZMA_VLI_UNKNOWN, NULL }
};
#endif
#endif
@@ -94,6 +101,7 @@ test_lzma_filter_flags_size(void)
// block header.
uint32_t size = 0;
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA1)) {
+ // LZMA1 isn't supported in .xz so we get LZMA_PROG_ERROR.
assert_lzma_ret(lzma_filter_flags_size(&size,
&lzma1_filter), LZMA_PROG_ERROR);
}
@@ -104,12 +112,8 @@ test_lzma_filter_flags_size(void)
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
}
- // Do not use macro ARRAY_SIZE() in the for loop condition directly.
- // If the BCJ filters are not configured and built, then ARRAY_SIZE()
- // will return 0 and cause a warning because the for loop will never
- // execute since any unsigned number cannot be < 0 (-Werror=type-limits).
- const uint32_t bcj_array_size = ARRAY_SIZE(bcj_filters_encoders);
- for (uint32_t i = 0; i < bcj_array_size; i++) {
+ for (size_t i = 0; bcj_filters_encoders[i].id != LZMA_VLI_UNKNOWN;
+ ++i) {
assert_lzma_ret(lzma_filter_flags_size(&size,
&bcj_filters_encoders[i]), LZMA_OK);
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
@@ -153,7 +157,7 @@ verify_filter_flags_encode(lzma_filter *filter, bool should_encode)
// First calculate the size of Filter Flags to know how much
// memory to allocate to hold the encoded Filter Flags
assert_lzma_ret(lzma_filter_flags_size(&size, filter), LZMA_OK);
- uint8_t *encoded_out = tuktest_malloc(size * sizeof(uint8_t));
+ uint8_t *encoded_out = tuktest_malloc(size);
size_t out_pos = 0;
if (!should_encode) {
assert_false(lzma_filter_flags_encode(filter, encoded_out,
@@ -220,8 +224,8 @@ test_lzma_filter_flags_encode(void)
.start_offset = 257
};
- const uint32_t bcj_array_size = ARRAY_SIZE(bcj_filters_encoders);
- for (uint32_t i = 0; i < bcj_array_size; i++) {
+ for (size_t i = 0; bcj_filters_encoders[i].id != LZMA_VLI_UNKNOWN;
+ ++i) {
// NULL options should pass for bcj filters
verify_filter_flags_encode(&bcj_filters_encoders[i], true);
lzma_filter bcj_with_options = {
@@ -263,7 +267,6 @@ test_lzma_filter_flags_encode(void)
size_t out_size = LZMA_BLOCK_HEADER_SIZE_MAX;
uint8_t out[LZMA_BLOCK_HEADER_SIZE_MAX];
-
// Filter ID outside of valid range
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos,
out_size), LZMA_PROG_ERROR);
@@ -328,7 +331,8 @@ test_lzma_filter_flags_encode(void)
// because it is agnostic to the type of options used in the call
#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
static void
-verify_filter_flags_decode(lzma_filter *filter_in, lzma_filter *filter_out)
+verify_filter_flags_decode(const lzma_filter *filter_in,
+ lzma_filter *filter_out)
{
uint32_t total_size = 0;
@@ -383,8 +387,8 @@ test_lzma_filter_flags_decode(void)
free(decoded);
}
- const uint32_t bcj_array_size = ARRAY_SIZE(bcj_filters_decoders);
- for (uint32_t i = 0; i < bcj_array_size; i++) {
+ for (size_t i = 0; bcj_filters_decoders[i].id != LZMA_VLI_UNKNOWN;
+ ++i) {
if (lzma_filter_encoder_is_supported(
bcj_filters_decoders[i].id)) {
lzma_filter bcj_decoded = {
@@ -398,7 +402,11 @@ test_lzma_filter_flags_decode(void)
&bcj_decoded);
assert_true(bcj_decoded.options == NULL);
- // Next test with offset
+ // Next test with start_offset.
+ //
+ // NOTE: The encoder and decoder don't verify if
+ // the start_offset is valid for the filter. Only
+ // the encoder or decoder initialization does.
lzma_options_bcj options = {
.start_offset = 257
};
diff --git a/tests/test_filter_str.c b/tests/test_filter_str.c
index 15aee55..42d9a22 100644
--- a/tests/test_filter_str.c
+++ b/tests/test_filter_str.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_filter_str.c
@@ -5,9 +7,6 @@
//
// Author: Jia Tan
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
@@ -20,37 +19,56 @@ test_lzma_str_to_filters(void)
int error_pos;
// Test with NULL string.
+ error_pos = -1;
assert_true(lzma_str_to_filters(NULL, &error_pos, filters, 0,
NULL) != NULL);
+ assert_int_eq(error_pos, 0);
// Test with NULL filter array.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2", &error_pos, NULL, 0,
NULL) != NULL);
+ assert_int_eq(error_pos, 0);
// Test with unsupported flags.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2", &error_pos, filters,
UINT32_MAX, NULL) != NULL);
+ assert_int_eq(error_pos, 0);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2", &error_pos, filters,
LZMA_STR_NO_SPACES << 1, NULL) != NULL);
+ assert_int_eq(error_pos, 0);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2", &error_pos, filters,
LZMA_STR_NO_SPACES, NULL) != NULL);
+ assert_int_eq(error_pos, 0);
// Test with empty string.
+ error_pos = -1;
assert_true(lzma_str_to_filters("", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 0);
// Test with invalid filter name and missing filter name.
+ error_pos = -1;
+ assert_true(lzma_str_to_filters("abcd", &error_pos,
+ filters, 0, NULL) != NULL);
+ assert_int_eq(error_pos, 0);
+
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2 abcd", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 6);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2--abcd", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 7);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2--", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 7);
@@ -58,12 +76,15 @@ test_lzma_str_to_filters(void)
// Test LZMA_STR_ALL_FILTERS flag (should work with LZMA1 if built).
#if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
// Using LZMA1 as a Filter should fail without LZMA_STR_ALL_FILTERS.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma1", &error_pos, filters,
0, NULL) != NULL);
assert_int_eq(error_pos, 0);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma1", &error_pos, filters,
LZMA_STR_ALL_FILTERS, NULL) == NULL);
+ assert_int_eq(error_pos, 5);
// Verify Filters array IDs are correct. The array should contain
// only two elements:
@@ -79,11 +100,15 @@ test_lzma_str_to_filters(void)
// same Filter multiple times in the chain and having a non-last
// Filter like lzma2 appear before another Filter.
// Without the flag, "lzma2 lzma2" must fail.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2 lzma2", &error_pos, filters,
0, NULL) != NULL);
+ assert_int_eq(error_pos, 11);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2 lzma2", &error_pos, filters,
LZMA_STR_NO_VALIDATION, NULL) == NULL);
+ assert_int_eq(error_pos, 11);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_FILTER_LZMA2);
@@ -92,48 +117,65 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
// Should fail with invalid Filter options (lc + lp must be <= 4).
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:lc=3,lp=3", &error_pos, filters,
LZMA_STR_NO_VALIDATION, NULL) != NULL);
+ assert_int_eq(error_pos, 15);
// Test invalid option name.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:foo=1,bar=2", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 6);
+ error_pos = -1;
+ assert_true(lzma_str_to_filters("lzma2:pb=1,bar=2", &error_pos,
+ filters, 0, NULL) != NULL);
+ assert_int_eq(error_pos, 11);
+
// Test missing option value.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:lc=", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 9);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:=,pb=1", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 6);
// Test unsupported preset value.
+ error_pos = -1;
assert_true(lzma_str_to_filters("-10", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 2);
+ error_pos = -1;
assert_true(lzma_str_to_filters("-5f", &error_pos,
filters, 0, NULL) != NULL);
assert_int_eq(error_pos, 2);
// Test filter chain too long.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2 lzma2 lzma2 lzma2 lzma2",
&error_pos, filters, LZMA_STR_NO_VALIDATION,
NULL) != NULL);
- assert_int_eq(error_pos, 24);
+ assert_int_eq(error_pos, 24); // The fifth is too many.
#if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
// Should fail with a Filter not supported in the .xz format (lzma1).
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma1", &error_pos, filters,
LZMA_STR_NO_VALIDATION, NULL) != NULL);
+ assert_int_eq(error_pos, 0);
#endif
// Test setting options with the "=" format.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2=dict=4096,lc=2,lp=2,pb=1,"
"mode=fast,nice=3,mf=hc3,depth=10", &error_pos,
filters, 0, NULL) == NULL);
+ assert_int_eq(error_pos, 63);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -151,8 +193,10 @@ test_lzma_str_to_filters(void)
#if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)
// Test BCJ Filter options.
+ error_pos = -1;
assert_true(lzma_str_to_filters("x86:start=16", &error_pos, filters,
LZMA_STR_NO_VALIDATION, NULL) == NULL);
+ assert_int_eq(error_pos, 12);
assert_uint_eq(filters[0].id, LZMA_FILTER_X86);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -165,8 +209,10 @@ test_lzma_str_to_filters(void)
#if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
// Test Delta Filter options.
+ error_pos = -1;
assert_true(lzma_str_to_filters("delta:dist=20", &error_pos, filters,
LZMA_STR_NO_VALIDATION, NULL) == NULL);
+ assert_int_eq(error_pos, 13);
assert_uint_eq(filters[0].id, LZMA_FILTER_DELTA);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -178,8 +224,10 @@ test_lzma_str_to_filters(void)
#endif
// Test skipping leading spaces.
+ error_pos = -1;
assert_true(lzma_str_to_filters(" lzma2", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 9);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -187,8 +235,10 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
// Test skipping trailing spaces.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2 ", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 9);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -196,8 +246,10 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
// Test with "--" instead of space separating.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2--lzma2", &error_pos, filters,
LZMA_STR_NO_VALIDATION, NULL) == NULL);
+ assert_int_eq(error_pos, 12);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_FILTER_LZMA2);
@@ -206,24 +258,30 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
// Test preset with and without leading "-", and with "e".
+ error_pos = -1;
assert_true(lzma_str_to_filters("-3", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 2);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
lzma_filters_free(filters, NULL);
+ error_pos = -1;
assert_true(lzma_str_to_filters("4", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 1);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
lzma_filters_free(filters, NULL);
+ error_pos = -1;
assert_true(lzma_str_to_filters("9e", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 2);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -231,8 +289,10 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
// Test using a preset as an lzma2 option.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:preset=9e", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 15);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -240,23 +300,33 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
// Test setting dictionary size with invalid modifier suffix.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:dict=4096ZiB", &error_pos, filters,
0, NULL) != NULL);
+ assert_int_eq(error_pos, 15);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:dict=4096KiBs", &error_pos, filters,
0, NULL) != NULL);
+ assert_int_eq(error_pos, 15);
// Test option that cannot have multiplier modifier.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:pb=1k", &error_pos, filters,
0, NULL) != NULL);
+ assert_int_eq(error_pos, 10);
// Test option value too large.
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:dict=4096GiB", &error_pos, filters,
0, NULL) != NULL);
+ assert_int_eq(error_pos, 11);
// Test valid uses of multiplier modifiers (k,m,g).
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:dict=4096KiB", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 18);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -266,8 +336,10 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:dict=40Mi", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 15);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -277,8 +349,10 @@ test_lzma_str_to_filters(void)
lzma_filters_free(filters, NULL);
+ error_pos = -1;
assert_true(lzma_str_to_filters("lzma2:dict=1g", &error_pos, filters,
0, NULL) == NULL);
+ assert_int_eq(error_pos, 13);
assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2);
assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN);
@@ -362,6 +436,10 @@ test_lzma_str_from_filters(void)
assert_true(lzma_str_to_filters("x86 lzma2", NULL, filters, 0, NULL)
== NULL);
+ // It always allocates the options structure even when it's not
+ // needed due to start_offset = 0 being the default.
+ assert_true(filters[0].options != NULL);
+
assert_lzma_ret(lzma_str_from_filters(&output_str, filters, 0, NULL),
LZMA_OK);
@@ -370,9 +448,7 @@ test_lzma_str_from_filters(void)
free(output_str);
// Test setting BCJ option to NULL.
- assert_false(filters[0].options == NULL);
free(filters[0].options);
-
filters[0].options = NULL;
assert_lzma_ret(lzma_str_from_filters(&output_str, filters, 0, NULL),
@@ -386,6 +462,7 @@ test_lzma_str_from_filters(void)
lzma_options_lzma opts;
assert_false(lzma_lzma_preset(&opts, LZMA_PRESET_DEFAULT));
+
// Test with too many Filters (array terminated after 4+ filters).
lzma_filter oversized_filters[LZMA_FILTERS_MAX + 2];
@@ -438,6 +515,9 @@ static const char supported_encoders[][9] = {
#ifdef HAVE_ENCODER_ARM64
"arm64",
#endif
+#ifdef HAVE_ENCODER_RISCV
+ "riscv",
+#endif
#ifdef HAVE_ENCODER_DELTA
"delta",
#endif
@@ -466,6 +546,9 @@ static const char supported_decoders[][9] = {
#ifdef HAVE_DECODER_ARM64
"arm64",
#endif
+#ifdef HAVE_DECODER_RISCV
+ "riscv",
+#endif
#ifdef HAVE_DECODER_DELTA
"delta",
#endif
@@ -494,6 +577,9 @@ static const char supported_filters[][9] = {
#if defined(HAVE_ENCODER_ARM64) || defined(HAVE_DECODER_ARM64)
"arm64",
#endif
+#if defined(HAVE_ENCODER_RISCV) || defined(HAVE_DECODER_RISCV)
+ "riscv",
+#endif
#if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
"delta",
#endif
@@ -512,18 +598,23 @@ test_lzma_str_list_filters(void)
// Test with bad flags.
assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN,
LZMA_STR_NO_VALIDATION , NULL), LZMA_OPTIONS_ERROR);
+ assert_true(str == NULL);
assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN,
LZMA_STR_NO_SPACES, NULL), LZMA_OPTIONS_ERROR);
+ assert_true(str == NULL);
// Test with bad Filter ID.
assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN - 1,
0, NULL), LZMA_OPTIONS_ERROR);
+ assert_true(str == NULL);
// Test LZMA_STR_ENCODER flag.
assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN,
LZMA_STR_ENCODER, NULL), LZMA_OK);
+ // NOTE: Just checking for "contains" is a bit weak check as
+ // "arm" matches "armthumb" and "arm64" too.
for (uint32_t i = 0; i < ARRAY_SIZE(supported_encoders); i++)
assert_str_contains(str, supported_encoders[i]);
@@ -541,6 +632,7 @@ test_lzma_str_list_filters(void)
// Test LZMA_STR_GETOPT_LONG flag.
assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN,
LZMA_STR_GETOPT_LONG, NULL), LZMA_OK);
+ assert_str_contains(str, "--");
free(str);
diff --git a/tests/test_hardware.c b/tests/test_hardware.c
index c72d9b2..45763f6 100644
--- a/tests/test_hardware.c
+++ b/tests/test_hardware.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_hardware.c
@@ -9,9 +11,6 @@
//
// Author: Jia Tan
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
diff --git a/tests/test_index.c b/tests/test_index.c
index a14b33d..ba1b978 100644
--- a/tests/test_index.c
+++ b/tests/test_index.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_index.c
@@ -8,10 +10,6 @@
// Authors: Jia Tan
// Lasse Collin
//
-//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
@@ -25,8 +23,11 @@
#define MEMLIMIT (UINT64_C(1) << 20)
+#ifdef HAVE_ENCODERS
static uint8_t *decode_buffer;
static size_t decode_buffer_size = 0;
+#endif
+
static lzma_index *decode_test_index;
@@ -44,8 +45,11 @@ test_lzma_index_memusage(void)
assert_uint_eq(lzma_index_memusage((lzma_vli)UINT32_MAX + 1, 1),
UINT64_MAX);
- // The maximum number of Blocks should be LZMA_VLI_MAX
- assert_uint_eq(lzma_index_memusage(1, LZMA_VLI_MAX), UINT64_MAX);
+ // While the number of blocks is lzma_vli, the real maximum value is
+ // much smaller than LZMA_VLI_MAX. Just check that it fails with a
+ // huge but valid VLI and that it succeeds with a smaller one.
+ assert_uint_eq(lzma_index_memusage(1, LZMA_VLI_MAX / 5), UINT64_MAX);
+ assert_uint(lzma_index_memusage(1, LZMA_VLI_MAX / 11), <, UINT64_MAX);
// Number of Streams must be non-zero
assert_uint_eq(lzma_index_memusage(0, 1), UINT64_MAX);
@@ -100,7 +104,7 @@ test_lzma_index_memused(void)
static void
test_lzma_index_append(void)
{
- // Basic input-ouput test done here.
+ // Basic input-output test done here.
// Less trivial tests for this function are done throughout
// other tests.
@@ -135,7 +139,7 @@ test_lzma_index_append(void)
lzma_index_end(idx, NULL);
// Test compressed .xz file size growing too large. This also tests
- // a failing assert fixed in 68bda971bb8b666a009331455fcedb4e18d837a4.
+ // a failing assert fixed in ae5c07b22a6b3766b84f409f1b6b5c100469068a.
// Should result in LZMA_DATA_ERROR.
idx = lzma_index_init(NULL);
@@ -224,28 +228,28 @@ test_lzma_index_checks(void)
assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
LZMA_OK);
assert_uint_eq(lzma_index_checks(idx),
- UINT32_C(1) << LZMA_CHECK_NONE);
+ LZMA_INDEX_CHECK_MASK_NONE);
// Set the check type to CRC32 and repeat
stream_flags.check = LZMA_CHECK_CRC32;
assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
LZMA_OK);
assert_uint_eq(lzma_index_checks(idx),
- UINT32_C(1) << LZMA_CHECK_CRC32);
+ LZMA_INDEX_CHECK_MASK_CRC32);
// Set the check type to CRC64 and repeat
stream_flags.check = LZMA_CHECK_CRC64;
assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
LZMA_OK);
assert_uint_eq(lzma_index_checks(idx),
- UINT32_C(1) << LZMA_CHECK_CRC64);
+ LZMA_INDEX_CHECK_MASK_CRC64);
// Set the check type to SHA256 and repeat
stream_flags.check = LZMA_CHECK_SHA256;
assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags),
LZMA_OK);
assert_uint_eq(lzma_index_checks(idx),
- UINT32_C(1) << LZMA_CHECK_SHA256);
+ LZMA_INDEX_CHECK_MASK_SHA256);
// Create second lzma_index and cat to first
lzma_index *second = lzma_index_init(NULL);
@@ -257,14 +261,14 @@ test_lzma_index_checks(void)
LZMA_OK);
assert_uint_eq(lzma_index_checks(second),
- UINT32_C(1) << LZMA_CHECK_CRC32);
+ LZMA_INDEX_CHECK_MASK_CRC32);
assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK);
// Index should now have both CRC32 and SHA256
assert_uint_eq(lzma_index_checks(idx),
- (UINT32_C(1) << LZMA_CHECK_CRC32) |
- (UINT32_C(1) << LZMA_CHECK_SHA256));
+ LZMA_INDEX_CHECK_MASK_CRC32 |
+ LZMA_INDEX_CHECK_MASK_SHA256);
// Change the check type of the second Stream to SHA256
stream_flags.check = LZMA_CHECK_SHA256;
@@ -273,7 +277,7 @@ test_lzma_index_checks(void)
// Index should now have only SHA256
assert_uint_eq(lzma_index_checks(idx),
- UINT32_C(1) << LZMA_CHECK_SHA256);
+ LZMA_INDEX_CHECK_MASK_SHA256);
// Test with a third Stream
lzma_index *third = lzma_index_init(NULL);
@@ -284,14 +288,14 @@ test_lzma_index_checks(void)
LZMA_OK);
assert_uint_eq(lzma_index_checks(third),
- UINT32_C(1) << LZMA_CHECK_CRC64);
+ LZMA_INDEX_CHECK_MASK_CRC64);
assert_lzma_ret(lzma_index_cat(idx, third, NULL), LZMA_OK);
// Index should now have CRC64 and SHA256
assert_uint_eq(lzma_index_checks(idx),
- (UINT32_C(1) << LZMA_CHECK_CRC64) |
- (UINT32_C(1) << LZMA_CHECK_SHA256));
+ LZMA_INDEX_CHECK_MASK_CRC64 |
+ LZMA_INDEX_CHECK_MASK_SHA256);
lzma_index_end(idx, NULL);
}
@@ -467,15 +471,18 @@ test_lzma_index_stream_size(void)
// Next, append a few Blocks and retest
assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
- assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
- assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
+ assert_lzma_ret(lzma_index_append(idx, NULL, 999, 1), LZMA_OK);
+ assert_lzma_ret(lzma_index_append(idx, NULL, 997, 1), LZMA_OK);
// Stream size should be:
// Size of Stream Header - 12 bytes
- // Size of all Blocks - 3000 bytes
+ // Size of all Blocks - 3000 bytes [*]
// Size of Index - 16 bytes
// Size of Stream Footer - 12 bytes
// Total: 3040 bytes
+ //
+ // [*] Block size is a multiple of 4 bytes so 999 and 997 get
+ // rounded up to 1000 bytes.
assert_uint_eq(lzma_index_stream_size(idx), 3040);
lzma_index *second = lzma_index_init(NULL);
@@ -520,10 +527,10 @@ test_lzma_index_total_size(void)
assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
assert_uint_eq(lzma_index_total_size(idx), 1000);
- assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
+ assert_lzma_ret(lzma_index_append(idx, NULL, 999, 1), LZMA_OK);
assert_uint_eq(lzma_index_total_size(idx), 2000);
- assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
+ assert_lzma_ret(lzma_index_append(idx, NULL, 997, 1), LZMA_OK);
assert_uint_eq(lzma_index_total_size(idx), 3000);
// Create second lzma_index and append Blocks to it.
@@ -545,6 +552,16 @@ test_lzma_index_total_size(void)
// from both Streams
assert_uint_eq(lzma_index_total_size(idx), 3200);
+ // Test sizes that aren't multiples of four bytes
+ assert_lzma_ret(lzma_index_append(idx, NULL, 11, 1), LZMA_OK);
+ assert_uint_eq(lzma_index_total_size(idx), 3212);
+
+ assert_lzma_ret(lzma_index_append(idx, NULL, 11, 1), LZMA_OK);
+ assert_uint_eq(lzma_index_total_size(idx), 3224);
+
+ assert_lzma_ret(lzma_index_append(idx, NULL, 9, 1), LZMA_OK);
+ assert_uint_eq(lzma_index_total_size(idx), 3236);
+
lzma_index_end(idx, NULL);
}
@@ -560,8 +577,8 @@ test_lzma_index_file_size(void)
assert_uint_eq(lzma_index_file_size(idx), 32);
assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
- assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
- assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK);
+ assert_lzma_ret(lzma_index_append(idx, NULL, 999, 1), LZMA_OK);
+ assert_lzma_ret(lzma_index_append(idx, NULL, 997, 1), LZMA_OK);
assert_uint_eq(lzma_index_file_size(idx), 3040);
@@ -690,6 +707,7 @@ test_lzma_index_iter_rewind(void)
assert_false(lzma_index_iter_next(&iter,
LZMA_INDEX_ITER_BLOCK));
assert_uint_eq(iter.block.number_in_file, i + 1);
+ assert_uint_eq(iter.block.number_in_stream, i + 1);
}
// Rewind back to the beginning and iterate over the Blocks again
@@ -700,6 +718,7 @@ test_lzma_index_iter_rewind(void)
assert_false(lzma_index_iter_next(&iter,
LZMA_INDEX_ITER_BLOCK));
assert_uint_eq(iter.block.number_in_file, i + 1);
+ assert_uint_eq(iter.block.number_in_stream, i + 1);
}
// Next concatenate two more lzma_indexes, iterate over them,
@@ -919,8 +938,9 @@ test_lzma_index_iter_next(void)
// Verify both Blocks
// Next call to iterate Block should return true because the
- // first Block can already be read from the LZMA_INDEX_ITER_STREAM
- // call.
+ // first Block can already be read from the earlier *successful*
+ // LZMA_INDEX_ITER_STREAM call; the previous failed call doesn't
+ // modify the iterator.
assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK));
// Rewind to test LZMA_INDEX_ITER_ANY
@@ -1046,13 +1066,14 @@ test_lzma_index_iter_locate(void)
lzma_index_iter_init(&iter, idx);
for (uint32_t n = 4; n <= 4 * 5555; n += 4)
- assert_lzma_ret(lzma_index_append(idx, NULL, n + 8, n),
+ assert_lzma_ret(lzma_index_append(idx, NULL, n + 7, n),
LZMA_OK);
assert_uint_eq(lzma_index_block_count(idx), 5555);
// First Record
assert_false(lzma_index_iter_locate(&iter, 0));
+ assert_uint_eq(iter.block.unpadded_size, 4 + 7);
assert_uint_eq(iter.block.total_size, 4 + 8);
assert_uint_eq(iter.block.uncompressed_size, 4);
assert_uint_eq(iter.block.compressed_file_offset,
@@ -1060,6 +1081,7 @@ test_lzma_index_iter_locate(void)
assert_uint_eq(iter.block.uncompressed_file_offset, 0);
assert_false(lzma_index_iter_locate(&iter, 3));
+ assert_uint_eq(iter.block.unpadded_size, 4 + 7);
assert_uint_eq(iter.block.total_size, 4 + 8);
assert_uint_eq(iter.block.uncompressed_size, 4);
assert_uint_eq(iter.block.compressed_file_offset,
@@ -1068,6 +1090,7 @@ test_lzma_index_iter_locate(void)
// Second Record
assert_false(lzma_index_iter_locate(&iter, 4));
+ assert_uint_eq(iter.block.unpadded_size, 2 * 4 + 7);
assert_uint_eq(iter.block.total_size, 2 * 4 + 8);
assert_uint_eq(iter.block.uncompressed_size, 2 * 4);
assert_uint_eq(iter.block.compressed_file_offset,
@@ -1077,6 +1100,7 @@ test_lzma_index_iter_locate(void)
// Last Record
assert_false(lzma_index_iter_locate(
&iter, lzma_index_uncompressed_size(idx) - 1));
+ assert_uint_eq(iter.block.unpadded_size, 4 * 5555 + 7);
assert_uint_eq(iter.block.total_size, 4 * 5555 + 8);
assert_uint_eq(iter.block.uncompressed_size, 4 * 5555);
assert_uint_eq(iter.block.compressed_file_offset,
@@ -1142,6 +1166,7 @@ test_lzma_index_iter_locate(void)
for (n = 0; n < group_multiple; ++n)
assert_lzma_ret(lzma_index_append(idx, NULL, 8, 0),
LZMA_OK);
+
assert_lzma_ret(lzma_index_append(idx, NULL, 16, 1), LZMA_OK);
assert_false(lzma_index_iter_locate(&iter, 0));
assert_uint_eq(iter.block.total_size, 16);
@@ -1171,17 +1196,17 @@ test_lzma_index_cat(void)
assert_lzma_ret(lzma_index_cat(dest, NULL, NULL), LZMA_PROG_ERROR);
assert_lzma_ret(lzma_index_cat(NULL, src, NULL), LZMA_PROG_ERROR);
- // Check for uncompressed size overflow
+ // Check for compressed size overflow
assert_lzma_ret(lzma_index_append(dest, NULL,
(UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK);
assert_lzma_ret(lzma_index_append(src, NULL,
(UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK);
assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR);
- // Check for compressed size overflow
lzma_index_end(src, NULL);
lzma_index_end(dest, NULL);
+ // Check for uncompressed size overflow
dest = lzma_index_init(NULL);
assert_true(dest != NULL);
@@ -1189,9 +1214,9 @@ test_lzma_index_cat(void)
assert_true(src != NULL);
assert_lzma_ret(lzma_index_append(dest, NULL,
- UNPADDED_SIZE_MIN, LZMA_VLI_MAX - 1), LZMA_OK);
+ UNPADDED_SIZE_MIN, (LZMA_VLI_MAX / 2) + 1), LZMA_OK);
assert_lzma_ret(lzma_index_append(src, NULL,
- UNPADDED_SIZE_MIN, LZMA_VLI_MAX - 1), LZMA_OK);
+ UNPADDED_SIZE_MIN, (LZMA_VLI_MAX / 2) + 1), LZMA_OK);
assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR);
lzma_index_end(dest, NULL);
@@ -1263,13 +1288,17 @@ my_alloc(void *opaque, size_t a, size_t b)
{
(void)opaque;
+ assert_true(SIZE_MAX / a >= b);
+
static unsigned count = 0;
- if (++count > 2)
+ if (count >= 2)
return NULL;
+ ++count;
return malloc(a * b);
}
+
static const lzma_allocator test_index_dup_alloc = { &my_alloc, NULL, NULL };
@@ -1326,6 +1355,7 @@ test_lzma_index_dup(void)
lzma_index_end(idx, NULL);
}
+
#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
static void
verify_index_buffer(const lzma_index *idx, const uint8_t *buffer,
@@ -1459,31 +1489,30 @@ test_lzma_index_encoder(void)
#endif
}
+
static void
generate_index_decode_buffer(void)
{
#ifdef HAVE_ENCODERS
decode_test_index = lzma_index_init(NULL);
- if (decode_test_index == NULL)
- return;
+ assert_true(decode_test_index != NULL);
// Add 4 Blocks
for (uint32_t i = 1; i < 5; i++)
- if (lzma_index_append(decode_test_index, NULL,
- 0x1000 * i, 0x100 * i) != LZMA_OK)
- return;
+ assert_lzma_ret(lzma_index_append(decode_test_index, NULL,
+ 0x1000 * i, 0x100 * i), LZMA_OK);
- size_t size = lzma_index_size(decode_test_index);
+ const size_t size = (size_t)lzma_index_size(decode_test_index);
decode_buffer = tuktest_malloc(size);
- if (lzma_index_buffer_encode(decode_test_index,
- decode_buffer, &decode_buffer_size, size) != LZMA_OK)
- decode_buffer_size = 0;
+ assert_lzma_ret(lzma_index_buffer_encode(decode_test_index,
+ decode_buffer, &decode_buffer_size, size), LZMA_OK);
+ assert_true(decode_buffer_size != 0);
#endif
}
-#ifdef HAVE_DECODERS
+#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
static void
decode_index(const uint8_t *buffer, const size_t size, lzma_stream *strm,
lzma_ret expected_error)
@@ -1498,11 +1527,10 @@ decode_index(const uint8_t *buffer, const size_t size, lzma_stream *strm,
static void
test_lzma_index_decoder(void)
{
-#ifndef HAVE_DECODERS
- assert_skip("Decoder support disabled");
+#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
+ assert_skip("Encoder or decoder support disabled");
#else
- if (decode_buffer_size == 0)
- assert_skip("Could not initialize decode test buffer");
+ assert_true(decode_buffer_size != 0);
lzma_stream strm = LZMA_STREAM_INIT;
@@ -1510,11 +1538,21 @@ test_lzma_index_decoder(void)
LZMA_PROG_ERROR);
assert_lzma_ret(lzma_index_decoder(&strm, NULL, MEMLIMIT),
LZMA_PROG_ERROR);
- assert_lzma_ret(lzma_index_decoder(NULL, &decode_test_index,
- MEMLIMIT), LZMA_PROG_ERROR);
+
+ // If the first argument (lzma_stream *strm) is NULL then
+ // *idx must still become NULL since the API docs say that
+ // it's done if an error occurs. This was fixed in
+ // 71eed2520e2eecae89bade9dceea16e56cfa2ea0.
+ lzma_index *idx_allocated = lzma_index_init(NULL);
+ lzma_index *idx = idx_allocated;
+ assert_lzma_ret(lzma_index_decoder(NULL, &idx, MEMLIMIT),
+ LZMA_PROG_ERROR);
+ assert_true(idx == NULL);
+
+ lzma_index_end(idx_allocated, NULL);
+ idx_allocated = NULL;
// Do actual decode
- lzma_index *idx;
assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT),
LZMA_OK);
@@ -1579,8 +1617,8 @@ test_lzma_index_buffer_encode(void)
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
assert_skip("Encoder or decoder support disabled");
#else
- // More simple test than test_lzma_index_encoder() because
- // currently lzma_index_buffer_encode() is mostly a wrapper
+ // These are simpler test than in test_lzma_index_encoder()
+ // because lzma_index_buffer_encode() is mostly a wrapper
// around lzma_index_encoder() anyway.
lzma_index *idx = lzma_index_init(NULL);
assert_true(idx != NULL);
@@ -1607,6 +1645,9 @@ test_lzma_index_buffer_encode(void)
0), LZMA_PROG_ERROR);
out_pos = 0;
assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
+ 0), LZMA_BUF_ERROR);
+ assert_uint_eq(out_pos, 0);
+ assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos,
1), LZMA_BUF_ERROR);
// Do encoding
@@ -1625,11 +1666,10 @@ test_lzma_index_buffer_encode(void)
static void
test_lzma_index_buffer_decode(void)
{
-#ifndef HAVE_DECODERS
- assert_skip("Decoder support disabled");
+#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
+ assert_skip("Encoder or decoder support disabled");
#else
- if (decode_buffer_size == 0)
- assert_skip("Could not initialize decode test buffer");
+ assert_true(decode_buffer_size != 0);
// Simple test since test_lzma_index_decoder() covers most of the
// lzma_index_buffer_decode() code anyway.
@@ -1638,34 +1678,70 @@ test_lzma_index_buffer_decode(void)
assert_lzma_ret(lzma_index_buffer_decode(NULL, NULL, NULL, NULL,
NULL, 0), LZMA_PROG_ERROR);
- lzma_index *idx;
uint64_t memlimit = MEMLIMIT;
size_t in_pos = 0;
+ lzma_index *idx_allocated = lzma_index_init(NULL);
+ lzma_index *idx = idx_allocated;
assert_lzma_ret(lzma_index_buffer_decode(&idx, NULL, NULL, NULL,
NULL, 0), LZMA_PROG_ERROR);
+ assert_true(idx == NULL);
+ idx = idx_allocated;
assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
NULL, NULL, 0), LZMA_PROG_ERROR);
+ assert_true(idx == NULL);
+ idx = idx_allocated;
assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
decode_buffer, NULL, 0), LZMA_PROG_ERROR);
+ assert_true(idx == NULL);
+ idx = idx_allocated;
assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
decode_buffer, NULL, 0), LZMA_PROG_ERROR);
+ assert_true(idx == NULL);
+ idx = idx_allocated;
assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
decode_buffer, &in_pos, 0), LZMA_DATA_ERROR);
+ assert_true(idx == NULL);
in_pos = 1;
+ idx = idx_allocated;
assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
decode_buffer, &in_pos, 0), LZMA_PROG_ERROR);
+ assert_true(idx == NULL);
+
+ // Test too short input
in_pos = 0;
+ idx = idx_allocated;
+ assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
+ decode_buffer, &in_pos, decode_buffer_size - 1),
+ LZMA_DATA_ERROR);
+ assert_true(idx == NULL);
+
+ lzma_index_end(idx_allocated, NULL);
+ idx_allocated = NULL;
// Test expected successful decode
+ in_pos = 0;
assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
decode_buffer, &in_pos, decode_buffer_size), LZMA_OK);
+ assert_uint_eq(in_pos, decode_buffer_size);
+ assert_true(index_is_equal(decode_test_index, idx));
+
+ lzma_index_end(idx, NULL);
+
+ // Test too much input. This won't read past
+ // the end of the allocated array (decode_buffer_size bytes).
+ in_pos = 0;
+ assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL,
+ decode_buffer, &in_pos, decode_buffer_size + 16),
+ LZMA_OK);
+
+ assert_uint_eq(in_pos, decode_buffer_size);
assert_true(index_is_equal(decode_test_index, idx));
lzma_index_end(idx, NULL);
diff --git a/tests/test_index_hash.c b/tests/test_index_hash.c
index f3c6e8f..842d534 100644
--- a/tests/test_index_hash.c
+++ b/tests/test_index_hash.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_index_hash.c
@@ -9,9 +11,6 @@
//
// Author: Jia Tan
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
diff --git a/tests/test_lzip_decoder.c b/tests/test_lzip_decoder.c
index 3743d43..cee97b8 100644
--- a/tests/test_lzip_decoder.c
+++ b/tests/test_lzip_decoder.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_lzip_decoder.c
@@ -5,9 +7,6 @@
//
// Author: Jia Tan
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
@@ -43,11 +42,11 @@ basic_lzip_decode(const char *src, const uint32_t expected_crc)
lzma_stream strm = LZMA_STREAM_INIT;
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, 0), LZMA_OK);
- uint8_t *output_buffer = tuktest_malloc(DECODE_CHUNK_SIZE);
+ uint8_t output_buffer[DECODE_CHUNK_SIZE];
strm.next_in = data;
strm.next_out = output_buffer;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_out = sizeof(output_buffer);
// Feed 1 byte at a time to the decoder to look for any bugs
// when switching between decoding sequences
@@ -59,12 +58,8 @@ basic_lzip_decode(const char *src, const uint32_t expected_crc)
checksum = lzma_crc32(output_buffer,
(size_t)(strm.next_out - output_buffer),
checksum);
- // No need to free output_buffer because it will
- // automatically be freed at the end of the test by
- // tuktest.
- output_buffer = tuktest_malloc(DECODE_CHUNK_SIZE);
strm.next_out = output_buffer;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_out = sizeof(output_buffer);
}
}
@@ -126,12 +121,12 @@ trailing_helper(const char *src, const uint32_t expected_data_checksum,
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT,
LZMA_CONCATENATED), LZMA_OK);
- uint8_t *output_buffer = tuktest_malloc(DECODE_CHUNK_SIZE);
+ uint8_t output_buffer[DECODE_CHUNK_SIZE];
strm.next_in = data;
- strm.next_out = output_buffer;
strm.avail_in = file_size;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.next_out = output_buffer;
+ strm.avail_out = sizeof(output_buffer);
lzma_ret ret = LZMA_OK;
while (ret == LZMA_OK) {
@@ -140,12 +135,8 @@ trailing_helper(const char *src, const uint32_t expected_data_checksum,
checksum = lzma_crc32(output_buffer,
(size_t)(strm.next_out - output_buffer),
checksum);
- // No need to free output_buffer because it will
- // automatically be freed at the end of the test by
- // tuktest.
- output_buffer = tuktest_malloc(DECODE_CHUNK_SIZE);
strm.next_out = output_buffer;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_out = sizeof(output_buffer);
}
}
@@ -182,20 +173,18 @@ decode_expect_error(const char *src, lzma_ret expected_error)
strm.avail_in = file_size;
strm.next_in = data;
- strm.avail_out = DECODE_CHUNK_SIZE;
- strm.next_out = output_buffer;
lzma_ret ret = LZMA_OK;
- while (ret == LZMA_OK) {
+ do {
// Discard output since we are only looking for errors
strm.next_out = output_buffer;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_out = sizeof(output_buffer);
if (strm.avail_in == 0)
ret = lzma_code(&strm, LZMA_FINISH);
else
ret = lzma_code(&strm, LZMA_RUN);
- }
+ } while (ret == LZMA_OK);
assert_lzma_ret(ret, expected_error);
lzma_end(&strm);
@@ -233,26 +222,25 @@ test_v1_trailing(void)
static void
-test_concatentated(void)
+test_concatenated(void)
{
// First test a file with one v0 member and one v1 member
// The first member should contain "Hello\n" and
// the second member should contain "World!\n"
-
lzma_stream strm = LZMA_STREAM_INIT;
size_t file_size;
uint8_t *v0_v1 = tuktest_file_from_srcdir("files/good-2-v0-v1.lz",
- &file_size);
+ &file_size);
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT,
LZMA_CONCATENATED), LZMA_OK);
uint8_t output_buffer[DECODE_CHUNK_SIZE];
- strm.avail_in = file_size;
strm.next_in = v0_v1;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_in = file_size;
strm.next_out = output_buffer;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
@@ -263,15 +251,15 @@ test_concatentated(void)
// The second file contains one v1 member and one v2 member
uint8_t *v1_v0 = tuktest_file_from_srcdir("files/good-2-v1-v0.lz",
- &file_size);
+ &file_size);
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT,
LZMA_CONCATENATED), LZMA_OK);
- strm.avail_in = file_size;
strm.next_in = v1_v0;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_in = file_size;
strm.next_out = output_buffer;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
@@ -281,15 +269,15 @@ test_concatentated(void)
// The third file contains 2 v1 members
uint8_t *v1_v1 = tuktest_file_from_srcdir("files/good-2-v1-v1.lz",
- &file_size);
+ &file_size);
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT,
LZMA_CONCATENATED), LZMA_OK);
- strm.avail_in = file_size;
strm.next_in = v1_v1;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_in = file_size;
strm.next_out = output_buffer;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
@@ -315,10 +303,10 @@ test_crc(void)
uint8_t output_buffer[DECODE_CHUNK_SIZE];
- strm.avail_in = file_size;
strm.next_in = data;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_in = file_size;
strm.next_out = output_buffer;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_DATA_ERROR);
@@ -326,10 +314,10 @@ test_crc(void)
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT,
LZMA_CONCATENATED | LZMA_IGNORE_CHECK), LZMA_OK);
- strm.avail_in = file_size;
strm.next_in = data;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_in = file_size;
strm.next_out = output_buffer;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
assert_uint_eq(strm.total_in, file_size);
@@ -338,10 +326,10 @@ test_crc(void)
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT,
LZMA_CONCATENATED | LZMA_TELL_ANY_CHECK), LZMA_OK);
- strm.avail_in = file_size;
strm.next_in = data;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_in = file_size;
strm.next_out = output_buffer;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_GET_CHECK);
assert_uint_eq(lzma_get_check(&strm), LZMA_CHECK_CRC32);
@@ -367,7 +355,7 @@ test_invalid_magic_bytes(void)
strm.next_in = lzip_id_string;
strm.avail_in = sizeof(lzip_id_string);
strm.next_out = output_buffer;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_RUN),
LZMA_FORMAT_ERROR);
@@ -393,10 +381,10 @@ test_invalid_version(void)
static void
test_invalid_dictionary_size(void)
{
- // First file has too small dictionary size field
+ // The first file has a too small dictionary size field.
decode_expect_error("files/bad-1-v1-dict-1.lz", LZMA_DATA_ERROR);
- // Second file has too large dictionary size field
+ // The second file has a too large dictionary size field.
decode_expect_error("files/bad-1-v1-dict-2.lz", LZMA_DATA_ERROR);
}
@@ -426,7 +414,7 @@ static void
test_invalid_memlimit(void)
{
// A very low memlimit should prevent decoding.
- // Should be able to update the memlimit after failing
+ // It should be possible to update the memlimit after the error.
size_t file_size;
uint8_t *data = tuktest_file_from_srcdir("files/good-1-v1.lz",
&file_size);
@@ -440,12 +428,12 @@ test_invalid_memlimit(void)
strm.next_in = data;
strm.avail_in = file_size;
strm.next_out = output_buffer;
- strm.avail_out = DECODE_CHUNK_SIZE;
+ strm.avail_out = sizeof(output_buffer);
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR);
- // Up the memlimit so decoding can continue.
- // First only increase by a small amount and expect an error
+ // Up the memlimit so that decoding can continue.
+ // First only increase by a small amount and expect an error.
assert_lzma_ret(lzma_memlimit_set(&strm, 100), LZMA_MEMLIMIT_ERROR);
assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT), LZMA_OK);
@@ -474,7 +462,7 @@ main(int argc, char **argv)
tuktest_run(test_v1_decode);
tuktest_run(test_v0_trailing);
tuktest_run(test_v1_trailing);
- tuktest_run(test_concatentated);
+ tuktest_run(test_concatenated);
tuktest_run(test_crc);
tuktest_run(test_invalid_magic_bytes);
tuktest_run(test_invalid_version);
@@ -484,5 +472,4 @@ main(int argc, char **argv)
tuktest_run(test_invalid_memlimit);
return tuktest_end();
#endif
-
}
diff --git a/tests/test_memlimit.c b/tests/test_memlimit.c
index c45a44b..7e8f862 100644
--- a/tests/test_memlimit.c
+++ b/tests/test_memlimit.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_memlimit.c
@@ -5,9 +7,6 @@
//
// Author: Lasse Collin
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
diff --git a/tests/test_microlzma.c b/tests/test_microlzma.c
new file mode 100644
index 0000000..c1d99d7
--- /dev/null
+++ b/tests/test_microlzma.c
@@ -0,0 +1,568 @@
+// SPDX-License-Identifier: 0BSD
+
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file test_microlzma.c
+/// \brief Tests MicroLZMA encoding and decoding
+//
+// Author: Jia Tan
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "tests.h"
+
+#define BUFFER_SIZE 1024
+
+
+#ifdef HAVE_ENCODER_LZMA1
+
+// MicroLZMA encoded "Hello\nWorld\n" output size in bytes.
+#define ENCODED_OUTPUT_SIZE 17
+
+// Byte array of "Hello\nWorld\n". This is used for various encoder tests.
+static const uint8_t hello_world[] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A,
+ 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x0A };
+
+// This is the CRC32 value of the MicroLZMA encoding of "Hello\nWorld\n".
+// The settings used were based on LZMA_PRESET_DEFAULT as of liblzma 5.6.0.
+// This assumes MicroLZMA is correct in liblzma 5.6.0, which is safe
+// considering the encoded "Hello\nWorld\n" can successfully be decoded at
+// this time. This is to test for regressions that cause MicroLZMA output
+// to change.
+static const uint32_t hello_world_encoded_crc = 0x3CDE40A8;
+
+
+// Function implementation borrowed from lzma_decoder.c. It is needed to
+// ensure the first byte of a MicroLZMA stream is set correctly with the
+// negation of the LZMA properties.
+static bool
+lzma_lzma_lclppb_decode(lzma_options_lzma *options, uint8_t byte)
+{
+ if (byte > (4 * 5 + 4) * 9 + 8)
+ return true;
+
+ // See the file format specification to understand this.
+ options->pb = byte / (9 * 5);
+ byte -= options->pb * 9 * 5;
+ options->lp = byte / 9;
+ options->lc = byte - options->lp * 9;
+
+ return options->lc + options->lp > LZMA_LCLP_MAX;
+}
+
+
+///////////////////
+// Encoder tests //
+///////////////////
+
+// This tests a few of the basic options. These options are not unique to
+// MicroLZMA in any way, its mostly ensuring that the options are actually
+// being checked before initializing the decoder internals.
+static void
+test_encode_options(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_options_lzma opt_lzma;
+
+ // Initialize with default options.
+ assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT));
+
+ // NULL stream
+ assert_lzma_ret(lzma_microlzma_encoder(NULL, &opt_lzma),
+ LZMA_PROG_ERROR);
+
+ // lc/lp/pb = 5/0/2 (lc invalid)
+ opt_lzma.lc = 5;
+ opt_lzma.lp = 0;
+ opt_lzma.pb = 2;
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma),
+ LZMA_OPTIONS_ERROR);
+
+ // lc/lp/pb = 0/5/2 (lp invalid)
+ opt_lzma.lc = 0;
+ opt_lzma.lp = 5;
+ opt_lzma.pb = 2;
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma),
+ LZMA_OPTIONS_ERROR);
+
+ // lc/lp/pb = 3/2/2 (lc + lp invalid)
+ opt_lzma.lc = 3;
+ opt_lzma.lp = 2;
+ opt_lzma.pb = 2;
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma),
+ LZMA_OPTIONS_ERROR);
+
+ // lc/lp/pb = 3/0/5 (pb invalid)
+ opt_lzma.lc = 3;
+ opt_lzma.lp = 0;
+ opt_lzma.pb = 5;
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma),
+ LZMA_OPTIONS_ERROR);
+
+ // Zero out lp, pb, lc options to not interfere with later tests.
+ opt_lzma.lp = 0;
+ opt_lzma.pb = 0;
+ opt_lzma.lc = 0;
+
+ // Set invalid dictionary size.
+ opt_lzma.dict_size = LZMA_DICT_SIZE_MIN - 1;
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma),
+ LZMA_OPTIONS_ERROR);
+
+ // Maximum dictionary size for the encoder, as described in lzma12.h
+ // is 1.5 GiB.
+ opt_lzma.dict_size = (UINT32_C(1) << 30) + (UINT32_C(1) << 29) + 1;
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma),
+ LZMA_OPTIONS_ERROR);
+
+ lzma_end(&strm);
+}
+
+
+static void
+test_encode_basic(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_options_lzma opt_lzma;
+
+ // The lzma_lzma_preset return value is inverse of what it perhaps
+ // should be, that is, it returns false on success.
+ assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT));
+
+ // Initialize the encoder using the default options.
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), LZMA_OK);
+
+ uint8_t output[BUFFER_SIZE];
+
+ strm.next_in = hello_world;
+ strm.avail_in = sizeof(hello_world);
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ // Everything must be encoded in one lzma_code() call.
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
+
+ // Check that the entire input was consumed.
+ assert_uint_eq(strm.total_in, sizeof(hello_world));
+
+ // Check that the first byte in the output stream is not 0x00.
+ // In a regular raw LZMA stream the first byte is always 0x00.
+ // In MicroLZMA the first byte replaced by the bitwise-negation
+ // of the LZMA properties.
+ assert_uint(output[0], !=, 0x00);
+
+ const uint8_t props = ~output[0];
+
+ lzma_options_lzma test_options;
+ assert_false(lzma_lzma_lclppb_decode(&test_options, props));
+
+ assert_uint_eq(opt_lzma.lc, test_options.lc);
+ assert_uint_eq(opt_lzma.lp, test_options.lp);
+ assert_uint_eq(opt_lzma.pb, test_options.pb);
+
+ // Compute the check over the output data. This is compared to
+ // the expected check value.
+ const uint32_t check_val = lzma_crc32(output, strm.total_out, 0);
+
+ assert_uint_eq(check_val, hello_world_encoded_crc);
+
+ lzma_end(&strm);
+}
+
+
+// This tests the behavior when strm.avail_out is so small it cannot hold
+// the header plus 1 encoded byte (< 6).
+static void
+test_encode_small_out(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_options_lzma opt_lzma;
+
+ assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT));
+
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), LZMA_OK);
+
+ uint8_t output[BUFFER_SIZE];
+
+ strm.next_in = hello_world;
+ strm.avail_in = sizeof(hello_world);
+ strm.next_out = output;
+ strm.avail_out = 5;
+
+ // LZMA_PROG_ERROR is expected when strm.avail_out < 6
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_PROG_ERROR);
+
+ // The encoder must be reset because coders cannot be used again
+ // after returning LZMA_PROG_ERROR.
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), LZMA_OK);
+
+ // Reset strm.avail_out to be > 6, but not enough to hold all of the
+ // compressed data.
+ strm.avail_out = ENCODED_OUTPUT_SIZE - 1;
+
+ // Encoding should not return an error now.
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
+ assert_uint(strm.total_in, <, sizeof(hello_world));
+
+ lzma_end(&strm);
+}
+
+
+// LZMA_FINISH is the only supported action. All others must
+// return LZMA_PROG_ERROR.
+static void
+test_encode_actions(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_options_lzma opt_lzma;
+
+ assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT));
+
+ const lzma_action actions[] = {
+ LZMA_RUN,
+ LZMA_SYNC_FLUSH,
+ LZMA_FULL_FLUSH,
+ LZMA_FULL_BARRIER,
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(actions); ++i) {
+ assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma),
+ LZMA_OK);
+
+ uint8_t output[BUFFER_SIZE];
+
+ strm.next_in = hello_world;
+ strm.avail_in = sizeof(hello_world);
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ assert_lzma_ret(lzma_code(&strm, actions[i]),
+ LZMA_PROG_ERROR);
+ }
+
+ lzma_end(&strm);
+}
+#endif // HAVE_ENCODER_LZMA1
+
+
+///////////////////
+// Decoder tests //
+///////////////////
+
+#if defined(HAVE_DECODER_LZMA1) && defined(HAVE_ENCODER_LZMA1)
+
+// Byte array of "Goodbye World!". This is used for various decoder tests.
+static const uint8_t goodbye_world[] = { 0x47, 0x6F, 0x6F, 0x64, 0x62,
+ 0x79, 0x65, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21 };
+
+static uint8_t *goodbye_world_encoded = NULL;
+static size_t goodbye_world_encoded_size = 0;
+
+
+// Helper function to encode data and return the compressed size.
+static size_t
+basic_microlzma_encode(const uint8_t *input, size_t in_size,
+ uint8_t **compressed)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_options_lzma opt_lzma;
+
+ // Lazy way to set the output size since the input should never
+ // inflate by much in these simple test cases. This is tested to
+ // be large enough after encoding to fit the entire input, so if
+ // this assumption does not hold then this will fail.
+ const size_t out_size = in_size << 1;
+
+ *compressed = tuktest_malloc(out_size);
+
+ // Always encode with the default options for simplicity.
+ if (lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT))
+ goto decoder_setup_error;
+
+ if (lzma_microlzma_encoder(&strm, &opt_lzma) != LZMA_OK)
+ goto decoder_setup_error;
+
+ strm.next_in = input;
+ strm.avail_in = in_size;
+ strm.next_out = *compressed;
+ strm.avail_out = out_size;
+
+ if (lzma_code(&strm, LZMA_FINISH) != LZMA_STREAM_END)
+ goto decoder_setup_error;
+
+ // Check that the entire input was consumed and that it fit into
+ // the output buffer.
+ if (strm.total_in != in_size)
+ goto decoder_setup_error;
+
+ lzma_end(&strm);
+
+ // lzma_end() doesn't touch other members of lzma_stream than
+ // lzma_stream.internal so using strm.total_out here is fine.
+ return strm.total_out;
+
+decoder_setup_error:
+ tuktest_error("Failed to initialize decoder tests");
+ return 0;
+}
+
+
+static void
+test_decode_options(void)
+{
+ // NULL stream
+ assert_lzma_ret(lzma_microlzma_decoder(NULL, BUFFER_SIZE,
+ sizeof(hello_world), true,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_PROG_ERROR);
+
+ // Uncompressed size larger than max
+ lzma_stream strm = LZMA_STREAM_INIT;
+ assert_lzma_ret(lzma_microlzma_decoder(&strm, BUFFER_SIZE,
+ LZMA_VLI_MAX + 1, true, LZMA_DICT_SIZE_DEFAULT),
+ LZMA_OPTIONS_ERROR);
+}
+
+
+// Test that decoding succeeds when uncomp_size is correct regardless of
+// the value of uncomp_size_is_exact.
+static void
+test_decode_uncomp_size_is_exact(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size,
+ sizeof(goodbye_world), true,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ uint8_t output[BUFFER_SIZE];
+
+ strm.next_in = goodbye_world_encoded;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
+ assert_uint_eq(strm.total_in, goodbye_world_encoded_size);
+
+ assert_uint_eq(strm.total_out, sizeof(goodbye_world));
+ assert_array_eq(goodbye_world, output, sizeof(goodbye_world));
+
+ // Reset decoder with uncomp_size_is_exact set to false and
+ // uncomp_size set to correct value. Also test using the
+ // uncompressed size as the dictionary size.
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size,
+ sizeof(goodbye_world), false,
+ sizeof(goodbye_world)), LZMA_OK);
+
+ strm.next_in = goodbye_world_encoded;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END);
+ assert_uint_eq(strm.total_in, goodbye_world_encoded_size);
+
+ assert_uint_eq(strm.total_out, sizeof(goodbye_world));
+ assert_array_eq(goodbye_world, output, sizeof(goodbye_world));
+
+ lzma_end(&strm);
+}
+
+
+// This tests decoding when MicroLZMA decoder is called with
+// an incorrect uncompressed size.
+static void
+test_decode_uncomp_size_wrong(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size,
+ sizeof(goodbye_world) + 1, false,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ uint8_t output[BUFFER_SIZE];
+
+ strm.next_in = goodbye_world_encoded;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ // LZMA_OK should be returned because the input size given was
+ // larger than the actual encoded size. The decoder is expecting
+ // more input to possibly fill the uncompressed size that was set.
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_OK);
+
+ assert_uint_eq(strm.total_out, sizeof(goodbye_world));
+
+ assert_array_eq(goodbye_world, output, sizeof(goodbye_world));
+
+ // Next, test with uncomp_size_is_exact set.
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size,
+ sizeof(goodbye_world) + 1, true,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ strm.next_in = goodbye_world_encoded;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ // No error detected, even though all input was consumed and there
+ // is more room in the output buffer.
+ //
+ // FIXME? LZMA_FINISH tells that no more input is coming and
+ // the MicroLZMA decoder knows the exact compressed size from
+ // the initialization as well. So should it return LZMA_DATA_ERROR
+ // on the first call instead of relying on the generic lzma_code()
+ // logic to eventually get LZMA_BUF_ERROR?
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_OK);
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_OK);
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_BUF_ERROR);
+
+ assert_uint_eq(strm.total_out, sizeof(goodbye_world));
+ assert_array_eq(goodbye_world, output, sizeof(goodbye_world));
+
+ // Reset stream with uncomp_size smaller than the real
+ // uncompressed size.
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size,
+ ARRAY_SIZE(hello_world) - 1, true,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ strm.next_in = goodbye_world_encoded;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ // This case actually results in an error since it decodes the full
+ // uncompressed size but the range coder is not in the proper state
+ // for the stream to end.
+ assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_DATA_ERROR);
+
+ lzma_end(&strm);
+}
+
+
+static void
+test_decode_comp_size_wrong(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+
+ // goodbye_world_encoded_size + 1 is safe because extra space was
+ // allocated for goodbye_world_encoded. The extra space isn't
+ // initialized but it shouldn't be read either, thus Valgrind
+ // has to remain happy with this code.
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size + 1,
+ sizeof(goodbye_world), true,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ uint8_t output[BUFFER_SIZE];
+
+ strm.next_in = goodbye_world_encoded;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ // When uncomp_size_is_exact is set, the compressed size must be
+ // correct or else LZMA_DATA_ERROR is returned.
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_DATA_ERROR);
+
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size + 1,
+ sizeof(goodbye_world), false,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ strm.next_in = goodbye_world_encoded;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ // When uncomp_size_is_exact is not set, the decoder does not
+ // detect when the compressed size is wrong as long as all of the
+ // expected output has been decoded. This is because the decoder
+ // assumes that the real uncompressed size might be bigger than
+ // the specified value and in that case more input might be needed
+ // as well.
+ assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
+
+ lzma_end(&strm);
+}
+
+
+static void
+test_decode_bad_lzma_properties(void)
+{
+ // Alter first byte to encode invalid LZMA properties.
+ uint8_t *compressed = tuktest_malloc(goodbye_world_encoded_size);
+ memcpy(compressed, goodbye_world_encoded, goodbye_world_encoded_size);
+
+ // lc=3, lp=2, pb=2
+ compressed[0] = (uint8_t)~0x6FU;
+
+ lzma_stream strm = LZMA_STREAM_INIT;
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size,
+ sizeof(goodbye_world), false,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ uint8_t output[BUFFER_SIZE];
+
+ strm.next_in = compressed;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_OPTIONS_ERROR);
+
+ // Use valid, but incorrect LZMA properties.
+ // lc=3, lp=1, pb=2
+ compressed[0] = (uint8_t)~0x66;
+
+ assert_lzma_ret(lzma_microlzma_decoder(&strm,
+ goodbye_world_encoded_size,
+ ARRAY_SIZE(goodbye_world), true,
+ LZMA_DICT_SIZE_DEFAULT), LZMA_OK);
+
+ strm.next_in = compressed;
+ strm.avail_in = goodbye_world_encoded_size;
+ strm.next_out = output;
+ strm.avail_out = sizeof(output);
+
+ assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_DATA_ERROR);
+
+ lzma_end(&strm);
+}
+#endif
+
+
+extern int
+main(int argc, char **argv)
+{
+ tuktest_start(argc, argv);
+
+#ifndef HAVE_ENCODER_LZMA1
+ tuktest_early_skip("LZMA1 encoder disabled");
+#else
+ tuktest_run(test_encode_options);
+ tuktest_run(test_encode_basic);
+ tuktest_run(test_encode_small_out);
+ tuktest_run(test_encode_actions);
+
+ // MicroLZMA decoder tests require the basic encoder functionality.
+# ifdef HAVE_DECODER_LZMA1
+ goodbye_world_encoded_size = basic_microlzma_encode(goodbye_world,
+ sizeof(goodbye_world), &goodbye_world_encoded);
+
+ tuktest_run(test_decode_options);
+ tuktest_run(test_decode_uncomp_size_is_exact);
+ tuktest_run(test_decode_uncomp_size_wrong);
+ tuktest_run(test_decode_comp_size_wrong);
+ tuktest_run(test_decode_bad_lzma_properties);
+# endif
+
+ return tuktest_end();
+#endif
+}
diff --git a/tests/test_scripts.sh b/tests/test_scripts.sh
index ee82361..ca9600e 100755
--- a/tests/test_scripts.sh
+++ b/tests/test_scripts.sh
@@ -1,18 +1,18 @@
#!/bin/sh
+# SPDX-License-Identifier: 0BSD
###############################################################################
#
# Author: Jonathan Nieder
#
-# This file has been put into the public domain.
-# You can do whatever you want with this file.
-#
###############################################################################
# If scripts weren't built, this test is skipped.
-XZ=../src/xz/xz
-XZDIFF=../src/scripts/xzdiff
-XZGREP=../src/scripts/xzgrep
+# When this is run from CMake, $1 is a relative path
+# to the directory with the executables and the scripts.
+XZ=${1:-../src/xz}/xz
+XZDIFF=${1:-../src/scripts}/xzdiff
+XZGREP=${1:-../src/scripts}/xzgrep
for i in XZ XZDIFF XZGREP; do
eval test -x "\$$i" && continue
@@ -23,14 +23,15 @@ done
# Installing the scripts in this case is a bit silly but they
# could still be used with other decompression tools so configure
# doesn't automatically disable scripts if decoders are disabled.
-if grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then
+if test ! -f ../config.h \
+ || grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then
:
else
echo "Decompression support is disabled, skipping this test."
exit 77
fi
-PATH=`pwd`/../src/xz:$PATH
+PATH=`pwd`/${1:-../src/xz}:$PATH
export PATH
test -z "$srcdir" && srcdir=.
diff --git a/tests/test_stream_flags.c b/tests/test_stream_flags.c
index 2248e67..3bc48be 100644
--- a/tests/test_stream_flags.c
+++ b/tests/test_stream_flags.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_stream_flags.c
@@ -6,9 +8,6 @@
// Authors: Jia Tan
// Lasse Collin
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
diff --git a/tests/test_suffix.sh b/tests/test_suffix.sh
new file mode 100755
index 0000000..7fc5996
--- /dev/null
+++ b/tests/test_suffix.sh
@@ -0,0 +1,192 @@
+#!/bin/sh
+# SPDX-License-Identifier: 0BSD
+
+###############################################################################
+#
+# Author: Jia Tan
+#
+###############################################################################
+
+# Optional argument:
+# $1 = directory of the xz executable
+
+# If xz was not built, skip this test. Autotools and CMake put
+# the xz executable in a different location.
+XZ=${1:-../src/xz}/xz
+if test ! -x "$XZ"; then
+ echo "xz was not built, skipping this test."
+ exit 77
+fi
+
+# If compression or decompression support is missing, this test is skipped.
+# This isn't perfect because it does not specifically check for LZMA1/2
+# filters. Many of the other tests also assume LZMA1/2 support if encoders
+# or decoders are enabled.
+if test ! -f ../config.h ; then
+ :
+elif grep 'define HAVE_ENCODERS' ../config.h > /dev/null \
+ && grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then
+ :
+else
+ echo "Compression or decompression support is disabled, skipping this test."
+ exit 77
+fi
+
+# Create temporary input file. The file contents are not important.
+SUFFIX_INPUT="suffix_temp"
+SUFFIX_INPUT_FILES="$SUFFIX_INPUT"_files
+SUFFIX_INPUT_FILES0="$SUFFIX_INPUT"_files0
+
+# Remove possible leftover temporary files
+rm -f \
+ "$SUFFIX_INPUT" \
+ "$SUFFIX_INPUT.foo" \
+ "$SUFFIX_INPUT_FILES" \
+ "$SUFFIX_INPUT_FILES"
+
+echo "foobar" > "$SUFFIX_INPUT"
+
+# Test basic suffix when compressing with raw format.
+if "$XZ" -zfk --suffix=".foo" -Fraw --lzma1=preset=0 "$SUFFIX_INPUT" ; then
+ :
+else
+ echo "Failed to compress a file with a suffix set in raw format"
+ exit 1
+fi
+
+# Test the output file is named properly.
+if test -f "$SUFFIX_INPUT.foo" ; then
+ :
+else
+ echo "Raw format compressed output file not named properly"
+ exit 1
+fi
+
+# Expect an error when compressing with raw format without a suffix
+if "$XZ" -zfk -Fraw --lzma1=preset=0 "$SUFFIX_INPUT" 2> /dev/null; then
+ echo "Error not reported when compressing in raw format without a suffix"
+ exit 1
+fi
+
+# Expect an error when decompressing with raw format without a suffix
+if "$XZ" -df -Fraw --lzma1=preset=0 "$SUFFIX_INPUT.foo" 2> /dev/null; then
+ echo "Error not reported when decompressing in raw format without a suffix"
+ exit 1
+fi
+
+# Test basic decompression with raw format and a suffix. This will also
+# delete $SUFFIX_INPUT.foo
+if "$XZ" -df --suffix=".foo" -Fraw --lzma1=preset=0 "$SUFFIX_INPUT.foo"; then
+ :
+else
+ echo "Failed to decompress a file with a suffix set in raw format"
+ exit 1
+fi
+
+# Test basic compression with .xz format and a suffix
+if "$XZ" -zfk --suffix=".foo" --lzma2=preset=0 "$SUFFIX_INPUT" ; then
+ :
+else
+ echo "Failed to compress a file with a suffix set in .xz format"
+ exit 1
+fi
+
+# Test the output file is named properly.
+if test -f "$SUFFIX_INPUT.foo" ; then
+ :
+else
+ echo ".xz format compressed output file named properly"
+ exit 1
+fi
+
+# This will delete $SUFFIX_INPUT.foo
+if "$XZ" -df --suffix=".foo" "$SUFFIX_INPUT.foo"; then
+ :
+else
+ echo "Failed to decompress a file with a suffix set in .xz format"
+ exit 1
+fi
+
+# Test reading from stdin in raw mode. This was broken in
+# cc5aa9ab138beeecaee5a1e81197591893ee9ca0 and fixed in
+# 837ea40b1c9d4998cac4500b55171bf33e0c31a6
+if echo foo | "$XZ" -Fraw --lzma1=preset=0 > /dev/null ; then
+ :
+else
+ echo "Implicit write to stdout not detected"
+ exit 1
+fi
+
+# Create two temporary files to be used with --files and --files0.
+printf "$SUFFIX_INPUT\n" > "$SUFFIX_INPUT_FILES"
+printf "$SUFFIX_INPUT\0" > "$SUFFIX_INPUT_FILES0"
+
+# Test proper handling of --files/--files0 when no suffix is set. This
+# must result in an error because xz does not know how to rename the output
+# file from the input files. This caused a segmentation fault due to a
+# mistake in f481523baac946fa3bc13d79186ffaf0c0b818a7, which was fixed by
+# 0a601ddc89fd7e1370807c6b58964f361dfcd34a.
+if "$XZ" -Fraw --lzma1=preset=0 --files="$SUFFIX_INPUT_FILES" 2> /dev/null ; then
+ echo "Failed to report error when compressing a file specified by --files in raw mode without a suffix"
+ exit 1
+fi
+
+if "$XZ" -Fraw --lzma1=preset=0 --files0="$SUFFIX_INPUT_FILES0" 2> /dev/null ; then
+ echo "Failed to report error when compressing a file specified by --files0 in raw mode without a suffix"
+ exit 1
+fi
+
+# Test proper suffix usage in raw mode with --files and --files0.
+if "$XZ" -zfk -Fraw --lzma1=preset=0 --suffix=.foo --files="$SUFFIX_INPUT_FILES" ; then
+ :
+else
+ echo "Error compressing a file specified by --files in raw mode with a suffix set"
+ exit 1
+fi
+
+if test -f "$SUFFIX_INPUT.foo" ; then
+ :
+else
+ echo "Entry processed by --files not named properly"
+ exit 1
+fi
+
+# Remove the artifact so we can be sure the next test executes properly.
+rm "$SUFFIX_INPUT.foo"
+
+if "$XZ" -zfk -Fraw --lzma1=preset=0 --suffix=.foo --files0="$SUFFIX_INPUT_FILES0" ; then
+ :
+else
+ echo "Error compressing a file specified by --files0 in raw mode with a suffix set"
+ exit 1
+fi
+
+if test -f "$SUFFIX_INPUT.foo" ; then
+ :
+else
+ echo "Entry processed by --files0 not named properly"
+ exit 1
+fi
+
+# When the file type cannot be determined by xz, it will copy the contents
+# of the file only if -c,--stdout is used. This was broken by
+# 837ea40b1c9d4998cac4500b55171bf33e0c31a6 and fixed by
+# f481523baac946fa3bc13d79186ffaf0c0b818a7.
+if echo foo | "$XZ" -df > /dev/null 2>&1; then
+ echo "Failed to report error when decompressing unknown file type without -c,--stdout"
+ exit 1
+fi
+
+if echo foo | "$XZ" -dfc > /dev/null; then
+ :
+else
+ echo "Failed to copy input to standard out when decompressing unknown file type with -c,--stdout"
+ exit 1
+fi
+
+# Remove remaining test artifacts
+rm -f \
+ "$SUFFIX_INPUT" \
+ "$SUFFIX_INPUT.foo" \
+ "$SUFFIX_INPUT_FILES" \
+ "$SUFFIX_INPUT_FILES0"
diff --git a/tests/test_vli.c b/tests/test_vli.c
index 996b775..51487dc 100644
--- a/tests/test_vli.c
+++ b/tests/test_vli.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file test_vli.c
@@ -5,9 +7,6 @@
//
// Author: Jia Tan
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#include "tests.h"
diff --git a/tests/tests.cmake b/tests/tests.cmake
new file mode 100644
index 0000000..62c546c
--- /dev/null
+++ b/tests/tests.cmake
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: 0BSD
+
+#############################################################################
+#
+# Optional file to be included by the top-level CMakeLists.txt to run tests
+#
+# The CMake rules for the tests are in this separate optional file so
+# that it's trivial to just delete the whole "tests" directory and still
+# get an otherwise normal CMake-based build. This way it's easy to ensure
+# that nothing in the "tests" directory can affect the build process.
+#
+# Author: Lasse Collin
+#
+#############################################################################
+
+include(CTest)
+
+if(BUILD_TESTING)
+ #################
+ # liblzma tests #
+ #################
+
+ set(LIBLZMA_TESTS
+ test_bcj_exact_size
+ test_block_header
+ test_check
+ test_filter_flags
+ test_filter_str
+ test_hardware
+ test_index
+ test_index_hash
+ test_lzip_decoder
+ test_memlimit
+ test_stream_flags
+ test_vli
+ )
+
+ # MicroLZMA encoder is needed for both encoder and decoder tests.
+ # If MicroLZMA decoder is not configured but LZMA1 decoder is, then
+ # test_microlzma will fail to compile because this configuration is
+ # not possible in the Autotools build, so the test was not made to
+ # support it since it would have required additional changes.
+ if (MICROLZMA_ENCODER AND (MICROLZMA_DECODER
+ OR NOT "lzma1" IN_LIST DECODERS))
+ list(APPEND LIBLZMA_TESTS test_microlzma)
+ endif()
+
+ foreach(TEST IN LISTS LIBLZMA_TESTS)
+ add_executable("${TEST}" "tests/${TEST}.c")
+
+ target_include_directories("${TEST}" PRIVATE
+ src/common
+ src/liblzma/api
+ src/liblzma
+ )
+
+ target_link_libraries("${TEST}" PRIVATE liblzma)
+
+ # Put the test programs into their own subdirectory so they don't
+ # pollute the top-level dir which might contain xz and xzdec.
+ set_target_properties("${TEST}" PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tests_bin"
+ )
+
+ add_test(NAME "${TEST}"
+ COMMAND "${CMAKE_CURRENT_BINARY_DIR}/tests_bin/${TEST}"
+ )
+
+ # Set srcdir environment variable so that the tests find their
+ # input files from the source tree.
+ #
+ # Set the return code for skipped tests to match Automake convention.
+ set_tests_properties("${TEST}" PROPERTIES
+ ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests"
+ SKIP_RETURN_CODE 77
+ )
+ endforeach()
+
+
+ ###########################
+ # Command line tool tests #
+ ###########################
+
+ # Since the CMake-based build doesn't use config.h, the test scripts
+ # cannot grep the contents of config.h to know which features have
+ # been disabled. When config.h is missing, they assume that all
+ # features are enabled. Thus, check if certain groups of features have
+ # been disabled and then possibly skip some of the tests entirely instead
+ # of letting them fail.
+ set(SUPPORTED_FILTERS_SORTED "${SUPPORTED_FILTERS}")
+ list(SORT SUPPORTED_FILTERS_SORTED)
+
+ set(ENCODERS_SORTED "${ENCODERS}")
+ list(SORT ENCODERS_SORTED)
+
+ if("${ENCODERS_SORTED}" STREQUAL "${SUPPORTED_FILTERS_SORTED}")
+ set(HAVE_ALL_ENCODERS ON)
+ else()
+ set(HAVE_ALL_ENCODERS OFF)
+ endif()
+
+ set(DECODERS_SORTED "${DECODERS}")
+ list(SORT DECODERS_SORTED)
+
+ if("${DECODERS_SORTED}" STREQUAL "${SUPPORTED_FILTERS_SORTED}")
+ set(HAVE_ALL_DECODERS ON)
+ else()
+ set(HAVE_ALL_DECODERS OFF)
+ endif()
+
+ set(ADDITIONAL_SUPPORTED_CHECKS_SORTED "${ADDITIONAL_SUPPORTED_CHECKS}")
+ list(SORT ADDITIONAL_SUPPORTED_CHECKS_SORTED)
+
+ set(ADDITIONAL_CHECK_TYPES_SORTED "${ADDITIONAL_CHECK_TYPES}")
+ list(SORT ADDITIONAL_CHECK_TYPES_SORTED)
+
+ if("${ADDITIONAL_SUPPORTED_CHECKS_SORTED}" STREQUAL
+ "${ADDITIONAL_CHECK_TYPES_SORTED}")
+ set(HAVE_ALL_CHECK_TYPES ON)
+ else()
+ set(HAVE_ALL_CHECK_TYPES OFF)
+ endif()
+
+ # test_scripts.sh only needs LZMA2 decoder and CRC32.
+ if(UNIX AND HAVE_DECODERS)
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_scripts")
+
+ add_test(NAME test_scripts.sh
+ COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_scripts.sh" ".."
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_scripts"
+ )
+
+ set_tests_properties(test_scripts.sh PROPERTIES
+ ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests"
+ SKIP_RETURN_CODE 77
+ )
+ endif()
+
+ # test_suffix.sh only needs LZMA2 encoder and decoder.
+ if(UNIX AND HAVE_ENCODERS AND HAVE_DECODERS)
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_suffix")
+
+ add_test(NAME test_suffix.sh
+ COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_suffix.sh" ".."
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_suffix"
+ )
+
+ set_tests_properties(test_suffix.sh PROPERTIES
+ SKIP_RETURN_CODE 77
+ )
+ endif()
+
+ # The test_compress.sh based tests compress and decompress using different
+ # filters so run it only if all encoders and decoders have been enabled.
+ if(UNIX AND HAVE_ALL_ENCODERS AND HAVE_ALL_DECODERS)
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_compress")
+
+ add_executable(create_compress_files tests/create_compress_files.c)
+ target_include_directories(create_compress_files PRIVATE src/common)
+ set_target_properties(create_compress_files PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY test_compress)
+
+ foreach(T compress_generated_abc
+ compress_generated_text
+ compress_generated_random)
+ add_test(NAME "test_${T}"
+ COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_compress.sh"
+ "${T}" ".."
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_compress"
+ )
+
+ set_tests_properties("test_${T}" PROPERTIES
+ ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests"
+ SKIP_RETURN_CODE 77
+ )
+ endforeach()
+ endif()
+
+ # test_files.sh decompresses files that use different filters and
+ # check types so run it only if support for all of them has been enabled.
+ if(UNIX AND HAVE_ALL_DECODERS AND HAVE_ALL_CHECK_TYPES AND LZIP_DECODER)
+ # test_files.sh doesn't make any temporary files but it
+ # must not be run at the top-level build directory because
+ # it checks if ../config.h exists. We don't want to read
+ # files outside the build directory!
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_files")
+
+ add_test(NAME test_files.sh
+ COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_files.sh" ".."
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_files"
+ )
+
+ set_tests_properties(test_files.sh PROPERTIES
+ ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests"
+ SKIP_RETURN_CODE 77
+ )
+ endif()
+endif()
diff --git a/tests/tests.h b/tests/tests.h
index 2d42700..f706cab 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file tests.h
@@ -5,9 +7,6 @@
//
// Author: Lasse Collin
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_TESTS_H
diff --git a/tests/tuktest.h b/tests/tuktest.h
index 508eace..12abd53 100644
--- a/tests/tuktest.h
+++ b/tests/tuktest.h
@@ -1,10 +1,13 @@
+// SPDX-License-Identifier: 0BSD
+
///////////////////////////////////////////////////////////////////////////////
//
/// \file tuktest.h
/// \brief Helper macros for writing simple test programs
-/// \version 2023-01-08
+/// \version 2024-02-14
///
-/// Some inspiration was taken from STest by Keith Nicholas.
+/// Some inspiration was taken from Seatest by Keith Nicholas and
+/// from STest which is a fork of Seatest by Jia Tan.
///
/// This is standard C99/C11 only and thus should be fairly portable
/// outside POSIX systems too.
@@ -110,8 +113,8 @@
/// Meson: https://mesonbuild.com/Unit-tests.html
///
/// CMake handles passing and failing tests by default but treats hard
-/// errors as regular fails. To CMake support skipped tests correctly,
-/// one has to set the SKIP_RETURN_CODE property for each test:
+/// errors as regular fails. To make CMake support skipped tests
+/// correctly, one has to set the SKIP_RETURN_CODE property for each test:
///
/// set_tests_properties(foo_test_name PROPERTIES SKIP_RETURN_CODE 77)
///
@@ -121,9 +124,6 @@
//
// Author: Lasse Collin
//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
///////////////////////////////////////////////////////////////////////////////
#ifndef TUKTEST_H
@@ -155,14 +155,14 @@
// This is silencing warnings about unused functions. Not all test programs
// need all functions from this header.
-#if TUKTEST_GNUC_REQ(3, 0)
+#if TUKTEST_GNUC_REQ(3, 0) || defined(__clang__)
# define tuktest_maybe_unused __attribute__((__unused__))
#else
# define tuktest_maybe_unused
#endif
// We need printf("") so silence the warning about empty format string.
-#if TUKTEST_GNUC_REQ(4, 2)
+#if TUKTEST_GNUC_REQ(4, 2) || defined(__clang__)
# pragma GCC diagnostic ignored "-Wformat-zero-length"
#endif