1
0
Fork 0

Compare commits

..

10 commits

Author SHA1 Message Date
8bf3699f4d
Releasing debian version 1.5-1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:09:30 +01:00
b444524d2a
Correcting public-domain identifier in copyright.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:09:30 +01:00
bc1883f769
Merging upstream version 1.5.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:09:30 +01:00
ee850f05f4
Releasing debian version 1.4-2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:09:06 +01:00
08e94c68dd
Updating to standards-version 4.7.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:09:06 +01:00
d434fd06d3
Updating years in copyright for 2024.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:09:05 +01:00
fa6ad45523
Releasing debian version 1.4-1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:08:51 +01:00
de24782dab
Disabling testsuite for now as the current upstream release misses some files for it to run at all.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:08:50 +01:00
47b003a45e
Refreshing build.patch.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:08:50 +01:00
5a79dbf791
Merging upstream version 1.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-20 15:08:50 +01:00
19 changed files with 181 additions and 130 deletions

View file

@ -1,12 +1,22 @@
2025-01-02 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.5 released.
* lzd.cc: Reject empty members and nonzero first LZMA byte.
2024-01-02 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.4 released.
* lzd.cc: Use header_size and trailer_size instead of 6 and 20.
2022-10-24 Antonio Diaz Diaz <antonio@gnu.org> 2022-10-24 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.3 released. * Version 1.3 released.
* lzd.cc (Range_decoder): Discard first byte explicitly. * lzd.cc (Range_decoder): Discard first LZMA byte explicitly.
2021-01-04 Antonio Diaz Diaz <antonio@gnu.org> 2021-01-04 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.2 released. * Version 1.2 released.
* lzd.cc (main): Verify also mismatches in member size. * lzd.cc (main): Check also mismatches in member size.
Accept and ignore the option '-d' for compatibility with zutils. Accept and ignore the option '-d' for compatibility with zutils.
Remove warning about "lzd not safe for real work". Remove warning about "lzd not safe for real work".
Print license notice. Print license notice.
@ -23,7 +33,7 @@
* Version 1.0 released. * Version 1.0 released.
* lzd.cc: Minor code improvements. * lzd.cc: Minor code improvements.
* check.sh: A POSIX shell is required to run the tests. * check.sh: Require a POSIX shell.
2016-05-10 Antonio Diaz Diaz <antonio@gnu.org> 2016-05-10 Antonio Diaz Diaz <antonio@gnu.org>
@ -70,8 +80,7 @@
* Version 0.1 released. * Version 0.1 released.
Copyright (C) 2013-2022 Antonio Diaz Diaz. Copyright (C) 2013-2025 Antonio Diaz Diaz.
This file is a collection of facts, and thus it is not copyrightable, This file is a collection of facts, and thus it is not copyrightable, but just
but just in case, you have unlimited permission to copy, distribute, and in case, you have unlimited permission to copy, distribute, and modify it.
modify it.

View file

@ -4,7 +4,8 @@ You will need a C++98 compiler with support for 'long long'.
(gcc 3.3.6 or newer is recommended). (gcc 3.3.6 or newer is recommended).
I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards
compliant compiler. compliant compiler.
Gcc is available at http://gcc.gnu.org. Gcc is available at http://gcc.gnu.org
Lzip is available at http://www.nongnu.org/lzip/lzip.html
Procedure Procedure
@ -31,7 +32,8 @@ extracted from the archive.
4. Optionally, type 'make check' to run the tests that come with lzd. 4. Optionally, type 'make check' to run the tests that come with lzd.
5. Type 'make install' to install the program and any data files and 5. Type 'make install' to install the program and any data files and
documentation. documentation. You need root privileges to install into a prefix owned
by root.
Another way Another way
@ -51,7 +53,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above. explained above.
Copyright (C) 2013-2022 Antonio Diaz Diaz. Copyright (C) 2013-2025 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute, and modify it. distribute, and modify it.

View file

@ -2,8 +2,8 @@
DISTNAME = $(pkgname)-$(pkgversion) DISTNAME = $(pkgname)-$(pkgversion)
INSTALL = install INSTALL = install
INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_PROGRAM = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644
INSTALL_DIR = $(INSTALL) -d -m 755 INSTALL_DIR = $(INSTALL) -d -m 755
INSTALL_DATA = $(INSTALL) -m 644
SHELL = /bin/sh SHELL = /bin/sh
CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1 CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1
@ -24,21 +24,24 @@ $(progname) : $(objs)
%.o : %.cc %.o : %.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROGVERSION=\"$(pkgversion)\" -c -o $@ $< $(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROGVERSION=\"$(pkgversion)\" -c -o $@ $<
$(objs) : Makefile # prevent 'make' from trying to remake source files
$(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ;
MAKEFLAGS += -r
.SUFFIXES :
$(objs) : Makefile
doc : doc :
info : $(VPATH)/doc/$(pkgname).info info : $(VPATH)/doc/$(pkgname).info
$(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi $(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi
cd $(VPATH)/doc && makeinfo $(pkgname).texi cd $(VPATH)/doc && $(MAKEINFO) $(pkgname).texi
man : $(VPATH)/doc/$(progname).1 man : $(VPATH)/doc/$(progname).1
$(VPATH)/doc/$(progname).1 : $(progname) $(VPATH)/doc/$(progname).1 : $(progname)
help2man -n 'educational decompressor for the lzip format' \ help2man -n 'educational decompressor for the lzip format' -o $@ --no-info ./$(progname)
-o $@ --no-info ./$(progname)
Makefile : $(VPATH)/configure $(VPATH)/Makefile.in Makefile : $(VPATH)/configure $(VPATH)/Makefile.in
./config.status ./config.status
@ -105,10 +108,10 @@ dist : doc
$(DISTNAME)/*.cc \ $(DISTNAME)/*.cc \
$(DISTNAME)/testsuite/check.sh \ $(DISTNAME)/testsuite/check.sh \
$(DISTNAME)/testsuite/test.txt \ $(DISTNAME)/testsuite/test.txt \
$(DISTNAME)/testsuite/em.lz \
$(DISTNAME)/testsuite/fox.lz \ $(DISTNAME)/testsuite/fox.lz \
$(DISTNAME)/testsuite/fox_*.lz \ $(DISTNAME)/testsuite/fox_*.lz \
$(DISTNAME)/testsuite/test.txt.lz \ $(DISTNAME)/testsuite/test.txt.lz
$(DISTNAME)/testsuite/test_em.txt.lz
rm -f $(DISTNAME) rm -f $(DISTNAME)
lzip -v -9 $(DISTNAME).tar lzip -v -9 $(DISTNAME).tar

10
NEWS
View file

@ -1,5 +1,7 @@
Changes in version 1.3: Changes in version 1.5:
Lzd now discards the first byte of the LZMA stream explicity (instead of lzd now exits with error status 2 if any empty member is found in a
shifting 1 extra byte in the initialization of 'code') to make the intent multimember file.
clearer.
lzd now exits with error status 2 if the first byte of the LZMA stream is
not 0.

39
README
View file

@ -1,3 +1,5 @@
See the file INSTALL for compilation and installation instructions.
Description Description
Lzd is a simplified decompressor for the lzip format with an educational Lzd is a simplified decompressor for the lzip format with an educational
@ -7,7 +9,7 @@ lzip works. Lzd is written in C++.
The source code of lzd is used in the lzip manual as a reference The source code of lzd is used in the lzip manual as a reference
decompressor in the description of the lzip file format. Reading the lzip decompressor in the description of the lzip file format. Reading the lzip
manual will help you understand the source code. Lzd is compliant with the manual will help you understand the source code. Lzd is compliant with the
lzip specification; it verifies the 3 integrity factors. lzip specification; it checks the 3 integrity factors.
The source code of lzd is also used as a reference in the description of the The source code of lzd is also used as a reference in the description of the
media type 'application/lzip'. media type 'application/lzip'.
@ -18,33 +20,9 @@ ignores) the option '-d' for compatibility with other lzip tools. In
particular, accepting the option '-d' allows lzd to be used as argument to particular, accepting the option '-d' allows lzd to be used as argument to
the option '--lz' of the tools from the zutils package. the option '--lz' of the tools from the zutils package.
Lzd will correctly decompress the concatenation of two or more compressed Lzd correctly decompresses the concatenation of two or more compressed
files. The result is the concatenation of the corresponding decompressed files. The result is the concatenation of the corresponding decompressed
data. Integrity of such concatenated compressed input is also verified. data. Integrity of such concatenated compressed input is also checked.
The lzip file format is designed for data sharing and long-term archiving,
taking into account both data integrity and decoder availability:
* The lzip format provides very safe integrity checking and some data
recovery means. The program lziprecover can repair bit flip errors
(one of the most common forms of data corruption) in lzip files, and
provides data recovery capabilities, including error-checked merging
of damaged copies of a file.
* The lzip format is as simple as possible (but not simpler). The lzip
manual provides the source code of a simple decompressor along with a
detailed explanation of how it works, so that with the only help of the
lzip manual it would be possible for a digital archaeologist to extract
the data from a lzip file long after quantum computers eventually
render LZMA obsolete.
* Additionally the lzip reference implementation is copylefted, which
guarantees that it will remain free forever.
A nice feature of the lzip format is that a corrupt byte is easier to repair
the nearer it is from the beginning of the file. Therefore, with the help of
lziprecover, losing an entire archive just because of a corrupt byte near
the beginning is a thing of the past.
The ideas embodied in lzd are due to (at least) the following people: The ideas embodied in lzd are due to (at least) the following people:
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrei Markov (for the Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrei Markov (for the
@ -52,11 +30,10 @@ definition of Markov chains), G.N.N. Martin (for the definition of range
encoding), and Igor Pavlov (for putting all the above together in LZMA). encoding), and Igor Pavlov (for putting all the above together in LZMA).
Copyright (C) 2013-2022 Antonio Diaz Diaz. Copyright (C) 2013-2025 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute, and modify it. distribute, and modify it.
The file Makefile.in is a data file used by configure to produce the The file Makefile.in is a data file used by configure to produce the Makefile.
Makefile. It has the same copyright owner and permissions that configure It has the same copyright owner and permissions that configure itself.
itself.

21
configure vendored
View file

@ -1,12 +1,12 @@
#! /bin/sh #! /bin/sh
# configure script for Lzd - Educational decompressor for the lzip format # configure script for Lzd - Educational decompressor for the lzip format
# Copyright (C) 2013-2022 Antonio Diaz Diaz. # Copyright (C) 2013-2025 Antonio Diaz Diaz.
# #
# This configure script is free software: you have unlimited permission # This configure script is free software: you have unlimited permission
# to copy, distribute, and modify it. # to copy, distribute, and modify it.
pkgname=lzd pkgname=lzd
pkgversion=1.3 pkgversion=1.5
progname=lzd progname=lzd
srctrigger=lzd.cc srctrigger=lzd.cc
@ -24,6 +24,7 @@ CXX=g++
CPPFLAGS= CPPFLAGS=
CXXFLAGS='-Wall -W -O2' CXXFLAGS='-Wall -W -O2'
LDFLAGS= LDFLAGS=
MAKEINFO=makeinfo
# checking whether we are using GNU C++. # checking whether we are using GNU C++.
/bin/sh -c "${CXX} --version" > /dev/null 2>&1 || { CXX=c++ ; CXXFLAGS=-O2 ; } /bin/sh -c "${CXX} --version" > /dev/null 2>&1 || { CXX=c++ ; CXXFLAGS=-O2 ; }
@ -65,10 +66,11 @@ while [ $# != 0 ] ; do
echo " --infodir=DIR info files directory [${infodir}]" echo " --infodir=DIR info files directory [${infodir}]"
echo " --mandir=DIR man pages directory [${mandir}]" echo " --mandir=DIR man pages directory [${mandir}]"
echo " CXX=COMPILER C++ compiler to use [${CXX}]" echo " CXX=COMPILER C++ compiler to use [${CXX}]"
echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]" echo " CPPFLAGS=OPTIONS command-line options for the preprocessor [${CPPFLAGS}]"
echo " CXXFLAGS=OPTIONS command line options for the C++ compiler [${CXXFLAGS}]" echo " CXXFLAGS=OPTIONS command-line options for the C++ compiler [${CXXFLAGS}]"
echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS" echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS"
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]" echo " LDFLAGS=OPTIONS command-line options for the linker [${LDFLAGS}]"
echo " MAKEINFO=NAME makeinfo program to use [${MAKEINFO}]"
echo echo
exit 0 ;; exit 0 ;;
--version | -V) --version | -V)
@ -96,6 +98,7 @@ while [ $# != 0 ] ; do
CXXFLAGS=*) CXXFLAGS=${optarg} ;; CXXFLAGS=*) CXXFLAGS=${optarg} ;;
CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;; CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;;
LDFLAGS=*) LDFLAGS=${optarg} ;; LDFLAGS=*) LDFLAGS=${optarg} ;;
MAKEINFO=*) MAKEINFO=${optarg} ;;
--*) --*)
echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;; echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;;
@ -106,7 +109,7 @@ while [ $# != 0 ] ; do
exit 1 ;; exit 1 ;;
esac esac
# Check if the option took a separate argument # Check whether the option took a separate argument
if [ "${arg2}" = yes ] ; then if [ "${arg2}" = yes ] ; then
if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift
else echo "configure: Missing argument to '${option}'" 1>&2 else echo "configure: Missing argument to '${option}'" 1>&2
@ -147,7 +150,7 @@ if [ -z "${no_create}" ] ; then
# This script is free software: you have unlimited permission # This script is free software: you have unlimited permission
# to copy, distribute, and modify it. # to copy, distribute, and modify it.
exec /bin/sh $0 ${args} --no-create exec /bin/sh "$0" ${args} --no-create
EOF EOF
chmod +x config.status chmod +x config.status
fi fi
@ -164,10 +167,11 @@ echo "CXX = ${CXX}"
echo "CPPFLAGS = ${CPPFLAGS}" echo "CPPFLAGS = ${CPPFLAGS}"
echo "CXXFLAGS = ${CXXFLAGS}" echo "CXXFLAGS = ${CXXFLAGS}"
echo "LDFLAGS = ${LDFLAGS}" echo "LDFLAGS = ${LDFLAGS}"
echo "MAKEINFO = ${MAKEINFO}"
rm -f Makefile rm -f Makefile
cat > Makefile << EOF cat > Makefile << EOF
# Makefile for Lzd - Educational decompressor for the lzip format # Makefile for Lzd - Educational decompressor for the lzip format
# Copyright (C) 2013-2022 Antonio Diaz Diaz. # Copyright (C) 2013-2025 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit. # This file was generated automatically by configure. Don't edit.
# #
# This Makefile is free software: you have unlimited permission # This Makefile is free software: you have unlimited permission
@ -187,6 +191,7 @@ CXX = ${CXX}
CPPFLAGS = ${CPPFLAGS} CPPFLAGS = ${CPPFLAGS}
CXXFLAGS = ${CXXFLAGS} CXXFLAGS = ${CXXFLAGS}
LDFLAGS = ${LDFLAGS} LDFLAGS = ${LDFLAGS}
MAKEINFO = ${MAKEINFO}
EOF EOF
cat "${srcdir}/Makefile.in" >> Makefile cat "${srcdir}/Makefile.in" >> Makefile

26
debian/changelog vendored
View file

@ -1,3 +1,29 @@
lzd (1.5-1) sid; urgency=medium
* Uploading to sid.
* Merging upstream version 1.5.
* Correcting public-domain identifier in copyright.
-- Daniel Baumann <daniel.baumann@progress-linux.org> Tue, 14 Jan 2025 11:09:08 +0100
lzd (1.4-2) sid; urgency=medium
* Uploading to sid.
* Updating years in copyright for 2024.
* Updating to standards-version 4.7.0.
-- Daniel Baumann <daniel.baumann@progress-linux.org> Thu, 25 Jul 2024 06:37:01 +0200
lzd (1.4-1) sid; urgency=medium
* Uploading to sid.
* Merging upstream version 1.4.
* Refreshing build.patch.
* Disabling testsuite for now as the current upstream release misses
some files for it to run at all.
-- Daniel Baumann <daniel.baumann@progress-linux.org> Tue, 23 Jan 2024 06:17:15 +0100
lzd (1.3-2) sid; urgency=medium lzd (1.3-2) sid; urgency=medium
* Uploading to sid. * Uploading to sid.

2
debian/control vendored
View file

@ -5,7 +5,7 @@ Maintainer: Daniel Baumann <daniel.baumann@progress-linux.org>
Build-Depends: Build-Depends:
debhelper-compat (= 13), debhelper-compat (= 13),
Rules-Requires-Root: no Rules-Requires-Root: no
Standards-Version: 4.6.2 Standards-Version: 4.7.0
Homepage: http://www.nongnu.org/lzip/lzd.html Homepage: http://www.nongnu.org/lzip/lzd.html
Vcs-Browser: https://git.progress-linux.org/users/daniel.baumann/debian/packages/lzd Vcs-Browser: https://git.progress-linux.org/users/daniel.baumann/debian/packages/lzd
Vcs-Git: https://git.progress-linux.org/users/daniel.baumann/debian/packages/lzd Vcs-Git: https://git.progress-linux.org/users/daniel.baumann/debian/packages/lzd

10
debian/copyright vendored
View file

@ -4,14 +4,14 @@ Upstream-Contact: lzip-bug@nongnu.org
Source: https://download.savannah.gnu.org/releases/lzip/ Source: https://download.savannah.gnu.org/releases/lzip/
Files: * Files: *
Copyright: 2013-2022 Antonio Diaz Diaz <ant_diaz@teleline.es> Copyright: 2013-2024 Antonio Diaz Diaz <ant_diaz@teleline.es>
License: PD License: public-domain
Files: debian/* Files: debian/*
Copyright: 2013-2022 Daniel Baumann <daniel.baumann@progress-linux.org> Copyright: 2013-2024 Daniel Baumann <daniel.baumann@progress-linux.org>
License: PD License: public-domain
License: PD License: public-domain
This program is free software: you have unlimited permission This program is free software: you have unlimited permission
to copy, distribute and modify it. to copy, distribute and modify it.
. .

View file

@ -4,16 +4,18 @@ Description: Avoid overwriting build-environment.
diff -Naurp lzd.orig/configure lzd/configure diff -Naurp lzd.orig/configure lzd/configure
--- lzd.orig/configure --- lzd.orig/configure
+++ lzd/configure +++ lzd/configure
@@ -21,9 +21,9 @@ datarootdir='$(prefix)/share' @@ -20,10 +20,10 @@ bindir='$(exec_prefix)/bin'
datarootdir='$(prefix)/share'
infodir='$(datarootdir)/info' infodir='$(datarootdir)/info'
mandir='$(datarootdir)/man' mandir='$(datarootdir)/man'
CXX=g++ -CXX=g++
-CPPFLAGS= -CPPFLAGS=
-CXXFLAGS='-Wall -W -O2' -CXXFLAGS='-Wall -W -O2'
-LDFLAGS= -LDFLAGS=
+#CXX=g++
+#CPPFLAGS= +#CPPFLAGS=
+#CXXFLAGS='-Wall -W -O2' +#CXXFLAGS='-Wall -W -O2'
+#LDFLAGS= +#LDFLAGS=
MAKEINFO=makeinfo
# checking whether we are using GNU C++. # checking whether we are using GNU C++.
/bin/sh -c "${CXX} --version" > /dev/null 2>&1 || { CXX=c++ ; CXXFLAGS=-O2 ; }

3
debian/rules vendored
View file

@ -10,3 +10,6 @@ override_dh_auto_configure:
override_dh_auto_install: override_dh_auto_install:
dh_auto_install -- DESTDIR=$(CURDIR)/debian/lzd dh_auto_install -- DESTDIR=$(CURDIR)/debian/lzd
override_dh_auto_test:
# disabled: incomplete upstream testsuite

73
lzd.cc
View file

@ -1,5 +1,5 @@
/* Lzd - Educational decompressor for the lzip format /* Lzd - Educational decompressor for the lzip format
Copyright (C) 2013-2022 Antonio Diaz Diaz. Copyright (C) 2013-2025 Antonio Diaz Diaz.
This program is free software. Redistribution and use in source and This program is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided binary forms, with or without modification, are permitted provided
@ -18,7 +18,7 @@
*/ */
/* /*
Exit status: 0 for a normal exit, 1 for environmental problems Exit status: 0 for a normal exit, 1 for environmental problems
(file not found, invalid command line options, I/O errors, etc), 2 to (file not found, invalid command-line options, I/O errors, etc), 2 to
indicate a corrupt or invalid input file. indicate a corrupt or invalid input file.
*/ */
@ -130,10 +130,11 @@ public:
const CRC32 crc32; const CRC32 crc32;
typedef uint8_t Lzip_header[6]; // 0-3 magic bytes enum { header_size = 6, trailer_size = 20 };
// 4 version typedef uint8_t Lzip_header[header_size]; // 0-3 magic bytes
// 5 coded dictionary size // 4 version
typedef uint8_t Lzip_trailer[20]; // 5 coded dictionary size
typedef uint8_t Lzip_trailer[trailer_size];
// 0-3 CRC32 of the uncompressed data // 0-3 CRC32 of the uncompressed data
// 4-11 size of the uncompressed data // 4-11 size of the uncompressed data
// 12-19 member size including header and trailer // 12-19 member size including header and trailer
@ -145,9 +146,11 @@ class Range_decoder
uint32_t range; uint32_t range;
public: public:
Range_decoder() : member_pos( 6 ), code( 0 ), range( 0xFFFFFFFFU ) Range_decoder()
: member_pos( header_size ), code( 0 ), range( 0xFFFFFFFFU )
{ {
get_byte(); // discard first byte of the LZMA stream if( get_byte() != 0 ) // check first LZMA byte
{ std::fputs( "Nonzero first LZMA byte.\n", stderr ); std::exit( 2 ); }
for( int i = 0; i < 4; ++i ) code = ( code << 8 ) | get_byte(); for( int i = 0; i < 4; ++i ) code = ( code << 8 ) | get_byte();
} }
@ -168,9 +171,9 @@ public:
return symbol; return symbol;
} }
unsigned decode_bit( Bit_model & bm ) bool decode_bit( Bit_model & bm )
{ {
unsigned symbol; bool symbol;
const uint32_t bound = ( range >> bit_model_total_bits ) * bm.probability; const uint32_t bound = ( range >> bit_model_total_bits ) * bm.probability;
if( code < bound ) if( code < bound )
{ {
@ -216,8 +219,8 @@ public:
unsigned symbol = 1; unsigned symbol = 1;
for( int i = 7; i >= 0; --i ) for( int i = 7; i >= 0; --i )
{ {
const unsigned match_bit = ( match_byte >> i ) & 1; const bool match_bit = ( match_byte >> i ) & 1;
const unsigned bit = decode_bit( bm[symbol+(match_bit<<8)+0x100] ); const bool bit = decode_bit( bm[symbol+(match_bit<<8)+0x100] );
symbol = ( symbol << 1 ) | bit; symbol = ( symbol << 1 ) | bit;
if( match_bit != bit ) if( match_bit != bit )
{ {
@ -232,11 +235,12 @@ public:
unsigned decode_len( Len_model & lm, const int pos_state ) unsigned decode_len( Len_model & lm, const int pos_state )
{ {
if( decode_bit( lm.choice1 ) == 0 ) if( decode_bit( lm.choice1 ) == 0 )
return decode_tree( lm.bm_low[pos_state], len_low_bits ); return min_match_len +
decode_tree( lm.bm_low[pos_state], len_low_bits );
if( decode_bit( lm.choice2 ) == 0 ) if( decode_bit( lm.choice2 ) == 0 )
return len_low_symbols + return min_match_len + len_low_symbols +
decode_tree( lm.bm_mid[pos_state], len_mid_bits ); decode_tree( lm.bm_mid[pos_state], len_mid_bits );
return len_low_symbols + len_mid_symbols + return min_match_len + len_low_symbols + len_mid_symbols +
decode_tree( lm.bm_high, len_high_bits ); decode_tree( lm.bm_high, len_high_bits );
} }
}; };
@ -371,12 +375,12 @@ bool LZ_decoder::decode_member() // Return false if error
rep0 = distance; rep0 = distance;
} }
state.set_rep(); state.set_rep();
len = min_match_len + rdec.decode_len( rep_len_model, pos_state ); len = rdec.decode_len( rep_len_model, pos_state );
} }
else // match else // match
{ {
rep3 = rep2; rep2 = rep1; rep1 = rep0; rep3 = rep2; rep2 = rep1; rep1 = rep0;
len = min_match_len + rdec.decode_len( match_len_model, pos_state ); len = rdec.decode_len( match_len_model, pos_state );
const int len_state = std::min( len - min_match_len, len_states - 1 ); const int len_state = std::min( len - min_match_len, len_states - 1 );
rep0 = rdec.decode_tree( bm_dis_slot[len_state], dis_slot_bits ); rep0 = rdec.decode_tree( bm_dis_slot[len_state], dis_slot_bits );
if( rep0 >= start_dis_model ) if( rep0 >= start_dis_model )
@ -389,13 +393,12 @@ bool LZ_decoder::decode_member() // Return false if error
direct_bits ); direct_bits );
else else
{ {
rep0 += rep0 += rdec.decode( direct_bits-dis_align_bits ) << dis_align_bits;
rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits;
rep0 += rdec.decode_tree_reversed( bm_align, dis_align_bits ); rep0 += rdec.decode_tree_reversed( bm_align, dis_align_bits );
if( rep0 == 0xFFFFFFFFU ) // marker found if( rep0 == 0xFFFFFFFFU ) // marker found
{ {
flush_data(); flush_data();
return ( len == min_match_len ); // End Of Stream marker return len == min_match_len; // End Of Stream marker
} }
} }
} }
@ -420,10 +423,10 @@ int main( const int argc, const char * const argv[] )
"See the lzip manual for an explanation of the code.\n" "See the lzip manual for an explanation of the code.\n"
"\nUsage: %s [-d] < file.lz > file\n" "\nUsage: %s [-d] < file.lz > file\n"
"Lzd decompresses from standard input to standard output.\n" "Lzd decompresses from standard input to standard output.\n"
"\nCopyright (C) 2022 Antonio Diaz Diaz.\n" "\nCopyright (C) 2025 Antonio Diaz Diaz.\n"
"License 2-clause BSD.\n" "License 2-clause BSD.\n"
"This is free software: you are free to change and redistribute it.\n" "This is free software: you are free to change and redistribute "
"There is NO WARRANTY, to the extent permitted by law.\n" "it.\nThere is NO WARRANTY, to the extent permitted by law.\n"
"Report bugs to lzip-bug@nongnu.org\n" "Report bugs to lzip-bug@nongnu.org\n"
"Lzd home page: http://www.nongnu.org/lzip/lzd.html\n", "Lzd home page: http://www.nongnu.org/lzip/lzd.html\n",
PROGVERSION, argv[0] ); PROGVERSION, argv[0] );
@ -435,10 +438,11 @@ int main( const int argc, const char * const argv[] )
setmode( STDOUT_FILENO, O_BINARY ); setmode( STDOUT_FILENO, O_BINARY );
#endif #endif
bool empty = false, multi = false;
for( bool first_member = true; ; first_member = false ) for( bool first_member = true; ; first_member = false )
{ {
Lzip_header header; // verify header Lzip_header header; // check header
for( int i = 0; i < 6; ++i ) header[i] = std::getc( stdin ); for( int i = 0; i < header_size; ++i ) header[i] = std::getc( stdin );
if( std::feof( stdin ) || std::memcmp( header, "LZIP\x01", 5 ) != 0 ) if( std::feof( stdin ) || std::memcmp( header, "LZIP\x01", 5 ) != 0 )
{ {
if( first_member ) if( first_member )
@ -449,37 +453,40 @@ int main( const int argc, const char * const argv[] )
unsigned dict_size = 1 << ( header[5] & 0x1F ); unsigned dict_size = 1 << ( header[5] & 0x1F );
dict_size -= ( dict_size / 16 ) * ( ( header[5] >> 5 ) & 7 ); dict_size -= ( dict_size / 16 ) * ( ( header[5] >> 5 ) & 7 );
if( dict_size < min_dictionary_size || dict_size > max_dictionary_size ) if( dict_size < min_dictionary_size || dict_size > max_dictionary_size )
{ std::fputs( "Invalid dictionary size in member header.\n", stderr ); { std::fputs( "Invalid dictionary size in member header.\n",
return 2; } stderr ); return 2; }
LZ_decoder decoder( dict_size ); // decode LZMA stream LZ_decoder decoder( dict_size ); // decode LZMA stream
if( !decoder.decode_member() ) if( !decoder.decode_member() )
{ std::fputs( "Data error\n", stderr ); return 2; } { std::fputs( "Data error.\n", stderr ); return 2; }
Lzip_trailer trailer; // verify trailer Lzip_trailer trailer; // check trailer
for( int i = 0; i < 20; ++i ) trailer[i] = decoder.get_byte(); for( int i = 0; i < trailer_size; ++i ) trailer[i] = decoder.get_byte();
int retval = 0; int retval = 0;
unsigned crc = 0; unsigned crc = 0;
for( int i = 3; i >= 0; --i ) crc = ( crc << 8 ) + trailer[i]; for( int i = 3; i >= 0; --i ) crc = ( crc << 8 ) + trailer[i];
if( crc != decoder.crc() ) if( crc != decoder.crc() )
{ std::fputs( "CRC mismatch\n", stderr ); retval = 2; } { std::fputs( "CRC mismatch.\n", stderr ); retval = 2; }
unsigned long long data_size = 0; unsigned long long data_size = 0;
for( int i = 11; i >= 4; --i ) for( int i = 11; i >= 4; --i )
data_size = ( data_size << 8 ) + trailer[i]; data_size = ( data_size << 8 ) + trailer[i];
if( data_size != decoder.data_position() ) if( data_size != decoder.data_position() )
{ std::fputs( "Data size mismatch\n", stderr ); retval = 2; } { std::fputs( "Data size mismatch.\n", stderr ); retval = 2; }
multi = !first_member; if( data_size == 0 ) empty = true;
unsigned long long member_size = 0; unsigned long long member_size = 0;
for( int i = 19; i >= 12; --i ) for( int i = 19; i >= 12; --i )
member_size = ( member_size << 8 ) + trailer[i]; member_size = ( member_size << 8 ) + trailer[i];
if( member_size != decoder.member_position() ) if( member_size != decoder.member_position() )
{ std::fputs( "Member size mismatch\n", stderr ); retval = 2; } { std::fputs( "Member size mismatch.\n", stderr ); retval = 2; }
if( retval ) return retval; if( retval ) return retval;
} }
if( std::fclose( stdout ) != 0 ) if( std::fclose( stdout ) != 0 )
{ std::fprintf( stderr, "Error closing stdout: %s\n", { std::fprintf( stderr, "Error closing stdout: %s\n",
std::strerror( errno ) ); return 1; } std::strerror( errno ) ); return 1; }
if( empty && multi )
{ std::fputs( "Empty member not allowed.\n", stderr ); return 2; }
return 0; return 0;
} }

View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# check script for Lzd - Educational decompressor for the lzip format # check script for Lzd - Educational decompressor for the lzip format
# Copyright (C) 2013-2022 Antonio Diaz Diaz. # Copyright (C) 2013-2025 Antonio Diaz Diaz.
# #
# This script is free software: you have unlimited permission # This script is free software: you have unlimited permission
# to copy, distribute, and modify it. # to copy, distribute, and modify it.
@ -30,8 +30,9 @@ cd "${objdir}"/tmp || framework_failure
in="${testdir}"/test.txt in="${testdir}"/test.txt
in_lz="${testdir}"/test.txt.lz in_lz="${testdir}"/test.txt.lz
in_em="${testdir}"/test_em.txt.lz em_lz="${testdir}"/em.lz
fox_lz="${testdir}"/fox.lz fox_lz="${testdir}"/fox.lz
fnz_lz="${testdir}"/fox_nz.lz
fail=0 fail=0
test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; } test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
@ -40,25 +41,41 @@ printf "testing lzd-%s..." "$2"
"${LZIP}" < "${in}" 2> /dev/null "${LZIP}" < "${in}" 2> /dev/null
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
for i in "${in_lz}" "${in_em}" ; do "${LZIP}" < "${in_lz}" > out || test_failed $LINENO
"${LZIP}" < "$i" > copy || test_failed $LINENO "$i" cmp "${in}" out || test_failed $LINENO
cmp "${in}" copy || test_failed $LINENO "$i"
done
cat "${in}" "${in}" > in2 || framework_failure cat "${in}" "${in}" > in2 || framework_failure
cat "${in_lz}" "${in_lz}" | "${LZIP}" > copy2 || test_failed $LINENO cat "${in_lz}" "${in_lz}" | "${LZIP}" > out2 || test_failed $LINENO
cmp in2 copy2 || test_failed $LINENO cmp in2 out2 || test_failed $LINENO
rm -f copy2 || framework_failure rm -f out2 || framework_failure
cat "${in_lz}" "${in_lz}" > copy2.lz || framework_failure cat "${in_lz}" "${in_lz}" > out2.lz || framework_failure
printf "\ngarbage" >> copy2.lz || framework_failure printf "\ngarbage" >> out2.lz || framework_failure
"${LZIP}" -d < copy2.lz > copy2 || test_failed $LINENO "${LZIP}" -d < out2.lz > out2 || test_failed $LINENO
cmp in2 copy2 || test_failed $LINENO cmp in2 out2 || test_failed $LINENO
rm -f in2 copy2 copy2.lz || framework_failure rm -f in2 out2 out2.lz || framework_failure
touch empty || framework_failure
"${LZIP}" -d < "${em_lz}" > em || test_failed $LINENO
cmp empty em || test_failed $LINENO
printf "\ntesting bad input..." printf "\ntesting bad input..."
for i in fox_bm.lz fox_v2.lz fox_s11.lz fox_de20.lz \ cat "${em_lz}" "${em_lz}" | "${LZIP}" -d > em 2> /dev/null
[ $? = 2 ] || test_failed $LINENO
cmp empty em || test_failed $LINENO
rm -f empty em || framework_failure
cat "${em_lz}" "${in_lz}" | "${LZIP}" -d > out 2> /dev/null
[ $? = 2 ] || test_failed $LINENO
cmp "${in}" out || test_failed $LINENO
cat "${in_lz}" "${em_lz}" | "${LZIP}" -d > out 2> /dev/null
[ $? = 2 ] || test_failed $LINENO
cmp "${in}" out || test_failed $LINENO
"${LZIP}" < "${fnz_lz}" 2> /dev/null
[ $? = 2 ] || test_failed $LINENO
for i in fox_v2.lz fox_s11.lz fox_de20.lz \
fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
"${LZIP}" < "${testdir}"/$i > /dev/null 2>&1 "${LZIP}" < "${testdir}"/$i > /dev/null 2>&1
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
@ -70,29 +87,29 @@ for i in fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
cmp fox out || test_failed $LINENO $i cmp fox out || test_failed $LINENO $i
done done
rm -f fox out || framework_failure rm -f fox || framework_failure
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure
cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure
if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null && if dd if=in3.lz of=trunc.lz bs=14682 count=1 2> /dev/null &&
[ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then [ -e trunc.lz ] && cmp in2.lz trunc.lz ; then
# can't detect truncated header of non-first member # can't detect truncated header of non-first member
for i in 6 20 14734 14758 ; do for i in 6 20 14664 14688 ; do
dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null
"${LZIP}" < trunc.lz > /dev/null 2>&1 "${LZIP}" < trunc.lz > /dev/null 2>&1
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
done done
else else
printf "\nwarning: skipping truncation test: 'dd' does not work on your system." printf "warning: skipping truncation test: 'dd' does not work on your system."
fi fi
rm -f in2.lz in3.lz trunc.lz || framework_failure rm -f in2.lz in3.lz trunc.lz || framework_failure
cat "${in_lz}" > ingin.lz || framework_failure cp "${in_lz}" ingin.lz || framework_failure
printf "g" >> ingin.lz || framework_failure printf "g" >> ingin.lz || framework_failure
cat "${in_lz}" >> ingin.lz || framework_failure cat "${in_lz}" >> ingin.lz || framework_failure
"${LZIP}" -d < ingin.lz > copy || test_failed $LINENO "${LZIP}" -d < ingin.lz > out || test_failed $LINENO
cmp "${in}" copy || test_failed $LINENO cmp "${in}" out || test_failed $LINENO
rm -f copy ingin.lz || framework_failure rm -f out ingin.lz || framework_failure
echo echo
if [ ${fail} = 0 ] ; then if [ ${fail} = 0 ] ; then

BIN
testsuite/em.lz Normal file

Binary file not shown.

Binary file not shown.

BIN
testsuite/fox_nz.lz Normal file

Binary file not shown.

View file

@ -1,8 +1,7 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -339,8 +338,7 @@ Public License instead of this License.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.

Binary file not shown.

Binary file not shown.