mirror of
https://git.tukaani.org/xz.git
synced 2025-12-27 07:48:44 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18b845e697 | ||
|
|
4080bbb844 | ||
|
|
674c89fdb8 | ||
|
|
2a6b938084 | ||
|
|
aea639e81b | ||
|
|
e3b42bfcb0 | ||
|
|
21625b7e11 | ||
|
|
c337983e92 | ||
|
|
b7fb438ea0 | ||
|
|
68e9ef036d | ||
|
|
a387707cd8 | ||
|
|
52902ad695 | ||
|
|
e81b9fc48c | ||
|
|
6e89ab58b0 | ||
|
|
65c59ad429 | ||
|
|
43521e77ac | ||
|
|
6b44cead95 | ||
|
|
1bbefa9659 | ||
|
|
ce3a3fbc7c | ||
|
|
99fcd57f2e | ||
|
|
c0c13d9d82 | ||
|
|
3d45987451 | ||
|
|
706bce5018 | ||
|
|
e96dee55df | ||
|
|
52bc1ee34d | ||
|
|
bad44cfe19 | ||
|
|
692ccdf551 | ||
|
|
2ac7bafc8f | ||
|
|
db714d30e0 | ||
|
|
39d2585dcd | ||
|
|
3f0130aa28 | ||
|
|
f204d1050a | ||
|
|
34a9c2d650 | ||
|
|
761c208d58 | ||
|
|
8a7cbc0745 | ||
|
|
ca2af49bb8 | ||
|
|
bfba3394ae | ||
|
|
507648ad11 | ||
|
|
ab5229d32a | ||
|
|
8791826f31 | ||
|
|
c410d812ea | ||
|
|
501c6013d4 | ||
|
|
9e3cb514b5 | ||
|
|
6fc3e54679 | ||
|
|
e84f2ab7f8 | ||
|
|
b14b8dbba9 | ||
|
|
09a114805e | ||
|
|
d3e6fe4419 | ||
|
|
b55a27b46f | ||
|
|
2fd28d2b7c |
27
.gitignore
vendored
27
.gitignore
vendored
@ -5,6 +5,7 @@
|
||||
|
||||
.deps
|
||||
.libs
|
||||
*.a
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.la
|
||||
@ -36,6 +37,8 @@ build-aux/test-driver
|
||||
|
||||
coverage
|
||||
|
||||
/doc/html
|
||||
|
||||
/src/liblzma/liblzma.pc
|
||||
/src/lzmainfo/lzmainfo
|
||||
/src/xz/xz
|
||||
@ -59,6 +62,8 @@ coverage
|
||||
/tests/test_filter_flags
|
||||
/tests/test_hardware
|
||||
/tests/test_index
|
||||
/tests/test_index_hash
|
||||
/test/test_lzip_decoder
|
||||
/tests/test_memlimit
|
||||
/tests/test_stream_flags
|
||||
/tests/test_vli
|
||||
@ -77,3 +82,25 @@ coverage
|
||||
/src/liblzma/api/Makefile
|
||||
/src/lzmainfo/Makefile
|
||||
/src/xzdec/Makefile
|
||||
|
||||
/CMakeCache.txt
|
||||
/CMakeFiles
|
||||
/CTestTestfile.cmake
|
||||
/cmake_install.cmake
|
||||
/DartConfiguration.tcl
|
||||
/liblzma-config-version.cmake
|
||||
/liblzma-config.cmake
|
||||
/lzcat
|
||||
/lzcat.1
|
||||
/lzma
|
||||
/lzma.1
|
||||
/Testing
|
||||
/tests_bin/
|
||||
/unlzma
|
||||
/unlzma.1
|
||||
/unxz
|
||||
/unxz.1
|
||||
/xz
|
||||
/xzcat
|
||||
/xzcat.1
|
||||
/xzdec
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
cmake_minimum_required(VERSION 3.13...3.16 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.13...3.25 FATAL_ERROR)
|
||||
|
||||
include(CMakePushCheckState)
|
||||
include(CheckIncludeFile)
|
||||
@ -75,10 +75,40 @@ project(xz VERSION "${XZ_VERSION}" LANGUAGES C)
|
||||
# On Apple OSes, don't build executables as bundles:
|
||||
set(CMAKE_MACOSX_BUNDLE OFF)
|
||||
|
||||
# windres from GNU binutils can be tricky with command line arguments
|
||||
# that contain spaces or other funny characters. Unfortunately we need
|
||||
# a space in PACKAGE_NAME. Using \x20 to encode the US-ASCII space seems
|
||||
# to work in both cmd.exe and /bin/sh.
|
||||
#
|
||||
# However, even \x20 isn't enough in all situations, resulting in
|
||||
# "syntax error" from windres. Using --use-temp-file prevents windres
|
||||
# from using popen() and this seems to fix the problem.
|
||||
#
|
||||
# llvm-windres claims to be compatible with GNU windres but with that
|
||||
# the \x20 results in "XZx20Utils" in the compiled binary. (At the
|
||||
# same time it works correctly with clang (the C compiler).) The option
|
||||
# --use-temp-file makes no difference.
|
||||
#
|
||||
# CMake 3.25 doesn't have CMAKE_RC_COMPILER_ID so we rely on
|
||||
# CMAKE_C_COMPILER_ID. If Clang is used together with GNU windres
|
||||
# then it will fail, but this way the risk of a bad string in
|
||||
# the binary should be fairly low.
|
||||
if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
# Use workarounds with GNU windres. The \x20 in PACKAGE_NAME works
|
||||
# with gcc too so we don't need to worry how to pass different flags
|
||||
# to windres and gcc.
|
||||
string(APPEND CMAKE_RC_FLAGS " --use-temp-file")
|
||||
set(PACKAGE_NAME "XZ\\x20Utils")
|
||||
else()
|
||||
# Elsewhere a space is safe. This also keeps things compatible with
|
||||
# EBCDIC in case CMake-based build is ever done on such a system.
|
||||
set(PACKAGE_NAME "XZ Utils")
|
||||
endif()
|
||||
|
||||
# Definitions common to all targets:
|
||||
add_compile_definitions(
|
||||
# Package info:
|
||||
PACKAGE_NAME="XZ Utils"
|
||||
PACKAGE_NAME="${PACKAGE_NAME}"
|
||||
PACKAGE_BUGREPORT="xz@tukaani.org"
|
||||
PACKAGE_URL="https://tukaani.org/xz/"
|
||||
|
||||
@ -154,13 +184,11 @@ if(NOT WIN32 AND NOT DEFINED HAVE_CLOCK_GETTIME)
|
||||
endif()
|
||||
if(HAVE_CLOCK_GETTIME)
|
||||
# Check if CLOCK_MONOTONIC is available for clock_gettime().
|
||||
check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_DECL_CLOCK_MONOTONIC)
|
||||
check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
|
||||
|
||||
# HAVE_DECL_CLOCK_MONOTONIC should always be defined to 0 or 1
|
||||
# when clock_gettime is available.
|
||||
add_compile_definitions(
|
||||
HAVE_CLOCK_GETTIME
|
||||
HAVE_DECL_CLOCK_MONOTONIC=$<BOOL:"${HAVE_DECL_CLOCK_MONOTONIC}">
|
||||
HAVE_CLOCK_MONOTONIC
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@ -184,7 +212,7 @@ else()
|
||||
add_compile_definitions(MYTHREAD_POSIX)
|
||||
|
||||
# Check if pthread_condattr_setclock() exists to use CLOCK_MONOTONIC.
|
||||
if(HAVE_DECL_CLOCK_MONOTONIC)
|
||||
if(HAVE_CLOCK_MONOTONIC)
|
||||
list(INSERT CMAKE_REQUIRED_LIBRARIES 0 "${CMAKE_THREAD_LIBS_INIT}")
|
||||
check_symbol_exists(pthread_condattr_setclock pthread.h
|
||||
HAVE_PTHREAD_CONDATTR_SETCLOCK)
|
||||
@ -436,8 +464,9 @@ if(HAVE_IMMINTRIN_H)
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__EDG__)
|
||||
__attribute__((__target__(\"ssse3,sse4.1,pclmul\")))
|
||||
#endif
|
||||
__m128i my_clmul(__m128i a, __m128i b)
|
||||
__m128i my_clmul(__m128i a)
|
||||
{
|
||||
const __m128i b = _mm_set_epi64x(1, 2);
|
||||
return _mm_clmulepi64_si128(a, b, 0);
|
||||
}
|
||||
int main(void) { return 0; }
|
||||
@ -612,6 +641,14 @@ if(HAVE_GETOPT_LONG)
|
||||
|
||||
target_link_libraries(xzdec PRIVATE liblzma)
|
||||
|
||||
if(WIN32)
|
||||
# Add the Windows resource file for xzdec.exe.
|
||||
target_sources(xzdec PRIVATE src/xzdec/xzdec_w32res.rc)
|
||||
set_target_properties(xzdec PROPERTIES
|
||||
LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/common/common_w32res.rc"
|
||||
)
|
||||
endif()
|
||||
|
||||
tuklib_progname(xzdec)
|
||||
|
||||
install(TARGETS xzdec
|
||||
@ -683,6 +720,14 @@ if(NOT MSVC AND HAVE_GETOPT_LONG)
|
||||
|
||||
target_compile_definitions(xz PRIVATE ASSUME_RAM=128)
|
||||
|
||||
if(WIN32)
|
||||
# Add the Windows resource file for xz.exe.
|
||||
target_sources(xz PRIVATE src/xz/xz_w32res.rc)
|
||||
set_target_properties(xz PROPERTIES
|
||||
LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/common/common_w32res.rc"
|
||||
)
|
||||
endif()
|
||||
|
||||
tuklib_progname(xz)
|
||||
tuklib_mbstr(xz)
|
||||
|
||||
@ -803,6 +848,7 @@ if(BUILD_TESTING)
|
||||
test_filter_flags
|
||||
test_hardware
|
||||
test_index
|
||||
test_index_hash
|
||||
test_memlimit
|
||||
test_stream_flags
|
||||
test_vli
|
||||
@ -814,6 +860,7 @@ if(BUILD_TESTING)
|
||||
target_include_directories("${TEST}" PRIVATE
|
||||
src/common
|
||||
src/liblzma/api
|
||||
src/liblzma
|
||||
lib
|
||||
)
|
||||
|
||||
|
||||
70
NEWS
70
NEWS
@ -2,6 +2,76 @@
|
||||
XZ Utils Release Notes
|
||||
======================
|
||||
|
||||
5.4.1 (2023-01-11)
|
||||
|
||||
* liblzma:
|
||||
|
||||
- Fixed the return value of lzma_microlzma_encoder() if the
|
||||
LZMA options lc/lp/pb are invalid. Invalid lc/lp/pb options
|
||||
made the function return LZMA_STREAM_END without encoding
|
||||
anything instead of returning LZMA_OPTIONS_ERROR.
|
||||
|
||||
- Windows / Visual Studio: Workaround a possible compiler bug
|
||||
when targeting 32-bit x86 and compiling the CLMUL version of
|
||||
the CRC64 code. The CLMUL code isn't enabled by the Windows
|
||||
project files but it is in the CMake-based builds.
|
||||
|
||||
* Build systems:
|
||||
|
||||
- Windows-specific CMake changes:
|
||||
|
||||
* Don't try to enable CLMUL CRC64 code if _mm_set_epi64x()
|
||||
isn't available. This fixes CMake-based build with Visual
|
||||
Studio 2013.
|
||||
|
||||
* Created a workaround for a build failure with windres
|
||||
from GNU binutils. It is used only when the C compiler
|
||||
is GCC (not Clang). The workaround is incompatible
|
||||
with llvm-windres, resulting in "XZx20Utils" instead
|
||||
of "XZ Utils" in the resource file, but without the
|
||||
workaround llvm-windres works correctly. See the
|
||||
comment in CMakeLists.txt for details.
|
||||
|
||||
* Included the resource files in the xz and xzdec build
|
||||
rules. Building the command line tools is still
|
||||
experimental but possible with MinGW-w64.
|
||||
|
||||
- Visual Studio: Added stream_decoder_mt.c to the project
|
||||
files. Now the threaded decompressor lzma_stream_decoder_mt()
|
||||
gets built. CMake-based build wasn't affected.
|
||||
|
||||
- Updated windows/INSTALL-MSVC.txt to mention that CMake-based
|
||||
build is now the preferred method with Visual Studio. The
|
||||
project files will probably be removed after 5.4.x releases.
|
||||
|
||||
- Changes to #defines in config.h:
|
||||
|
||||
* HAVE_DECL_CLOCK_MONOTONIC was replaced by
|
||||
HAVE_CLOCK_MONOTONIC. The old macro was always defined
|
||||
in configure-generated config.h to either 0 or 1. The
|
||||
new macro is defined (to 1) only if the declaration of
|
||||
CLOCK_MONOTONIC is available. This matches the way most
|
||||
other config.h macros work and makes things simpler with
|
||||
other build systems.
|
||||
|
||||
* HAVE_DECL_PROGRAM_INVOCATION_NAME was replaced by
|
||||
HAVE_PROGRAM_INVOCATION_NAME for the same reason.
|
||||
|
||||
* Tests:
|
||||
|
||||
- Fixed test script compatibility with ancient /bin/sh
|
||||
versions. Now the five test_compress_* tests should
|
||||
no longer fail on Solaris 10.
|
||||
|
||||
- Added and refactored a few tests.
|
||||
|
||||
* Translations:
|
||||
|
||||
- Updated the Catalan and Esperanto translations.
|
||||
|
||||
- Added Korean and Ukrainian man page translations.
|
||||
|
||||
|
||||
5.4.0 (2022-12-13)
|
||||
|
||||
This bumps the minor version of liblzma because new features were
|
||||
|
||||
3
THANKS
3
THANKS
@ -30,6 +30,7 @@ has been important. :-) In alphabetical order:
|
||||
- Vitaly Chikunov
|
||||
- Antoine Cœur
|
||||
- Gabi Davar
|
||||
- İhsan Doğan
|
||||
- Chris Donawa
|
||||
- Andrew Dudman
|
||||
- Markus Duft
|
||||
@ -56,10 +57,12 @@ has been important. :-) In alphabetical order:
|
||||
- Peter Ivanov
|
||||
- Nicholas Jackson
|
||||
- Sam James
|
||||
- Hajin Jang
|
||||
- Jouk Jansen
|
||||
- Jun I Jin
|
||||
- Kiyoshi Kanazawa
|
||||
- Per Øyvind Karlsen
|
||||
- Iouri Kharon
|
||||
- Thomas Klausner
|
||||
- Richard Koch
|
||||
- Ville Koskinen
|
||||
|
||||
@ -13,7 +13,6 @@ include(CheckSymbolExists)
|
||||
function(tuklib_progname TARGET_OR_ALL)
|
||||
# NOTE: This glibc extension requires _GNU_SOURCE.
|
||||
check_symbol_exists(program_invocation_name errno.h
|
||||
HAVE_DECL_PROGRAM_INVOCATION_NAME)
|
||||
tuklib_add_definition_if("${TARGET_OR_ALL}"
|
||||
HAVE_DECL_PROGRAM_INVOCATION_NAME)
|
||||
HAVE_PROGRAM_INVOCATION_NAME)
|
||||
tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_PROGRAM_INVOCATION_NAME)
|
||||
endfunction()
|
||||
|
||||
13
configure.ac
13
configure.ac
@ -638,7 +638,10 @@ case $enable_threads in
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
AC_CHECK_FUNCS([clock_gettime pthread_condattr_setclock])
|
||||
AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
|
||||
AC_CHECK_DECL([CLOCK_MONOTONIC], [AC_DEFINE(
|
||||
[HAVE_CLOCK_MONOTONIC], [1], [Define to 1 if
|
||||
`CLOCK_MONOTONIC' is declared in <time.h>.])], [],
|
||||
[[#include <time.h>]])
|
||||
CFLAGS=$OLD_CFLAGS
|
||||
;;
|
||||
win95)
|
||||
@ -935,6 +938,8 @@ AC_CHECK_DECL([_mm_movemask_epi8],
|
||||
# For faster CRC on 32/64-bit x86 and E2K (see also crc64_fast.c):
|
||||
#
|
||||
# - Check for the CLMUL intrinsic _mm_clmulepi64_si128 in <immintrin.h>.
|
||||
# Check also for _mm_set_epi64x for consistency with CMake build
|
||||
# where it's needed to disable CLMUL with VS2013.
|
||||
#
|
||||
# - Check that __attribute__((__target__("ssse3,sse4.1,pclmul"))) works
|
||||
# together with _mm_clmulepi64_si128 from <immintrin.h>. The attribute
|
||||
@ -962,13 +967,15 @@ else
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__EDG__)
|
||||
__attribute__((__target__("ssse3,sse4.1,pclmul")))
|
||||
#endif
|
||||
__m128i my_clmul(__m128i a, __m128i b)
|
||||
__m128i my_clmul(__m128i a)
|
||||
{
|
||||
const __m128i b = _mm_set_epi64x(1, 2);
|
||||
return _mm_clmulepi64_si128(a, b, 0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_USABLE_CLMUL], [1],
|
||||
[Define to 1 if _mm_clmulepi64_si128 is usable.
|
||||
[Define to 1 if _mm_set_epi64x and
|
||||
_mm_clmulepi64_si128 are usable.
|
||||
See configure.ac for details.])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
|
||||
@ -21,5 +21,8 @@
|
||||
|
||||
AC_DEFUN_ONCE([TUKLIB_PROGNAME], [
|
||||
AC_REQUIRE([TUKLIB_COMMON])
|
||||
AC_CHECK_DECLS([program_invocation_name], [], [], [#include <errno.h>])
|
||||
AC_CHECK_DECL([program_invocation_name], [AC_DEFINE(
|
||||
[HAVE_PROGRAM_INVOCATION_NAME], [1],
|
||||
[Define to 1 if `program_invocation_name' is declared in <errno.h>.])],
|
||||
[], [#include <errno.h>])
|
||||
])dnl
|
||||
|
||||
5552
po4a/ko.po
Normal file
5552
po4a/ko.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
# to get a new .po file. After translating the .po file, run
|
||||
# "update-po" again to generate the translated man pages.
|
||||
|
||||
[po4a_langs] de fr ro
|
||||
[po4a_langs] de fr ro uk ko
|
||||
[po4a_paths] xz-man.pot $lang:$lang.po
|
||||
|
||||
[type: man] ../src/xz/xz.1 $lang:man/$lang/xz.1
|
||||
|
||||
3676
po4a/uk.po
Normal file
3676
po4a/uk.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -100,12 +100,18 @@ mythread_sigmask(int how, const sigset_t *restrict set,
|
||||
// Using pthreads //
|
||||
////////////////////
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
// If clock_gettime() isn't available, use gettimeofday() from <sys/time.h>
|
||||
// as a fallback. gettimeofday() is in SUSv2 and thus is supported on all
|
||||
// relevant POSIX systems.
|
||||
#ifndef HAVE_CLOCK_GETTIME
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#define MYTHREAD_RET_TYPE void *
|
||||
#define MYTHREAD_RET_VALUE NULL
|
||||
|
||||
@ -219,8 +225,8 @@ static inline int
|
||||
mythread_cond_init(mythread_cond *mycond)
|
||||
{
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
// NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1.
|
||||
# if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && HAVE_DECL_CLOCK_MONOTONIC
|
||||
# if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \
|
||||
defined(HAVE_CLOCK_MONOTONIC)
|
||||
struct timespec ts;
|
||||
pthread_condattr_t condattr;
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Pre-C99 systems lack stdbool.h. All the code in LZMA Utils must be written
|
||||
// Pre-C99 systems lack stdbool.h. All the code in XZ Utils must be written
|
||||
// so that it works with fake bool type, for example:
|
||||
//
|
||||
// bool foo = (flags & 0x100) != 0;
|
||||
@ -149,18 +149,8 @@ typedef unsigned char _Bool;
|
||||
# define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
// string.h should be enough but let's include strings.h and memory.h too if
|
||||
// they exists, since that shouldn't do any harm, but may improve portability.
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
#endif
|
||||
|
||||
// As of MSVC 2013, inline and restrict are supported with
|
||||
// non-standard keywords.
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if !HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||
#ifndef HAVE_PROGRAM_INVOCATION_NAME
|
||||
char *progname = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
TUKLIB_DECLS_BEGIN
|
||||
|
||||
#if HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||
#ifdef HAVE_PROGRAM_INVOCATION_NAME
|
||||
# define progname program_invocation_name
|
||||
#else
|
||||
# define progname TUKLIB_SYMBOL(tuklib_progname)
|
||||
|
||||
@ -24,7 +24,7 @@ liblzma_la_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/liblzma/simple \
|
||||
-I$(top_srcdir)/src/common \
|
||||
-DTUKLIB_SYMBOL_PREFIX=lzma_
|
||||
liblzma_la_LDFLAGS = -no-undefined -version-info 9:0:4
|
||||
liblzma_la_LDFLAGS = -no-undefined -version-info 9:1:4
|
||||
|
||||
EXTRA_DIST += liblzma_generic.map liblzma_linux.map validate_map.sh
|
||||
if COND_SYMVERS_GENERIC
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
*/
|
||||
#define LZMA_VERSION_MAJOR 5
|
||||
#define LZMA_VERSION_MINOR 4
|
||||
#define LZMA_VERSION_PATCH 0
|
||||
#define LZMA_VERSION_PATCH 1
|
||||
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE
|
||||
|
||||
#ifndef LZMA_VERSION_COMMIT
|
||||
|
||||
@ -184,6 +184,20 @@ calc_hi(uint64_t poly, uint64_t a)
|
||||
MASK_H(in, mask, high)
|
||||
|
||||
|
||||
// MSVC (VS2015 - VS2022) produces bad 32-bit x86 code from the CLMUL CRC
|
||||
// code when optimizations are enabled (release build). According to the bug
|
||||
// report, the ebx register is corrupted and the calculated result is wrong.
|
||||
// Trying to workaround the problem with "__asm mov ebx, ebx" didn't help.
|
||||
// The following pragma works and performance is still good. x86-64 builds
|
||||
// aren't affected by this problem.
|
||||
//
|
||||
// NOTE: Another pragma after the function restores the optimizations.
|
||||
// If the #if condition here is updated, the other one must be updated too.
|
||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) \
|
||||
&& defined(_M_IX86)
|
||||
# pragma optimize("g", off)
|
||||
#endif
|
||||
|
||||
// EDG-based compilers (Intel's classic compiler and compiler for E2K) can
|
||||
// define __GNUC__ but the attribute must not be used with them.
|
||||
// The new Clang-based ICX needs the attribute.
|
||||
@ -371,6 +385,10 @@ crc64_clmul(const uint8_t *buf, size_t size, uint64_t crc)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) \
|
||||
&& defined(_M_IX86)
|
||||
# pragma optimize("", on)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@ -37,9 +37,12 @@ typedef struct {
|
||||
uint64_t (*block_size)(const void *options);
|
||||
|
||||
/// Tells the size of the Filter Properties field. If options are
|
||||
/// invalid, UINT32_MAX is returned. If this is NULL, props_size_fixed
|
||||
/// is used.
|
||||
/// invalid, LZMA_OPTIONS_ERROR is returned and size is set to
|
||||
/// UINT32_MAX.
|
||||
lzma_ret (*props_size_get)(uint32_t *size, const void *options);
|
||||
|
||||
/// Some filters will always have the same size Filter Properties
|
||||
/// field. If props_size_get is NULL, this value is used.
|
||||
uint32_t props_size_fixed;
|
||||
|
||||
/// Encodes Filter Properties.
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
#include "index.h"
|
||||
#include "stream_flags_common.h"
|
||||
|
||||
|
||||
@ -2,6 +2,13 @@
|
||||
//
|
||||
/// \file index.h
|
||||
/// \brief Handling of Index
|
||||
/// \note This header file does not include common.h or lzma.h because
|
||||
/// this file is needed by both liblzma internally and by the
|
||||
/// tests. Including common.h will include and define many things
|
||||
/// the tests do not need and prevents issues with header file
|
||||
/// include order. This way, if lzma.h or common.h are not
|
||||
/// included before this file it will break on every OS instead
|
||||
/// of causing more subtle errors.
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
@ -13,8 +20,6 @@
|
||||
#ifndef LZMA_INDEX_H
|
||||
#define LZMA_INDEX_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/// Minimum Unpadded Size
|
||||
#define UNPADDED_SIZE_MIN LZMA_VLI_C(5)
|
||||
@ -22,6 +27,9 @@
|
||||
/// Maximum Unpadded Size
|
||||
#define UNPADDED_SIZE_MAX (LZMA_VLI_MAX & ~LZMA_VLI_C(3))
|
||||
|
||||
/// Index Indicator based on xz specification
|
||||
#define INDEX_INDICATOR 0
|
||||
|
||||
|
||||
/// Get the size of the Index Padding field. This is needed by Index encoder
|
||||
/// and decoder, but applications should have no use for this.
|
||||
|
||||
@ -80,7 +80,7 @@ index_decode(void *coder_ptr, const lzma_allocator *allocator,
|
||||
// format". One could argue that the application should
|
||||
// verify the Index Indicator before trying to decode the
|
||||
// Index, but well, I suppose it is simpler this way.
|
||||
if (in[(*in_pos)++] != 0x00)
|
||||
if (in[(*in_pos)++] != INDEX_INDICATOR)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
coder->sequence = SEQ_COUNT;
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#ifndef LZMA_INDEX_DECODER_H
|
||||
#define LZMA_INDEX_DECODER_H
|
||||
|
||||
#include "common.h"
|
||||
#include "index.h"
|
||||
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ index_encode(void *coder_ptr,
|
||||
while (*out_pos < out_size)
|
||||
switch (coder->sequence) {
|
||||
case SEQ_INDICATOR:
|
||||
out[*out_pos] = 0x00;
|
||||
out[*out_pos] = INDEX_INDICATOR;
|
||||
++*out_pos;
|
||||
coder->sequence = SEQ_COUNT;
|
||||
break;
|
||||
|
||||
@ -145,7 +145,7 @@ lzma_index_hash_append(lzma_index_hash *index_hash, lzma_vli unpadded_size,
|
||||
lzma_vli uncompressed_size)
|
||||
{
|
||||
// Validate the arguments.
|
||||
if (index_hash->sequence != SEQ_BLOCK
|
||||
if (index_hash == NULL || index_hash->sequence != SEQ_BLOCK
|
||||
|| unpadded_size < UNPADDED_SIZE_MIN
|
||||
|| unpadded_size > UNPADDED_SIZE_MAX
|
||||
|| uncompressed_size > LZMA_VLI_MAX)
|
||||
@ -190,7 +190,7 @@ lzma_index_hash_decode(lzma_index_hash *index_hash, const uint8_t *in,
|
||||
switch (index_hash->sequence) {
|
||||
case SEQ_BLOCK:
|
||||
// Check the Index Indicator is present.
|
||||
if (in[(*in_pos)++] != 0x00)
|
||||
if (in[(*in_pos)++] != INDEX_INDICATOR)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
index_hash->sequence = SEQ_COUNT;
|
||||
|
||||
@ -111,7 +111,8 @@ microlzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
|
||||
// Encode the properties byte. Bitwise-negation of it will be the
|
||||
// first output byte.
|
||||
return_if_error(lzma_lzma_lclppb_encode(options, &coder->props));
|
||||
if (lzma_lzma_lclppb_encode(options, &coder->props))
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
// Initialize the LZMA encoder.
|
||||
const lzma_filter_info filters[2] = {
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
#include "index.h"
|
||||
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include "stream_decoder.h"
|
||||
#include "block_decoder.h"
|
||||
#include "index.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -164,7 +165,7 @@ stream_decode(void *coder_ptr, const lzma_allocator *allocator,
|
||||
|
||||
if (coder->pos == 0) {
|
||||
// Detect if it's Index.
|
||||
if (in[*in_pos] == 0x00) {
|
||||
if (in[*in_pos] == INDEX_INDICATOR) {
|
||||
coder->sequence = SEQ_INDEX;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -887,7 +887,7 @@ decode_block_header(struct lzma_stream_coder *coder,
|
||||
|
||||
if (coder->pos == 0) {
|
||||
// Detect if it's Index.
|
||||
if (in[*in_pos] == 0x00)
|
||||
if (in[*in_pos] == INDEX_INDICATOR)
|
||||
return LZMA_INDEX_DETECTED;
|
||||
|
||||
// Calculate the size of the Block Header. Note that
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
//
|
||||
// Authors: Lasse Collin
|
||||
// Jia Tan
|
||||
// Igor Pavlov
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
|
||||
@ -723,7 +723,16 @@ vmessage(enum message_verbosity v, const char *fmt, va_list ap)
|
||||
// This is a translatable string because French needs
|
||||
// a space before a colon.
|
||||
fprintf(stderr, _("%s: "), progname);
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
vfprintf(stderr, fmt, ap);
|
||||
#ifdef __clang__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
fputc('\n', stderr);
|
||||
|
||||
signals_unblock();
|
||||
|
||||
@ -12,7 +12,9 @@
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#if !(defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC)
|
||||
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CLOCK_MONOTONIC)
|
||||
# include <time.h>
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
@ -28,8 +30,7 @@ static uint64_t next_flush;
|
||||
static uint64_t
|
||||
mytime_now(void)
|
||||
{
|
||||
// NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1.
|
||||
#if defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC
|
||||
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CLOCK_MONOTONIC)
|
||||
// If CLOCK_MONOTONIC was available at compile time but for some
|
||||
// reason isn't at runtime, fallback to CLOCK_REALTIME which
|
||||
// according to POSIX is mandatory for all implementations.
|
||||
|
||||
@ -18,6 +18,9 @@
|
||||
|
||||
// For case-insensitive filename suffix on case-insensitive systems
|
||||
#if defined(TUKLIB_DOSLIKE) || defined(__VMS)
|
||||
# ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
# endif
|
||||
# define strcmp strcasecmp
|
||||
#endif
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ EXTRA_DIST = \
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/common \
|
||||
-I$(top_srcdir)/src/liblzma/api \
|
||||
-I$(top_srcdir)/src/liblzma \
|
||||
-I$(top_builddir)/lib
|
||||
|
||||
LDADD = $(top_builddir)/src/liblzma/liblzma.la
|
||||
@ -44,8 +45,10 @@ check_PROGRAMS = \
|
||||
test_filter_flags \
|
||||
test_block_header \
|
||||
test_index \
|
||||
test_index_hash \
|
||||
test_bcj_exact_size \
|
||||
test_memlimit \
|
||||
test_lzip_decoder \
|
||||
test_vli
|
||||
|
||||
TESTS = \
|
||||
@ -55,8 +58,10 @@ TESTS = \
|
||||
test_filter_flags \
|
||||
test_block_header \
|
||||
test_index \
|
||||
test_index_hash \
|
||||
test_bcj_exact_size \
|
||||
test_memlimit \
|
||||
test_lzip_decoder \
|
||||
test_vli \
|
||||
test_files.sh \
|
||||
test_compress_prepared_bcj_sparc \
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
// Avoid re-creating the test files every time the tests are run.
|
||||
#define maybe_create_test(argc, argv, name) \
|
||||
do { \
|
||||
if ((argc < 2 || strcmp(argv[1], #name) == 0) \
|
||||
if ((argc < 2 || strcmp(argv[1], "compress_generated_" #name) == 0) \
|
||||
&& !file_exists("compress_generated_" #name)) { \
|
||||
FILE *file = file_create("compress_generated_" #name); \
|
||||
write_ ## name(file); \
|
||||
|
||||
@ -35,6 +35,9 @@ static lzma_filter filters_one[2] = {
|
||||
};
|
||||
|
||||
|
||||
// These filters are only used in test_lzma_block_header_decode()
|
||||
// which only runs if encoders and decoders are configured.
|
||||
#ifdef HAVE_DECODERS
|
||||
static lzma_filter filters_four[5] = {
|
||||
{
|
||||
.id = LZMA_FILTER_X86,
|
||||
@ -52,6 +55,7 @@ static lzma_filter filters_four[5] = {
|
||||
.id = LZMA_VLI_UNKNOWN,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static lzma_filter filters_five[6] = {
|
||||
|
||||
@ -50,6 +50,22 @@ static uint8_t *sha256_xz_data;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CHECK_CRC64
|
||||
static const uint8_t *
|
||||
get_random256(uint32_t *seed)
|
||||
{
|
||||
static uint8_t buf[256];
|
||||
|
||||
for (size_t i = 0; i < sizeof(buf); ++i) {
|
||||
*seed = *seed * 1103515245 + 12345;
|
||||
buf[i] = (uint8_t)(*seed >> 22);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
test_lzma_crc32(void)
|
||||
{
|
||||
@ -99,6 +115,17 @@ test_lzma_crc64(void)
|
||||
for (size_t i = 0; i < sizeof(test_string); ++i)
|
||||
crc = lzma_crc64(test_string + i, 1, crc);
|
||||
assert_uint_eq(crc, test_vector);
|
||||
|
||||
// Test 4: The CLMUL implementation works on 16-byte chunks.
|
||||
// Test combination of different start and end alignments
|
||||
// and also short buffer lengths where special handling is needed.
|
||||
uint32_t seed = 29;
|
||||
crc = 0x96E30D5184B7FA2C; // Random initial value
|
||||
for (size_t start = 0; start < 32; ++start)
|
||||
for (size_t size = 1; size < 256 - 32; ++size)
|
||||
crc = lzma_crc64(get_random256(&seed), size, crc);
|
||||
|
||||
assert_uint_eq(crc, 0x23AB787177231C9F);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -84,10 +84,19 @@ XZDEC="../src/xzdec/xzdec" # No memory usage limiter available
|
||||
test -x ../src/xzdec/xzdec || XZDEC=
|
||||
|
||||
# Create the required input file if needed.
|
||||
#
|
||||
# Derive temporary filenames for compressed and uncompressed outputs
|
||||
# from the input filename. This is needed when multiple tests are
|
||||
# run in parallel.
|
||||
FILE=$1
|
||||
TMP_COMP="tmp_comp_$FILE"
|
||||
TMP_UNCOMP="tmp_uncomp_$FILE"
|
||||
|
||||
case $FILE in
|
||||
# compress_generated files will be created in the build directory
|
||||
# in the /tests/ sub-directory.
|
||||
compress_generated_*)
|
||||
if ./create_compress_files "${FILE#compress_generated_}" ; then
|
||||
if ./create_compress_files "$FILE" ; then
|
||||
:
|
||||
else
|
||||
rm -f "$FILE"
|
||||
@ -95,18 +104,17 @@ case $FILE in
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
# compress_prepared files exist in the source directory since they
|
||||
# do not need to be copied or regenerated.
|
||||
compress_prepared_*)
|
||||
FILE="$srcdir/$FILE"
|
||||
;;
|
||||
'')
|
||||
echo "No test file was specified."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Derive temporary filenames for compressed and uncompressed outputs
|
||||
# from the input filename. This is needed when multiple tests are
|
||||
# run in parallel.
|
||||
TMP_COMP="tmp_comp_${FILE##*/}"
|
||||
TMP_UNCOMP="tmp_uncomp_${FILE##*/}"
|
||||
|
||||
# Remove temporary now (in case they are something weird), and on exit.
|
||||
rm -f "$TMP_COMP" "$TMP_UNCOMP"
|
||||
trap 'rm -f "$TMP_COMP" "$TMP_UNCOMP"' 0
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec "$srcdir/test_compress.sh" "$srcdir/compress_prepared_bcj_sparc"
|
||||
exec "$srcdir/test_compress.sh" compress_prepared_bcj_sparc
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec "$srcdir/test_compress.sh" "$srcdir/compress_prepared_bcj_x86"
|
||||
exec "$srcdir/test_compress.sh" compress_prepared_bcj_x86
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
/// \file test_filter_flags.c
|
||||
/// \brief Tests Filter Flags coders
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
// Authors: Jia Tan
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
@ -12,247 +13,515 @@
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
static uint8_t buffer[4096];
|
||||
static lzma_filter known_flags;
|
||||
static lzma_filter decoded_flags;
|
||||
static lzma_stream strm = LZMA_STREAM_INIT;
|
||||
// FIXME: This is from src/liblzma/common/common.h but it cannot be
|
||||
// included here. This constant is needed in only a few files, perhaps
|
||||
// move it to some other internal header or create a new one?
|
||||
#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62)
|
||||
|
||||
|
||||
static bool
|
||||
encode(uint32_t known_size)
|
||||
{
|
||||
memcrap(buffer, sizeof(buffer));
|
||||
#if defined(HAVE_ENCODERS)
|
||||
// No tests are run without encoders, so init the global filters
|
||||
// only when the encoders are enabled.
|
||||
static lzma_filter lzma1_filter = { LZMA_FILTER_LZMA1, NULL };
|
||||
static lzma_filter lzma2_filter = { LZMA_FILTER_LZMA2, NULL };
|
||||
static lzma_filter delta_filter = { LZMA_FILTER_DELTA, NULL };
|
||||
|
||||
uint32_t tmp;
|
||||
if (lzma_filter_flags_size(&tmp, &known_flags) != LZMA_OK)
|
||||
return true;
|
||||
static lzma_filter bcj_filters_encoders[] = {
|
||||
#ifdef HAVE_ENCODER_X86
|
||||
{ LZMA_FILTER_X86, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_POWERPC
|
||||
{ LZMA_FILTER_POWERPC, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_IA64
|
||||
{ LZMA_FILTER_IA64, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_ARM
|
||||
{ LZMA_FILTER_ARM, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_ARM64
|
||||
{ LZMA_FILTER_ARM64, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_ARMTHUMB
|
||||
{ LZMA_FILTER_ARMTHUMB, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_SPARC
|
||||
{ LZMA_FILTER_SPARC, NULL },
|
||||
#endif
|
||||
};
|
||||
|
||||
if (tmp != known_size)
|
||||
return true;
|
||||
// HAVE_ENCODERS ifdef not termianted here because decoders are
|
||||
// only used if encoders are, but encoders can still be used
|
||||
// even if decoders are not.
|
||||
|
||||
size_t out_pos = 0;
|
||||
if (lzma_filter_flags_encode(&known_flags,
|
||||
buffer, &out_pos, known_size) != LZMA_OK)
|
||||
return true;
|
||||
|
||||
if (out_pos != known_size)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
decode_ret(uint32_t known_size, lzma_ret expected_ret)
|
||||
{
|
||||
memcrap(&decoded_flags, sizeof(decoded_flags));
|
||||
|
||||
size_t pos = 0;
|
||||
if (lzma_filter_flags_decode(&decoded_flags, NULL,
|
||||
buffer, &pos, known_size) != expected_ret
|
||||
|| pos != known_size)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
decode(uint32_t known_size)
|
||||
{
|
||||
if (decode_ret(known_size, LZMA_OK))
|
||||
return true;
|
||||
|
||||
if (known_flags.id != decoded_flags.id)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86)
|
||||
static void
|
||||
test_bcj(void)
|
||||
{
|
||||
// Test 1
|
||||
known_flags.id = LZMA_FILTER_X86;
|
||||
known_flags.options = NULL;
|
||||
|
||||
expect(!encode(2));
|
||||
expect(!decode(2));
|
||||
expect(decoded_flags.options == NULL);
|
||||
|
||||
// Test 2
|
||||
lzma_options_bcj options;
|
||||
options.start_offset = 0;
|
||||
known_flags.options = &options;
|
||||
expect(!encode(2));
|
||||
expect(!decode(2));
|
||||
expect(decoded_flags.options == NULL);
|
||||
|
||||
// Test 3
|
||||
options.start_offset = 123456;
|
||||
known_flags.options = &options;
|
||||
expect(!encode(6));
|
||||
expect(!decode(6));
|
||||
expect(decoded_flags.options != NULL);
|
||||
|
||||
lzma_options_bcj *decoded = decoded_flags.options;
|
||||
expect(decoded->start_offset == options.start_offset);
|
||||
|
||||
free(decoded);
|
||||
}
|
||||
#ifdef HAVE_DECODERS
|
||||
static lzma_filter bcj_filters_decoders[] = {
|
||||
#ifdef HAVE_DECODER_X86
|
||||
{ LZMA_FILTER_X86, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_DECODER_POWERPC
|
||||
{ LZMA_FILTER_POWERPC, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_DECODER_IA64
|
||||
{ LZMA_FILTER_IA64, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_DECODER_ARM
|
||||
{ LZMA_FILTER_ARM, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_DECODER_ARM64
|
||||
{ LZMA_FILTER_ARM64, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_DECODER_ARMTHUMB
|
||||
{ LZMA_FILTER_ARMTHUMB, NULL },
|
||||
#endif
|
||||
#ifdef HAVE_DECODER_SPARC
|
||||
{ LZMA_FILTER_SPARC, NULL },
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA)
|
||||
static void
|
||||
test_delta(void)
|
||||
test_lzma_filter_flags_size(void)
|
||||
{
|
||||
// Test 1
|
||||
known_flags.id = LZMA_FILTER_DELTA;
|
||||
known_flags.options = NULL;
|
||||
expect(encode(99));
|
||||
|
||||
// Test 2
|
||||
lzma_options_delta options = {
|
||||
.type = LZMA_DELTA_TYPE_BYTE,
|
||||
.dist = 0
|
||||
};
|
||||
known_flags.options = &options;
|
||||
expect(encode(99));
|
||||
|
||||
// Test 3
|
||||
options.dist = LZMA_DELTA_DIST_MIN;
|
||||
expect(!encode(3));
|
||||
expect(!decode(3));
|
||||
expect(((lzma_options_delta *)(decoded_flags.options))->dist
|
||||
== options.dist);
|
||||
|
||||
free(decoded_flags.options);
|
||||
|
||||
// Test 4
|
||||
options.dist = LZMA_DELTA_DIST_MAX;
|
||||
expect(!encode(3));
|
||||
expect(!decode(3));
|
||||
expect(((lzma_options_delta *)(decoded_flags.options))->dist
|
||||
== options.dist);
|
||||
|
||||
free(decoded_flags.options);
|
||||
|
||||
// Test 5
|
||||
options.dist = LZMA_DELTA_DIST_MAX + 1;
|
||||
expect(encode(99));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifdef HAVE_FILTER_LZMA
|
||||
static void
|
||||
validate_lzma(void)
|
||||
{
|
||||
const lzma_options_lzma *known = known_flags.options;
|
||||
const lzma_options_lzma *decoded = decoded_flags.options;
|
||||
|
||||
expect(known->dictionary_size <= decoded->dictionary_size);
|
||||
|
||||
if (known->dictionary_size == 1)
|
||||
expect(decoded->dictionary_size == 1);
|
||||
else
|
||||
expect(known->dictionary_size + known->dictionary_size / 2
|
||||
> decoded->dictionary_size);
|
||||
|
||||
expect(known->literal_context_bits == decoded->literal_context_bits);
|
||||
expect(known->literal_pos_bits == decoded->literal_pos_bits);
|
||||
expect(known->pos_bits == decoded->pos_bits);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_lzma(void)
|
||||
{
|
||||
// Test 1
|
||||
known_flags.id = LZMA_FILTER_LZMA1;
|
||||
known_flags.options = NULL;
|
||||
expect(encode(99));
|
||||
|
||||
// Test 2
|
||||
lzma_options_lzma options = {
|
||||
.dictionary_size = 0,
|
||||
.literal_context_bits = 0,
|
||||
.literal_pos_bits = 0,
|
||||
.pos_bits = 0,
|
||||
.preset_dictionary = NULL,
|
||||
.preset_dictionary_size = 0,
|
||||
.mode = LZMA_MODE_INVALID,
|
||||
.fast_bytes = 0,
|
||||
.match_finder = LZMA_MF_INVALID,
|
||||
.match_finder_cycles = 0,
|
||||
};
|
||||
|
||||
// Test 3 (empty dictionary not allowed)
|
||||
known_flags.options = &options;
|
||||
expect(encode(99));
|
||||
|
||||
// Test 4 (brute-force test some valid dictionary sizes)
|
||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN;
|
||||
while (options.dictionary_size != LZMA_DICTIONARY_SIZE_MAX) {
|
||||
if (++options.dictionary_size == 5000)
|
||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX - 5;
|
||||
|
||||
expect(!encode(4));
|
||||
expect(!decode(4));
|
||||
validate_lzma();
|
||||
|
||||
free(decoded_flags.options);
|
||||
#ifndef HAVE_ENCODERS
|
||||
assert_skip("Encoder support disabled");
|
||||
#else
|
||||
// For each supported filter, test that the size can be calculated
|
||||
// and that the size calculated is reasonable. A reasonable size
|
||||
// must be greater than 0, but less than the maximum size for the
|
||||
// block header.
|
||||
uint32_t size = 0;
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA1)) {
|
||||
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||
&lzma1_filter), LZMA_PROG_ERROR);
|
||||
}
|
||||
|
||||
// Test 5 (too big dictionary size)
|
||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX + 1;
|
||||
expect(encode(99));
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||
&lzma2_filter), LZMA_OK);
|
||||
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||
}
|
||||
|
||||
// Test 6 (brute-force test lc/lp/pb)
|
||||
options.dictionary_size = LZMA_DICTIONARY_SIZE_MIN;
|
||||
for (uint32_t lc = LZMA_LITERAL_CONTEXT_BITS_MIN;
|
||||
lc <= LZMA_LITERAL_CONTEXT_BITS_MAX; ++lc) {
|
||||
for (uint32_t lp = LZMA_LITERAL_POS_BITS_MIN;
|
||||
lp <= LZMA_LITERAL_POS_BITS_MAX; ++lp) {
|
||||
for (uint32_t pb = LZMA_POS_BITS_MIN;
|
||||
pb <= LZMA_POS_BITS_MAX; ++pb) {
|
||||
if (lc + lp > LZMA_LITERAL_BITS_MAX)
|
||||
continue;
|
||||
// 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++) {
|
||||
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||
&bcj_filters_encoders[i]), LZMA_OK);
|
||||
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||
}
|
||||
|
||||
options.literal_context_bits = lc;
|
||||
options.literal_pos_bits = lp;
|
||||
options.pos_bits = pb;
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||
assert_lzma_ret(lzma_filter_flags_size(&size,
|
||||
&delta_filter), LZMA_OK);
|
||||
assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX);
|
||||
}
|
||||
|
||||
expect(!encode(4));
|
||||
expect(!decode(4));
|
||||
validate_lzma();
|
||||
// Test invalid Filter IDs
|
||||
lzma_filter bad_filter = { 2, NULL };
|
||||
|
||||
free(decoded_flags.options);
|
||||
}
|
||||
assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter),
|
||||
LZMA_OPTIONS_ERROR);
|
||||
bad_filter.id = LZMA_VLI_MAX;
|
||||
assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter),
|
||||
LZMA_PROG_ERROR);
|
||||
bad_filter.id = LZMA_FILTER_RESERVED_START;
|
||||
assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter),
|
||||
LZMA_PROG_ERROR);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Helper function for test_lzma_filter_flags_encode.
|
||||
// The should_encode parameter represents if the encoding operation
|
||||
// is expected to fail.
|
||||
// Avoid data -> encode -> decode -> compare to data.
|
||||
// Instead create expected encoding and compare to result from
|
||||
// lzma_filter_flags_encode.
|
||||
// Filter Flags in .xz are encoded as:
|
||||
// |Filter ID (VLI)|Size of Properties (VLI)|Filter Properties|
|
||||
#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
|
||||
static void
|
||||
verify_filter_flags_encode(lzma_filter *filter, bool should_encode)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
|
||||
// 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));
|
||||
size_t out_pos = 0;
|
||||
if (!should_encode) {
|
||||
assert_false(lzma_filter_flags_encode(filter, encoded_out,
|
||||
&out_pos, size) == LZMA_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
// Next encode the Filter Flags for the provided filter
|
||||
assert_lzma_ret(lzma_filter_flags_encode(filter, encoded_out,
|
||||
&out_pos, size), LZMA_OK);
|
||||
assert_uint_eq(size, out_pos);
|
||||
|
||||
// Next decode the VLI for the Filter ID and verify it matches
|
||||
// the expected Filter ID
|
||||
size_t filter_id_vli_size = 0;
|
||||
lzma_vli filter_id = 0;
|
||||
assert_lzma_ret(lzma_vli_decode(&filter_id, NULL, encoded_out,
|
||||
&filter_id_vli_size, size), LZMA_OK);
|
||||
assert_uint_eq(filter->id, filter_id);
|
||||
|
||||
// Next decode the Size of Properites and ensure it equals
|
||||
// the expected size.
|
||||
// Expected size should be:
|
||||
// total filter flag length - size of filter id VLI + size of
|
||||
// property size VLI
|
||||
// Not verifying the contents of Filter Properties since
|
||||
// that belongs in a different test
|
||||
size_t size_of_properties_vli_size = 0;
|
||||
lzma_vli size_of_properties = 0;
|
||||
assert_lzma_ret(lzma_vli_decode(&size_of_properties, NULL,
|
||||
encoded_out + filter_id_vli_size,
|
||||
&size_of_properties_vli_size, size), LZMA_OK);
|
||||
assert_uint_eq(size - (size_of_properties_vli_size +
|
||||
filter_id_vli_size), size_of_properties);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
test_lzma_filter_flags_encode(void)
|
||||
{
|
||||
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
|
||||
assert_skip("Encoder or decoder support disabled");
|
||||
#else
|
||||
// No test for LZMA1 since the .xz format does not support LZMA1
|
||||
// and so the flags cannot be encoded for that filter
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||
// Test with NULL options that should fail
|
||||
lzma_options_lzma *options = lzma2_filter.options;
|
||||
lzma2_filter.options = NULL;
|
||||
verify_filter_flags_encode(&lzma2_filter, false);
|
||||
|
||||
// Place options back in the filter, and test should pass
|
||||
lzma2_filter.options = options;
|
||||
verify_filter_flags_encode(&lzma2_filter, true);
|
||||
}
|
||||
|
||||
// NOTE: Many BCJ filters require that start_offset is a multiple
|
||||
// of some power of two. The Filter Flags encoder and decoder don't
|
||||
// completely validate the options and thus 257 passes the tests
|
||||
// with all BCJ filters. It would be caught when initializing
|
||||
// a filter chain encoder or decoder.
|
||||
lzma_options_bcj bcj_options = {
|
||||
.start_offset = 257
|
||||
};
|
||||
|
||||
const uint32_t bcj_array_size = ARRAY_SIZE(bcj_filters_encoders);
|
||||
for (uint32_t i = 0; i < bcj_array_size; i++) {
|
||||
// NULL options should pass for bcj filters
|
||||
verify_filter_flags_encode(&bcj_filters_encoders[i], true);
|
||||
lzma_filter bcj_with_options = {
|
||||
bcj_filters_encoders[i].id, &bcj_options };
|
||||
verify_filter_flags_encode(&bcj_with_options, true);
|
||||
}
|
||||
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||
lzma_options_delta delta_opts_below_min = {
|
||||
.type = LZMA_DELTA_TYPE_BYTE,
|
||||
.dist = LZMA_DELTA_DIST_MIN - 1
|
||||
};
|
||||
|
||||
lzma_options_delta delta_opts_above_max = {
|
||||
.type = LZMA_DELTA_TYPE_BYTE,
|
||||
.dist = LZMA_DELTA_DIST_MAX + 1
|
||||
};
|
||||
|
||||
verify_filter_flags_encode(&delta_filter, true);
|
||||
|
||||
lzma_filter delta_filter_bad_options = {
|
||||
LZMA_FILTER_DELTA, &delta_opts_below_min };
|
||||
|
||||
// Next test error case using minimum - 1 delta distance
|
||||
verify_filter_flags_encode(&delta_filter_bad_options, false);
|
||||
|
||||
// Next test error case using maximum + 1 delta distance
|
||||
delta_filter_bad_options.options = &delta_opts_above_max;
|
||||
verify_filter_flags_encode(&delta_filter_bad_options, false);
|
||||
|
||||
// Next test NULL case
|
||||
delta_filter_bad_options.options = NULL;
|
||||
verify_filter_flags_encode(&delta_filter_bad_options, false);
|
||||
}
|
||||
|
||||
// Test expected failing cases
|
||||
lzma_filter bad_filter = { LZMA_FILTER_RESERVED_START, NULL };
|
||||
size_t out_pos = 0;
|
||||
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);
|
||||
out_pos = 0;
|
||||
bad_filter.id = LZMA_VLI_MAX + 1;
|
||||
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos,
|
||||
out_size), LZMA_PROG_ERROR);
|
||||
out_pos = 0;
|
||||
|
||||
// Invalid Filter ID
|
||||
bad_filter.id = 2;
|
||||
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos,
|
||||
out_size), LZMA_OPTIONS_ERROR);
|
||||
out_pos = 0;
|
||||
|
||||
// Out size too small
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||
uint32_t bad_size = 0;
|
||||
|
||||
// First test with 0 output size
|
||||
assert_lzma_ret(lzma_filter_flags_encode(
|
||||
&lzma2_filter, out, &out_pos, 0),
|
||||
LZMA_PROG_ERROR);
|
||||
|
||||
// Next calculate the size needed to encode and
|
||||
// use less than that
|
||||
assert_lzma_ret(lzma_filter_flags_size(&bad_size,
|
||||
&lzma2_filter), LZMA_OK);
|
||||
|
||||
assert_lzma_ret(lzma_filter_flags_encode(
|
||||
&lzma2_filter, out, &out_pos,
|
||||
bad_size - 1), LZMA_PROG_ERROR);
|
||||
out_pos = 0;
|
||||
}
|
||||
|
||||
// Invalid options
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||
bad_filter.id = LZMA_FILTER_DELTA;
|
||||
|
||||
// First test with NULL options
|
||||
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out,
|
||||
&out_pos, out_size), LZMA_PROG_ERROR);
|
||||
out_pos = 0;
|
||||
|
||||
// Next test with invalid options
|
||||
lzma_options_delta bad_options = {
|
||||
.dist = LZMA_DELTA_DIST_MAX + 1,
|
||||
.type = LZMA_DELTA_TYPE_BYTE
|
||||
};
|
||||
bad_filter.options = &bad_options;
|
||||
|
||||
assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out,
|
||||
&out_pos, out_size), LZMA_PROG_ERROR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Helper function for test_lzma_filter_flags_decode.
|
||||
// Encodes the filter_in without using lzma_filter_flags_encode.
|
||||
// Leaves the specific assertions of filter_out options to the caller
|
||||
// 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)
|
||||
{
|
||||
uint32_t total_size = 0;
|
||||
|
||||
assert_lzma_ret(lzma_filter_flags_size(&total_size, filter_in),
|
||||
LZMA_OK);
|
||||
assert_uint(total_size, >, 0);
|
||||
uint8_t *filter_flag_buffer = tuktest_malloc(total_size);
|
||||
|
||||
uint32_t properties_size = 0;
|
||||
size_t out_pos = 0;
|
||||
size_t in_pos = 0;
|
||||
assert_lzma_ret(lzma_properties_size(&properties_size, filter_in),
|
||||
LZMA_OK);
|
||||
assert_lzma_ret(lzma_vli_encode(filter_in->id, NULL,
|
||||
filter_flag_buffer, &out_pos, total_size), LZMA_OK);
|
||||
assert_lzma_ret(lzma_vli_encode(properties_size, NULL,
|
||||
filter_flag_buffer, &out_pos, total_size),
|
||||
LZMA_OK);
|
||||
assert_lzma_ret(lzma_properties_encode(filter_in,
|
||||
filter_flag_buffer + out_pos), LZMA_OK);
|
||||
assert_lzma_ret(lzma_filter_flags_decode(filter_out, NULL,
|
||||
filter_flag_buffer, &in_pos, total_size),
|
||||
LZMA_OK);
|
||||
assert_uint_eq(filter_in->id, filter_out->id);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
test_lzma_filter_flags_decode(void)
|
||||
{
|
||||
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
|
||||
assert_skip("Encoder or decoder support disabled");
|
||||
#else
|
||||
// For each filter, only run the decoder test if both the encoder
|
||||
// and decoder are enabled. This is because verify_filter_flags_decode
|
||||
// uses lzma_filter_flags_size which requires the encoder.
|
||||
if (lzma_filter_decoder_is_supported(LZMA_FILTER_LZMA2) &&
|
||||
lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||
lzma_filter lzma2_decoded = { LZMA_FILTER_LZMA2, NULL };
|
||||
|
||||
verify_filter_flags_decode(&lzma2_filter, &lzma2_decoded);
|
||||
|
||||
lzma_options_lzma *expected = lzma2_filter.options;
|
||||
lzma_options_lzma *decoded = lzma2_decoded.options;
|
||||
|
||||
// Only the dictionary size is encoded and decoded
|
||||
// so only compare those
|
||||
assert_uint_eq(decoded->dict_size, expected->dict_size);
|
||||
|
||||
// The decoded options must be freed by the caller
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
const uint32_t bcj_array_size = ARRAY_SIZE(bcj_filters_decoders);
|
||||
for (uint32_t i = 0; i < bcj_array_size; i++) {
|
||||
if (lzma_filter_encoder_is_supported(
|
||||
bcj_filters_decoders[i].id)) {
|
||||
lzma_filter bcj_decoded = {
|
||||
bcj_filters_decoders[i].id, NULL };
|
||||
|
||||
lzma_filter bcj_encoded = {
|
||||
bcj_filters_decoders[i].id, NULL };
|
||||
|
||||
// First test without options
|
||||
verify_filter_flags_decode(&bcj_encoded,
|
||||
&bcj_decoded);
|
||||
assert_true(bcj_decoded.options == NULL);
|
||||
|
||||
// Next test with offset
|
||||
lzma_options_bcj options = {
|
||||
.start_offset = 257
|
||||
};
|
||||
|
||||
bcj_encoded.options = &options;
|
||||
verify_filter_flags_decode(&bcj_encoded,
|
||||
&bcj_decoded);
|
||||
lzma_options_bcj *decoded_opts = bcj_decoded.options;
|
||||
assert_uint_eq(decoded_opts->start_offset,
|
||||
options.start_offset);
|
||||
free(decoded_opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
int
|
||||
main(void)
|
||||
if (lzma_filter_decoder_is_supported(LZMA_FILTER_DELTA) &&
|
||||
lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||
lzma_filter delta_decoded = { LZMA_FILTER_DELTA, NULL };
|
||||
|
||||
verify_filter_flags_decode(&delta_filter, &delta_decoded);
|
||||
lzma_options_delta *expected = delta_filter.options;
|
||||
lzma_options_delta *decoded = delta_decoded.options;
|
||||
assert_uint_eq(expected->dist, decoded->dist);
|
||||
assert_uint_eq(expected->type, decoded->type);
|
||||
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
// Test expected failing cases
|
||||
uint8_t bad_encoded_filter[LZMA_BLOCK_HEADER_SIZE_MAX];
|
||||
lzma_filter bad_filter;
|
||||
|
||||
// Filter ID outside of valid range
|
||||
lzma_vli bad_filter_id = LZMA_FILTER_RESERVED_START;
|
||||
size_t bad_encoded_out_pos = 0;
|
||||
size_t in_pos = 0;
|
||||
|
||||
assert_lzma_ret(lzma_vli_encode(bad_filter_id, NULL,
|
||||
bad_encoded_filter, &bad_encoded_out_pos,
|
||||
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||
|
||||
assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL,
|
||||
bad_encoded_filter, &in_pos,
|
||||
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_DATA_ERROR);
|
||||
|
||||
bad_encoded_out_pos = 0;
|
||||
in_pos = 0;
|
||||
|
||||
// Invalid Filter ID
|
||||
bad_filter_id = 2;
|
||||
bad_encoded_out_pos = 0;
|
||||
in_pos = 0;
|
||||
|
||||
assert_lzma_ret(lzma_vli_encode(bad_filter_id, NULL,
|
||||
bad_encoded_filter, &bad_encoded_out_pos,
|
||||
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||
|
||||
// Next encode Size of Properties with the value of 0
|
||||
assert_lzma_ret(lzma_vli_encode(0, NULL,
|
||||
bad_encoded_filter, &bad_encoded_out_pos,
|
||||
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||
|
||||
// Decode should fail on bad Filter ID
|
||||
assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL,
|
||||
bad_encoded_filter, &in_pos,
|
||||
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OPTIONS_ERROR);
|
||||
bad_encoded_out_pos = 0;
|
||||
in_pos = 0;
|
||||
|
||||
// Outsize too small
|
||||
// Encode the LZMA2 filter normally, but then set
|
||||
// the out size when decoding as too small
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2) &&
|
||||
lzma_filter_decoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||
uint32_t filter_flag_size = 0;
|
||||
assert_lzma_ret(lzma_filter_flags_size(&filter_flag_size,
|
||||
&lzma2_filter), LZMA_OK);
|
||||
|
||||
assert_lzma_ret(lzma_filter_flags_encode(&lzma2_filter,
|
||||
bad_encoded_filter, &bad_encoded_out_pos,
|
||||
LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK);
|
||||
|
||||
assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL,
|
||||
bad_encoded_filter, &in_pos,
|
||||
filter_flag_size - 1), LZMA_DATA_ERROR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
#if defined(HAVE_ENCODER_X86) && defined(HAVE_DECODER_X86)
|
||||
test_bcj();
|
||||
#endif
|
||||
#if defined(HAVE_ENCODER_DELTA) && defined(HAVE_DECODER_DELTA)
|
||||
test_delta();
|
||||
#endif
|
||||
// #ifdef HAVE_FILTER_LZMA
|
||||
// test_lzma();
|
||||
// #endif
|
||||
tuktest_start(argc, argv);
|
||||
|
||||
lzma_end(&strm);
|
||||
#ifdef HAVE_ENCODERS
|
||||
// Only init filter options if encoder is supported because decoder
|
||||
// tests requires encoder support, so the decoder tests will only
|
||||
// run if for a given filter both the encoder and decoder are enabled.
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA1)) {
|
||||
lzma_options_lzma *options = tuktest_malloc(
|
||||
sizeof(lzma_options_lzma));
|
||||
lzma_lzma_preset(options, LZMA_PRESET_DEFAULT);
|
||||
lzma1_filter.options = options;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) {
|
||||
lzma_options_lzma *options = tuktest_malloc(
|
||||
sizeof(lzma_options_lzma));
|
||||
lzma_lzma_preset(options, LZMA_PRESET_DEFAULT);
|
||||
lzma2_filter.options = options;
|
||||
}
|
||||
|
||||
if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) {
|
||||
lzma_options_delta *options = tuktest_malloc(
|
||||
sizeof(lzma_options_delta));
|
||||
options->dist = LZMA_DELTA_DIST_MIN;
|
||||
options->type = LZMA_DELTA_TYPE_BYTE;
|
||||
delta_filter.options = options;
|
||||
}
|
||||
#endif
|
||||
|
||||
tuktest_run(test_lzma_filter_flags_size);
|
||||
tuktest_run(test_lzma_filter_flags_encode);
|
||||
tuktest_run(test_lzma_filter_flags_decode);
|
||||
return tuktest_end();
|
||||
}
|
||||
|
||||
386
tests/test_index_hash.c
Normal file
386
tests/test_index_hash.c
Normal file
@ -0,0 +1,386 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file test_index_hash.c
|
||||
/// \brief Tests src/liblzma/common/index_hash.c API functions
|
||||
///
|
||||
/// \note No test included for lzma_index_hash_end since it
|
||||
/// would be trivial unless tested for memory leaks
|
||||
/// with something like valgrind
|
||||
//
|
||||
// Author: Jia Tan
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
// Needed for UNPADDED_SIZE_MIN and UNPADDED_SIZE_MAX macro definitions
|
||||
// and index_size and vli_ceil4 helper functions
|
||||
#include "common/index.h"
|
||||
|
||||
|
||||
static void
|
||||
test_lzma_index_hash_init(void)
|
||||
{
|
||||
#ifndef HAVE_DECODERS
|
||||
assert_skip("Decoder support disabled");
|
||||
#else
|
||||
// First test with NULL index_hash.
|
||||
// This should create a fresh index_hash.
|
||||
lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL);
|
||||
assert_true(index_hash != NULL);
|
||||
|
||||
// Next test with non-NULL index_hash.
|
||||
lzma_index_hash *second_hash = lzma_index_hash_init(index_hash, NULL);
|
||||
|
||||
// It should not create a new index_hash pointer.
|
||||
// Instead it must just re-init the first index_hash.
|
||||
assert_true(index_hash == second_hash);
|
||||
|
||||
lzma_index_hash_end(index_hash, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_lzma_index_hash_append(void)
|
||||
{
|
||||
#ifndef HAVE_DECODERS
|
||||
assert_skip("Decoder support disabled");
|
||||
#else
|
||||
// Test all invalid parameters
|
||||
assert_lzma_ret(lzma_index_hash_append(NULL, 0, 0),
|
||||
LZMA_PROG_ERROR);
|
||||
|
||||
// Test NULL index_hash
|
||||
assert_lzma_ret(lzma_index_hash_append(NULL, UNPADDED_SIZE_MIN,
|
||||
LZMA_VLI_MAX), LZMA_PROG_ERROR);
|
||||
|
||||
// Test with invalid Unpadded Size
|
||||
lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL);
|
||||
assert_true(index_hash != NULL);
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
UNPADDED_SIZE_MIN - 1, LZMA_VLI_MAX),
|
||||
LZMA_PROG_ERROR);
|
||||
|
||||
// Test with invalid Uncompressed Size
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
UNPADDED_SIZE_MIN, LZMA_VLI_MAX + 1),
|
||||
LZMA_PROG_ERROR);
|
||||
|
||||
// First append a Record describing a small Block.
|
||||
// This should succeed.
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
UNPADDED_SIZE_MIN, 1), LZMA_OK);
|
||||
|
||||
// Append another small Record.
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
UNPADDED_SIZE_MIN, 1), LZMA_OK);
|
||||
|
||||
// Append a Record that would cause the compressed size to grow
|
||||
// too big
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
UNPADDED_SIZE_MAX, 1), LZMA_DATA_ERROR);
|
||||
|
||||
lzma_index_hash_end(index_hash, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS)
|
||||
// Fill an index_hash with unpadded and uncompressed VLIs
|
||||
// by calling lzma_index_hash_append
|
||||
static void
|
||||
fill_index_hash(lzma_index_hash *index_hash, const lzma_vli *unpadded_sizes,
|
||||
const lzma_vli *uncomp_sizes, uint32_t block_count)
|
||||
{
|
||||
for (uint32_t i = 0; i < block_count; ++i)
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
unpadded_sizes[i], uncomp_sizes[i]), LZMA_OK);
|
||||
}
|
||||
|
||||
|
||||
// Set the contents of buf to the expected Index based on the
|
||||
// .xz specification. This needs the unpadded and uncompressed VLIs
|
||||
// to correctly create the Index.
|
||||
static void
|
||||
generate_index(uint8_t *buf, const lzma_vli *unpadded_sizes,
|
||||
const lzma_vli *uncomp_sizes, uint32_t block_count,
|
||||
size_t index_max_size)
|
||||
{
|
||||
size_t in_pos = 0;
|
||||
size_t out_pos = 0;
|
||||
|
||||
// First set Index Indicator
|
||||
buf[out_pos++] = INDEX_INDICATOR;
|
||||
|
||||
// Next write out Number of Records
|
||||
assert_lzma_ret(lzma_vli_encode(block_count, &in_pos, buf,
|
||||
&out_pos, index_max_size), LZMA_STREAM_END);
|
||||
|
||||
// Next write out each Record.
|
||||
// A Record consists of Unpadded Size and Uncompressed Size
|
||||
// written next to each other as VLIs.
|
||||
for (uint32_t i = 0; i < block_count; ++i) {
|
||||
in_pos = 0;
|
||||
assert_lzma_ret(lzma_vli_encode(unpadded_sizes[i], &in_pos,
|
||||
buf, &out_pos, index_max_size), LZMA_STREAM_END);
|
||||
in_pos = 0;
|
||||
assert_lzma_ret(lzma_vli_encode(uncomp_sizes[i], &in_pos,
|
||||
buf, &out_pos, index_max_size), LZMA_STREAM_END);
|
||||
}
|
||||
|
||||
// Add Index Padding
|
||||
lzma_vli rounded_out_pos = vli_ceil4(out_pos);
|
||||
memzero(buf + out_pos, rounded_out_pos - out_pos);
|
||||
out_pos = rounded_out_pos;
|
||||
|
||||
// Add the CRC32
|
||||
write32le(buf + out_pos, lzma_crc32(buf, out_pos, 0));
|
||||
out_pos += 4;
|
||||
|
||||
assert_uint_eq(out_pos, index_max_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
test_lzma_index_hash_decode(void)
|
||||
{
|
||||
#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
|
||||
assert_skip("Encoder or decoder support disabled");
|
||||
#else
|
||||
lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL);
|
||||
assert_true(index_hash != NULL);
|
||||
|
||||
size_t in_pos = 0;
|
||||
|
||||
// Six valid values for the Unpadded Size fields in an Index
|
||||
const lzma_vli unpadded_sizes[6] = {
|
||||
UNPADDED_SIZE_MIN,
|
||||
1000,
|
||||
4000,
|
||||
8000,
|
||||
16000,
|
||||
32000
|
||||
};
|
||||
|
||||
// Six valid values for the Uncompressed Size fields in an Index
|
||||
const lzma_vli uncomp_sizes[6] = {
|
||||
1,
|
||||
500,
|
||||
8000,
|
||||
20,
|
||||
1,
|
||||
500
|
||||
};
|
||||
|
||||
// Add two Records to an index_hash
|
||||
fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 2);
|
||||
|
||||
const lzma_vli size_two_records = lzma_index_hash_size(index_hash);
|
||||
assert_uint(size_two_records, >, 0);
|
||||
uint8_t *index_two_records = tuktest_malloc(size_two_records);
|
||||
|
||||
generate_index(index_two_records, unpadded_sizes, uncomp_sizes, 2,
|
||||
size_two_records);
|
||||
|
||||
// First test for basic buffer size error
|
||||
in_pos = size_two_records + 1;
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_two_records, &in_pos,
|
||||
size_two_records), LZMA_BUF_ERROR);
|
||||
|
||||
// Next test for invalid Index Indicator
|
||||
in_pos = 0;
|
||||
index_two_records[0] ^= 1;
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_two_records, &in_pos,
|
||||
size_two_records), LZMA_DATA_ERROR);
|
||||
index_two_records[0] ^= 1;
|
||||
|
||||
// Next verify the index_hash as expected
|
||||
in_pos = 0;
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_two_records, &in_pos,
|
||||
size_two_records), LZMA_STREAM_END);
|
||||
|
||||
// Next test an index_hash with three Records
|
||||
index_hash = lzma_index_hash_init(index_hash, NULL);
|
||||
fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 3);
|
||||
|
||||
const lzma_vli size_three_records = lzma_index_hash_size(
|
||||
index_hash);
|
||||
assert_uint(size_three_records, >, 0);
|
||||
uint8_t *index_three_records = tuktest_malloc(size_three_records);
|
||||
|
||||
generate_index(index_three_records, unpadded_sizes, uncomp_sizes,
|
||||
3, size_three_records);
|
||||
|
||||
in_pos = 0;
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_three_records, &in_pos,
|
||||
size_three_records), LZMA_STREAM_END);
|
||||
|
||||
// Next test an index_hash with five Records
|
||||
index_hash = lzma_index_hash_init(index_hash, NULL);
|
||||
fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 5);
|
||||
|
||||
const lzma_vli size_five_records = lzma_index_hash_size(
|
||||
index_hash);
|
||||
assert_uint(size_five_records, >, 0);
|
||||
uint8_t *index_five_records = tuktest_malloc(size_five_records);
|
||||
|
||||
generate_index(index_five_records, unpadded_sizes, uncomp_sizes, 5,
|
||||
size_five_records);
|
||||
|
||||
// Instead of testing all input at once, give input
|
||||
// one byte at a time
|
||||
in_pos = 0;
|
||||
for (lzma_vli i = 0; i < size_five_records - 1; ++i) {
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_five_records, &in_pos, in_pos + 1),
|
||||
LZMA_OK);
|
||||
}
|
||||
|
||||
// Last byte should return LZMA_STREAM_END
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_five_records, &in_pos,
|
||||
in_pos + 1), LZMA_STREAM_END);
|
||||
|
||||
// Next test if the index_hash is given an incorrect Unpadded
|
||||
// Size. Should detect and report LZMA_DATA_ERROR
|
||||
index_hash = lzma_index_hash_init(index_hash, NULL);
|
||||
fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 5);
|
||||
// The sixth Record will have an invalid Unpadded Size
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
unpadded_sizes[5] + 1,
|
||||
uncomp_sizes[5]), LZMA_OK);
|
||||
|
||||
const lzma_vli size_six_records = lzma_index_hash_size(
|
||||
index_hash);
|
||||
|
||||
assert_uint(size_six_records, >, 0);
|
||||
uint8_t *index_six_records = tuktest_malloc(size_six_records);
|
||||
|
||||
generate_index(index_six_records, unpadded_sizes, uncomp_sizes, 6,
|
||||
size_six_records);
|
||||
in_pos = 0;
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_six_records, &in_pos,
|
||||
size_six_records), LZMA_DATA_ERROR);
|
||||
|
||||
// Next test if the Index is corrupt (invalid CRC32).
|
||||
// Should detect and report LZMA_DATA_ERROR
|
||||
index_hash = lzma_index_hash_init(index_hash, NULL);
|
||||
fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 2);
|
||||
|
||||
index_two_records[size_two_records - 1] ^= 1;
|
||||
|
||||
in_pos = 0;
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_two_records, &in_pos,
|
||||
size_two_records), LZMA_DATA_ERROR);
|
||||
|
||||
// Next test with Index and index_hash struct not matching
|
||||
// a Record
|
||||
index_hash = lzma_index_hash_init(index_hash, NULL);
|
||||
fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 2);
|
||||
// Recalculate Index with invalid Unpadded Size
|
||||
const lzma_vli unpadded_sizes_invalid[2] = {
|
||||
unpadded_sizes[0],
|
||||
unpadded_sizes[1] + 1
|
||||
};
|
||||
|
||||
generate_index(index_two_records, unpadded_sizes_invalid,
|
||||
uncomp_sizes, 2, size_two_records);
|
||||
|
||||
in_pos = 0;
|
||||
assert_lzma_ret(lzma_index_hash_decode(index_hash,
|
||||
index_two_records, &in_pos,
|
||||
size_two_records), LZMA_DATA_ERROR);
|
||||
|
||||
lzma_index_hash_end(index_hash, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_lzma_index_hash_size(void)
|
||||
{
|
||||
#ifndef HAVE_DECODERS
|
||||
assert_skip("Decoder support disabled");
|
||||
#else
|
||||
lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL);
|
||||
assert_true(index_hash != NULL);
|
||||
|
||||
// First test empty index_hash
|
||||
// Expected size should be:
|
||||
// Index Indicator - 1 byte
|
||||
// Number of Records - 1 byte
|
||||
// List of Records - 0 bytes
|
||||
// Index Padding - 2 bytes
|
||||
// CRC32 - 4 bytes
|
||||
// Total - 8 bytes
|
||||
assert_uint_eq(lzma_index_hash_size(index_hash), 8);
|
||||
|
||||
// Append a Record describing a small Block to the index_hash
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
UNPADDED_SIZE_MIN, 1), LZMA_OK);
|
||||
|
||||
// Expected size should be:
|
||||
// Index Indicator - 1 byte
|
||||
// Number of Records - 1 byte
|
||||
// List of Records - 2 bytes
|
||||
// Index Padding - 0 bytes
|
||||
// CRC32 - 4 bytes
|
||||
// Total - 8 bytes
|
||||
lzma_vli expected_size = 8;
|
||||
assert_uint_eq(lzma_index_hash_size(index_hash), expected_size);
|
||||
|
||||
// Append additional small Record
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
UNPADDED_SIZE_MIN, 1), LZMA_OK);
|
||||
|
||||
// Expected size should be:
|
||||
// Index Indicator - 1 byte
|
||||
// Number of Records - 1 byte
|
||||
// List of Records - 4 bytes
|
||||
// Index Padding - 2 bytes
|
||||
// CRC32 - 4 bytes
|
||||
// Total - 12 bytes
|
||||
expected_size = 12;
|
||||
assert_uint_eq(lzma_index_hash_size(index_hash), expected_size);
|
||||
|
||||
// Append a larger Record to the index_hash (3 bytes for each VLI)
|
||||
const lzma_vli three_byte_vli = 0x10000;
|
||||
assert_lzma_ret(lzma_index_hash_append(index_hash,
|
||||
three_byte_vli, three_byte_vli), LZMA_OK);
|
||||
|
||||
// Expected size should be:
|
||||
// Index Indicator - 1 byte
|
||||
// Number of Records - 1 byte
|
||||
// List of Records - 10 bytes
|
||||
// Index Padding - 0 bytes
|
||||
// CRC32 - 4 bytes
|
||||
// Total - 16 bytes
|
||||
expected_size = 16;
|
||||
assert_uint_eq(lzma_index_hash_size(index_hash), expected_size);
|
||||
|
||||
lzma_index_hash_end(index_hash, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
tuktest_start(argc, argv);
|
||||
tuktest_run(test_lzma_index_hash_init);
|
||||
tuktest_run(test_lzma_index_hash_append);
|
||||
tuktest_run(test_lzma_index_hash_decode);
|
||||
tuktest_run(test_lzma_index_hash_size);
|
||||
return tuktest_end();
|
||||
}
|
||||
475
tests/test_lzip_decoder.c
Normal file
475
tests/test_lzip_decoder.c
Normal file
@ -0,0 +1,475 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file test_lzip_decoder.c
|
||||
/// \brief Tests decoding lzip data
|
||||
//
|
||||
// Author: Jia Tan
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#ifdef HAVE_LZIP_DECODER
|
||||
|
||||
// Memlimit large enough to pass all of the test files
|
||||
#define MEMLIMIT (1U << 20)
|
||||
#define DECODE_CHUNK_SIZE 1024
|
||||
|
||||
|
||||
// The uncompressed data in the test files are short US-ASCII strings.
|
||||
// The tests check if the decompressed output is what it is expected to be.
|
||||
// Storing the strings here as text would break the tests on EBCDIC systems
|
||||
// and storing the strings as an array of hex values is inconvenient, so
|
||||
// store the CRC32 values of the expected data instead.
|
||||
//
|
||||
// CRC32 value of "Hello\nWorld\n"
|
||||
static const uint32_t hello_world_crc = 0x15A2A343;
|
||||
|
||||
// CRC32 value of "Trailing garbage\n"
|
||||
static const uint32_t trailing_garbage_crc = 0x87081A60;
|
||||
|
||||
|
||||
// Helper function to decode a good file with no flags and plenty high memlimit
|
||||
static void
|
||||
basic_lzip_decode(const char *src, const uint32_t expected_crc) {
|
||||
size_t file_size;
|
||||
uint8_t *data = tuktest_file_from_srcdir(src, &file_size);
|
||||
uint32_t checksum = 0;
|
||||
|
||||
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);
|
||||
|
||||
strm.next_in = data;
|
||||
strm.next_out = output_buffer;
|
||||
strm.avail_out = DECODE_CHUNK_SIZE;
|
||||
|
||||
// Feed 1 byte at a time to the decoder to look for any bugs
|
||||
// when switching between decoding sequences
|
||||
lzma_ret ret = LZMA_OK;
|
||||
while (ret == LZMA_OK) {
|
||||
strm.avail_in = 1;
|
||||
ret = lzma_code(&strm, LZMA_RUN);
|
||||
if (strm.avail_out == 0) {
|
||||
checksum = lzma_crc32(output_buffer,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
assert_lzma_ret(ret, LZMA_STREAM_END);
|
||||
assert_uint_eq(strm.total_in, file_size);
|
||||
|
||||
checksum = lzma_crc32(output_buffer, strm.next_out - output_buffer,
|
||||
checksum);
|
||||
assert_uint_eq(checksum, expected_crc);
|
||||
|
||||
lzma_end(&strm);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_options(void)
|
||||
{
|
||||
// Test NULL stream
|
||||
assert_lzma_ret(lzma_lzip_decoder(NULL, MEMLIMIT, 0),
|
||||
LZMA_PROG_ERROR);
|
||||
|
||||
// Test invalid flags
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, UINT32_MAX),
|
||||
LZMA_OPTIONS_ERROR);
|
||||
// Memlimit tests are done elsewhere
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_v0_decode(void) {
|
||||
// This tests if liblzma can decode lzip version 0 files.
|
||||
// lzip 1.17 and older can decompress this, but lzip 1.18
|
||||
// and newer can no longer decode these files.
|
||||
basic_lzip_decode("files/good-1-v0.lz", hello_world_crc);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_v1_decode(void) {
|
||||
// This tests decoding a basic lzip v1 file
|
||||
basic_lzip_decode("files/good-1-v1.lz", hello_world_crc);
|
||||
}
|
||||
|
||||
|
||||
// Helper function to decode a good file with trailing bytes after
|
||||
// the lzip stream
|
||||
static void
|
||||
trailing_helper(const char *src, const uint32_t expected_data_checksum,
|
||||
const uint32_t expected_trailing_checksum) {
|
||||
size_t file_size;
|
||||
uint32_t checksum = 0;
|
||||
uint8_t *data = tuktest_file_from_srcdir(src, &file_size);
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT,
|
||||
LZMA_CONCATENATED), LZMA_OK);
|
||||
|
||||
uint8_t *output_buffer = tuktest_malloc(DECODE_CHUNK_SIZE);
|
||||
|
||||
strm.next_in = data;
|
||||
strm.next_out = output_buffer;
|
||||
strm.avail_in = file_size;
|
||||
strm.avail_out = DECODE_CHUNK_SIZE;
|
||||
|
||||
lzma_ret ret = LZMA_OK;
|
||||
while (ret == LZMA_OK) {
|
||||
ret = lzma_code(&strm, LZMA_RUN);
|
||||
if (strm.avail_out == 0) {
|
||||
checksum = lzma_crc32(output_buffer,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
assert_lzma_ret(ret, LZMA_STREAM_END);
|
||||
assert_uint(strm.total_in, <, file_size);
|
||||
|
||||
checksum = lzma_crc32(output_buffer,
|
||||
strm.next_out - output_buffer,
|
||||
checksum);
|
||||
|
||||
assert_uint_eq(checksum, expected_data_checksum);
|
||||
|
||||
// Trailing data should be readable from strm.next_in
|
||||
checksum = lzma_crc32(strm.next_in, strm.avail_in, 0);
|
||||
assert_uint_eq(checksum, expected_trailing_checksum);
|
||||
|
||||
lzma_end(&strm);
|
||||
}
|
||||
|
||||
|
||||
// Helper function to decode a bad file and compare to returned error to
|
||||
// what the caller expects
|
||||
static void
|
||||
decode_expect_error(const char *src, lzma_ret expected_error)
|
||||
{
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
size_t file_size;
|
||||
uint8_t *data = tuktest_file_from_srcdir(src, &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 = data;
|
||||
strm.avail_out = DECODE_CHUNK_SIZE;
|
||||
strm.next_out = output_buffer;
|
||||
|
||||
lzma_ret ret = LZMA_OK;
|
||||
|
||||
while (ret == LZMA_OK) {
|
||||
// Discard output since we are only looking for errors
|
||||
strm.next_out = output_buffer;
|
||||
strm.avail_out = DECODE_CHUNK_SIZE;
|
||||
if (strm.avail_in == 0)
|
||||
ret = lzma_code(&strm, LZMA_FINISH);
|
||||
else
|
||||
ret = lzma_code(&strm, LZMA_RUN);
|
||||
}
|
||||
|
||||
assert_lzma_ret(ret, expected_error);
|
||||
lzma_end(&strm);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_v0_trailing(void) {
|
||||
trailing_helper("files/good-1-v0-trailing-1.lz", hello_world_crc,
|
||||
trailing_garbage_crc);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_v1_trailing(void) {
|
||||
trailing_helper("files/good-1-v1-trailing-1.lz", hello_world_crc,
|
||||
trailing_garbage_crc);
|
||||
|
||||
// The second files/good-1-v1-trailing-2.lz will have the same
|
||||
// expected output and trailing output as
|
||||
// files/good-1-v1-trailing-1.lz, but this tests if the prefix
|
||||
// to the trailing data contains lzip magic bytes.
|
||||
// When this happens, the expected behavior is to silently ignore
|
||||
// the magic byte prefix and consume it from the input file.
|
||||
trailing_helper("files/good-1-v1-trailing-2.lz", hello_world_crc,
|
||||
trailing_garbage_crc);
|
||||
|
||||
// Expect LZMA_BUF error if a file ends with the lzip magic bytes
|
||||
// but does not contain any data after
|
||||
decode_expect_error("files/bad-1-v1-trailing-magic.lz",
|
||||
LZMA_BUF_ERROR);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_concatentated(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);
|
||||
|
||||
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.next_out = output_buffer;
|
||||
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
|
||||
|
||||
assert_uint_eq(strm.total_in, file_size);
|
||||
|
||||
uint32_t checksum = lzma_crc32(output_buffer, strm.total_out, 0);
|
||||
assert_uint_eq(checksum, hello_world_crc);
|
||||
|
||||
// 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);
|
||||
|
||||
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.next_out = output_buffer;
|
||||
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
|
||||
|
||||
assert_uint_eq(strm.total_in, file_size);
|
||||
checksum = lzma_crc32(output_buffer, strm.total_out, 0);
|
||||
assert_uint_eq(checksum, hello_world_crc);
|
||||
|
||||
// The third file contains 2 v1 members
|
||||
uint8_t *v1_v1 = tuktest_file_from_srcdir("files/good-2-v1-v1.lz",
|
||||
&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.next_out = output_buffer;
|
||||
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
|
||||
|
||||
assert_uint_eq(strm.total_in, file_size);
|
||||
checksum = lzma_crc32(output_buffer, strm.total_out, 0);
|
||||
assert_uint_eq(checksum, hello_world_crc);
|
||||
|
||||
lzma_end(&strm);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_crc(void) {
|
||||
// Test invalid checksum
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
size_t file_size;
|
||||
uint8_t *data = tuktest_file_from_srcdir("files/bad-1-v1-crc32.lz",
|
||||
&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 = data;
|
||||
strm.avail_out = DECODE_CHUNK_SIZE;
|
||||
strm.next_out = output_buffer;
|
||||
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_DATA_ERROR);
|
||||
|
||||
// Test ignoring the checksum value - should decode successfully
|
||||
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.next_out = output_buffer;
|
||||
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
|
||||
assert_uint_eq(strm.total_in, file_size);
|
||||
|
||||
// Test tell check
|
||||
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.next_out = output_buffer;
|
||||
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_GET_CHECK);
|
||||
assert_uint_eq(lzma_get_check(&strm), LZMA_CHECK_CRC32);
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_DATA_ERROR);
|
||||
lzma_end(&strm);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_invalid_magic_bytes(void) {
|
||||
uint8_t lzip_id_string[] = { 0x4C, 0x5A, 0x49, 0x50 };
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(lzip_id_string); i++) {
|
||||
// Corrupt magic bytes
|
||||
lzip_id_string[i] ^= 1;
|
||||
uint8_t output_buffer[DECODE_CHUNK_SIZE];
|
||||
|
||||
assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, 0),
|
||||
LZMA_OK);
|
||||
|
||||
strm.next_in = lzip_id_string;
|
||||
strm.avail_in = sizeof(lzip_id_string);
|
||||
strm.next_out = output_buffer;
|
||||
strm.avail_out = DECODE_CHUNK_SIZE;
|
||||
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_RUN),
|
||||
LZMA_FORMAT_ERROR);
|
||||
|
||||
// Reset magic bytes
|
||||
lzip_id_string[i] ^= 1;
|
||||
}
|
||||
|
||||
lzma_end(&strm);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_invalid_version(void)
|
||||
{
|
||||
// The file contains a version number that is not 0 or 1,
|
||||
// so it should cause an error
|
||||
decode_expect_error("files/unsupported-1-v234.lz",
|
||||
LZMA_OPTIONS_ERROR);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_invalid_dictionary_size(void) {
|
||||
// First file has 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
|
||||
decode_expect_error("files/bad-1-v1-dict-2.lz", LZMA_DATA_ERROR);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_invalid_uncomp_size(void) {
|
||||
// Test invalid v0 lzip file uncomp size
|
||||
decode_expect_error("files/bad-1-v0-uncomp-size.lz",
|
||||
LZMA_DATA_ERROR);
|
||||
|
||||
// Test invalid v1 lzip file uncomp size
|
||||
decode_expect_error("files/bad-1-v1-uncomp-size.lz",
|
||||
LZMA_DATA_ERROR);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_invalid_member_size(void) {
|
||||
decode_expect_error("files/bad-1-v1-member-size.lz",
|
||||
LZMA_DATA_ERROR);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_invalid_memlimit(void) {
|
||||
// A very low memlimit should prevent decoding.
|
||||
// Should be able to update the memlimit after failing
|
||||
size_t file_size;
|
||||
uint8_t *data = tuktest_file_from_srcdir("files/good-1-v1.lz",
|
||||
&file_size);
|
||||
|
||||
uint8_t output_buffer[DECODE_CHUNK_SIZE];
|
||||
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
|
||||
assert_lzma_ret(lzma_lzip_decoder(&strm, 1, 0), LZMA_OK);
|
||||
|
||||
strm.next_in = data;
|
||||
strm.avail_in = file_size;
|
||||
strm.next_out = output_buffer;
|
||||
strm.avail_out = DECODE_CHUNK_SIZE;
|
||||
|
||||
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
|
||||
assert_lzma_ret(lzma_memlimit_set(&strm, 100), LZMA_MEMLIMIT_ERROR);
|
||||
assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT), LZMA_OK);
|
||||
|
||||
// Finish decoding
|
||||
assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END);
|
||||
|
||||
assert_uint_eq(strm.total_in, file_size);
|
||||
uint32_t checksum = lzma_crc32(output_buffer, strm.total_out, 0);
|
||||
assert_uint_eq(checksum, hello_world_crc);
|
||||
|
||||
lzma_end(&strm);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
tuktest_start(argc, argv);
|
||||
|
||||
#ifndef HAVE_LZIP_DECODER
|
||||
tuktest_early_skip("lzip decoder disabled");
|
||||
#else
|
||||
tuktest_run(test_options);
|
||||
tuktest_run(test_v0_decode);
|
||||
tuktest_run(test_v1_decode);
|
||||
tuktest_run(test_v0_trailing);
|
||||
tuktest_run(test_v1_trailing);
|
||||
tuktest_run(test_concatentated);
|
||||
tuktest_run(test_crc);
|
||||
tuktest_run(test_invalid_magic_bytes);
|
||||
tuktest_run(test_invalid_version);
|
||||
tuktest_run(test_invalid_dictionary_size);
|
||||
tuktest_run(test_invalid_uncomp_size);
|
||||
tuktest_run(test_invalid_member_size);
|
||||
tuktest_run(test_invalid_memlimit);
|
||||
return tuktest_end();
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
//
|
||||
/// \file tuktest.h
|
||||
/// \brief Helper macros for writing simple test programs
|
||||
/// \version 2022-06-16
|
||||
/// \version 2023-01-08
|
||||
///
|
||||
/// Some inspiration was taken from STest by Keith Nicholas.
|
||||
///
|
||||
@ -349,7 +349,7 @@ static struct tuktest_malloc_record *tuktest_malloc_global = NULL;
|
||||
static void *
|
||||
tuktest_malloc_impl(size_t size, const char *filename, unsigned line)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
void *p = malloc(size == 0 ? 1 : size);
|
||||
struct tuktest_malloc_record *r = malloc(sizeof(*r));
|
||||
|
||||
if (p == NULL || r == NULL) {
|
||||
|
||||
@ -18,7 +18,11 @@ Introduction
|
||||
Building
|
||||
--------
|
||||
|
||||
The following files in this directory are for MSVC:
|
||||
It is recommended to use CMake to generate build files for MSVC.
|
||||
The project files in vs201x directories will be removed in the
|
||||
future (5.4.x releases will include them still).
|
||||
|
||||
Descriptions of the files in the vs201x directories:
|
||||
|
||||
config.h liblzma configuration #defines for MSVC.
|
||||
liblzma.vcxproj This builds static liblzma.
|
||||
@ -34,12 +38,8 @@ Building
|
||||
This means that you may need to either install Windows SDK 8.1 or
|
||||
you may need to set the target platform version before building.
|
||||
|
||||
Currently no test programs are built or run under MSVC.
|
||||
|
||||
MSVC gives a bunch of compiler warnings. Some warnings are specific
|
||||
to 32-bit or 64-bit build and some appear for both builds. These
|
||||
are known and shouldn't be a problem. Some of them will probably
|
||||
be fixed in the future.
|
||||
Currently no test programs are built or run under MSVC from the
|
||||
project files. CMake-based builds include tests too.
|
||||
|
||||
|
||||
Notes
|
||||
@ -49,3 +49,8 @@ Notes
|
||||
by default. To avoid this when using static liblzma from your code,
|
||||
#define LZMA_API_STATIC before #including <lzma.h>.
|
||||
|
||||
MSVC gives a bunch of compiler warnings. Some warnings are specific
|
||||
to 32-bit or 64-bit build and some appear for both builds. These
|
||||
are known and shouldn't be a problem. Some of them will probably
|
||||
be fixed in the future.
|
||||
|
||||
|
||||
@ -248,6 +248,7 @@
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_flags_common.c" />
|
||||
|
||||
@ -280,6 +280,7 @@
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_flags_common.c" />
|
||||
|
||||
@ -248,6 +248,7 @@
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_flags_common.c" />
|
||||
|
||||
@ -280,6 +280,7 @@
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_flags_common.c" />
|
||||
|
||||
@ -249,6 +249,7 @@
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_flags_common.c" />
|
||||
|
||||
@ -281,6 +281,7 @@
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_buffer_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_decoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_encoder_mt.c" />
|
||||
<ClCompile Include="..\..\src\liblzma\common\stream_flags_common.c" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user