summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-01-25 13:41:02 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-01-25 13:41:02 +0000
commit45916b8c0bea9a451cf62116581ea253659dbea6 (patch)
tree6a17a4653d30f14f75a92a2a5dde67426ed35e87
parentAdding upstream version 1.1. (diff)
downloadlzd-45916b8c0bea9a451cf62116581ea253659dbea6.tar.xz
lzd-45916b8c0bea9a451cf62116581ea253659dbea6.zip
Adding upstream version 1.2.upstream/1.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--AUTHORS7
-rw-r--r--COPYING26
-rw-r--r--ChangeLog21
-rw-r--r--INSTALL14
-rw-r--r--Makefile.in9
-rw-r--r--NEWS18
-rw-r--r--README66
-rwxr-xr-xconfigure25
-rw-r--r--lzd.cc129
-rwxr-xr-xtestsuite/check.sh32
-rw-r--r--testsuite/fox.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_bcrc.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_bm.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_crc0.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_das46.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_de20.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_mes81.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_s11.lzbin0 -> 80 bytes
-rw-r--r--testsuite/fox_v2.lzbin0 -> 80 bytes
-rw-r--r--testsuite/test_em.txt.lzbin0 -> 14024 bytes
20 files changed, 208 insertions, 139 deletions
diff --git a/AUTHORS b/AUTHORS
index a7b5945..27ceba5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,7 +1,6 @@
Lzd was written by Antonio Diaz Diaz.
The ideas embodied in lzd are due to (at least) the following people:
-Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for
-the 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).
+Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
+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).
diff --git a/COPYING b/COPYING
index 5b9d8b9..0105f19 100644
--- a/COPYING
+++ b/COPYING
@@ -1,17 +1,17 @@
- Lzd - Educational decompressor for the lzip format
- Copyright (C) Antonio Diaz Diaz.
+ Lzd - Educational decompressor for the lzip format
+ Copyright (C) Antonio Diaz Diaz.
- This program is free software. Redistribution and use in source and
- binary forms, with or without modification, are permitted provided
- that the following conditions are met:
+ This program is free software. Redistribution and use in source and
+ binary forms, with or without modification, are permitted provided
+ that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/ChangeLog b/ChangeLog
index eae5639..b17c9db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,16 @@
+2021-01-04 Antonio Diaz Diaz <antonio@gnu.org>
+
+ * Version 1.2 released.
+ * lzd.cc (main): Verify also mismatches in member size.
+ Accept and ignore the option '-d' for compatibility with zutils.
+ Remove warning about "lzd not safe for real work".
+ Print license notice.
+ * testsuite: Add 10 new test files.
+
2019-01-11 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.1 released.
- * File_* renamed to Lzip_*.
+ * Rename File_* to Lzip_*.
* lzd.cc: Compile on DOS with DJGPP.
* configure: Accept appending to CXXFLAGS, 'CXXFLAGS+=OPTIONS'.
@@ -19,7 +28,7 @@
2016-01-23 Antonio Diaz Diaz <antonio@gnu.org>
* Version 0.8 released.
- * Documented that lzip does not use 'literal_pos_state_bits'.
+ * Document that lzip does not use 'literal_pos_state_bits'.
2015-07-07 Antonio Diaz Diaz <antonio@gnu.org>
@@ -39,7 +48,7 @@
2013-08-01 Antonio Diaz Diaz <antonio@gnu.org>
* Version 0.4 released.
- * check.sh: Removed '/dev/full' from tests.
+ * check.sh: Remove '/dev/full' from tests.
2013-07-24 Antonio Diaz Diaz <antonio@gnu.org>
@@ -49,15 +58,15 @@
2013-05-06 Antonio Diaz Diaz <antonio@gnu.org>
* Version 0.2 released.
- * main.c: Added a missing '#include' for OS/2.
+ * main.c: Add a missing '#include' for OS/2.
2013-03-21 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 0.1 released.
-Copyright (C) 2013-2019 Antonio Diaz Diaz.
+Copyright (C) 2013-2021 Antonio Diaz Diaz.
This file is a collection of facts, and thus it is not copyrightable,
-but just in case, you have unlimited permission to copy, distribute and
+but just in case, you have unlimited permission to copy, distribute, and
modify it.
diff --git a/INSTALL b/INSTALL
index 55b2603..f2a5025 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
Requirements
------------
-You will need a C++ compiler.
-I use gcc 5.3.0 and 4.1.2, but the code should compile with any standards
+You will need a C++11 compiler. (gcc 3.3.6 or newer is recommended).
+I use gcc 6.1.0 and 4.1.2, but the code should compile with any standards
compliant compiler.
Gcc is available at http://gcc.gnu.org.
@@ -36,10 +36,10 @@ the main archive.
Another way
-----------
You can also compile lzd into a separate directory.
-To do this, you must use a version of 'make' that supports the 'VPATH'
-variable, such as GNU 'make'. 'cd' to the directory where you want the
+To do this, you must use a version of 'make' that supports the variable
+'VPATH', such as GNU 'make'. 'cd' to the directory where you want the
object files and executables to go and run the 'configure' script.
-'configure' automatically checks for the source code in '.', in '..' and
+'configure' automatically checks for the source code in '.', in '..', and
in the directory that 'configure' is in.
'configure' recognizes the option '--srcdir=DIR' to control where to
@@ -50,7 +50,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above.
-Copyright (C) 2013-2019 Antonio Diaz Diaz.
+Copyright (C) 2013-2021 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
-distribute and modify it.
+distribute, and modify it.
diff --git a/Makefile.in b/Makefile.in
index 471ff4b..b2f6d55 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -63,7 +63,7 @@ install-info :
-rm -f "$(DESTDIR)$(infodir)/$(pkgname).info"*
$(INSTALL_DATA) $(VPATH)/doc/$(pkgname).info "$(DESTDIR)$(infodir)/$(pkgname).info"
-if $(CAN_RUN_INSTALLINFO) ; then \
- install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$(pkgname).info" ; \
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$(pkgname).info" ; \
fi
install-info-compress : install-info
@@ -84,7 +84,7 @@ uninstall-bin :
uninstall-info :
-if $(CAN_RUN_INSTALLINFO) ; then \
- install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$(pkgname).info" ; \
+ install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$(pkgname).info" ; \
fi
-rm -f "$(DESTDIR)$(infodir)/$(pkgname).info"*
@@ -105,7 +105,10 @@ dist : doc
$(DISTNAME)/*.cc \
$(DISTNAME)/testsuite/check.sh \
$(DISTNAME)/testsuite/test.txt \
- $(DISTNAME)/testsuite/test.txt.lz
+ $(DISTNAME)/testsuite/fox.lz \
+ $(DISTNAME)/testsuite/fox_*.lz \
+ $(DISTNAME)/testsuite/test.txt.lz \
+ $(DISTNAME)/testsuite/test_em.txt.lz
rm -f $(DISTNAME)
lzip -v -9 $(DISTNAME).tar
diff --git a/NEWS b/NEWS
index b22edc2..f1893b8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,16 @@
-Changes in version 1.1:
+Changes in version 1.2:
-All 'File_*' identifiers have been renamed to 'Lzip_*'.
+Mismatches in member size are now verified. Lzd is now compliant with the
+lzip specification; it verifies the 3 integrity factors.
-Lzd now should compile on DOS with DJGPP.
+Lzd now accepts (and ignores) the option '-d'. This allows it to be used as
+argument to the option '--lz' of the tools from the zutils package.
-The configure script now accepts appending options to CXXFLAGS using the
-syntax 'CXXFLAGS+=OPTIONS'.
+The warning about "lzd not safe for real work" has been removed.
+(Lzd is safe, just not very convenient to use).
+
+10 new test files have been added to the testsuite.
+
+The source code of lzd is now used as a reference in the description of the
+media type 'application/lzip'.
+See http://datatracker.ietf.org/doc/draft-diaz-lzip
diff --git a/README b/README
index 4b639c6..fa5ff44 100644
--- a/README
+++ b/README
@@ -2,52 +2,60 @@ Description
Lzd is a simplified decompressor for the lzip format with an educational
purpose. Studying its source is a good first step to understand how lzip
-works. It is not safe to use lzd for any real work.
+works.
-The source of lzd is used in the lzip manual as a reference decompressor
-in the description of the lzip file format. Reading the lzip manual will
-help you understand the source.
+The source of lzd is used in the lzip manual as a reference decompressor in
+the description of the lzip file format. Reading the lzip manual will help
+you understand the source. Lzd is compliant with the lzip specification; it
+verifies the 3 integrity factors.
-Lzd decompresses from standard input to standard output. Lzd will
-correctly decompress the concatenation of two or more compressed files.
-The result is the concatenation of the corresponding decompressed data.
-Integrity of such concatenated compressed input is also verified.
+The source of lzd is also used as a reference in the description of the
+media type 'application/lzip'.
+See http://datatracker.ietf.org/doc/draft-diaz-lzip
+
+Lzd decompresses from standard input to standard output. It accepts (and
+ignores) the option '-d' for compatibility with other lzip tools. In
+particular, accepting the option '-d' allows lzd to be used as argument to
+the option '--lz' of the tools from the zutils package.
+
+Lzd will correctly decompress the concatenation of two or more compressed
+files. The result is the concatenation of the corresponding decompressed
+data. Integrity of such concatenated compressed input is also verified.
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 lziprecover program 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.
+ 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.
+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:
-Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for
-the 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).
+Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
+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).
-Copyright (C) 2013-2019 Antonio Diaz Diaz.
+Copyright (C) 2013-2021 Antonio Diaz Diaz.
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
Makefile. It has the same copyright owner and permissions that configure
diff --git a/configure b/configure
index a4e000e..a1f7471 100755
--- a/configure
+++ b/configure
@@ -1,12 +1,12 @@
#! /bin/sh
# configure script for Lzd - Educational decompressor for the lzip format
-# Copyright (C) 2013-2019 Antonio Diaz Diaz.
+# Copyright (C) 2013-2021 Antonio Diaz Diaz.
#
# This configure script is free software: you have unlimited permission
-# to copy, distribute and modify it.
+# to copy, distribute, and modify it.
pkgname=lzd
-pkgversion=1.1
+pkgversion=1.2
progname=lzd
srctrigger=lzd.cc
@@ -26,11 +26,7 @@ CXXFLAGS='-Wall -W -O2'
LDFLAGS=
# 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 ; }
# Loop over all args
args=
@@ -42,11 +38,12 @@ while [ $# != 0 ] ; do
shift
# Add the argument quoted to args
- args="${args} \"${option}\""
+ if [ -z "${args}" ] ; then args="\"${option}\""
+ else args="${args} \"${option}\"" ; fi
# Split out the argument for options that take them
case ${option} in
- *=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
+ *=*) optarg=`echo "${option}" | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
esac
# Process the options
@@ -125,7 +122,7 @@ if [ -z "${srcdir}" ] ; then
if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
## the sed command below emulates the dirname command
- srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+ srcdir=`echo "$0" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
fi
fi
@@ -148,7 +145,7 @@ if [ -z "${no_create}" ] ; then
# Run this file to recreate the current configuration.
#
# 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
EOF
@@ -170,11 +167,11 @@ echo "LDFLAGS = ${LDFLAGS}"
rm -f Makefile
cat > Makefile << EOF
# Makefile for Lzd - Educational decompressor for the lzip format
-# Copyright (C) 2013-2019 Antonio Diaz Diaz.
+# Copyright (C) 2013-2021 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit.
#
# This Makefile is free software: you have unlimited permission
-# to copy, distribute and modify it.
+# to copy, distribute, and modify it.
pkgname = ${pkgname}
pkgversion = ${pkgversion}
diff --git a/lzd.cc b/lzd.cc
index 503bc36..f7572b2 100644
--- a/lzd.cc
+++ b/lzd.cc
@@ -1,25 +1,25 @@
-/* Lzd - Educational decompressor for the lzip format
- Copyright (C) 2013-2019 Antonio Diaz Diaz.
+/* Lzd - Educational decompressor for the lzip format
+ Copyright (C) 2013-2021 Antonio Diaz Diaz.
- This program is free software. Redistribution and use in source and
- binary forms, with or without modification, are permitted provided
- that the following conditions are met:
+ This program is free software. Redistribution and use in source and
+ binary forms, with or without modification, are permitted provided
+ that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
- Exit status: 0 for a normal exit, 1 for environmental problems
- (file not found, invalid flags, I/O errors, etc), 2 to indicate a
- corrupt or invalid input file.
+ Exit status: 0 for a normal exit, 1 for environmental problems
+ (file not found, invalid flags, I/O errors, etc), 2 to indicate a
+ corrupt or invalid input file.
*/
#include <algorithm>
@@ -47,7 +47,7 @@ public:
void set_char()
{
- static const int next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
+ const int next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
st = next[st];
}
void set_match() { st = ( st < 7 ) ? 7 : 10; }
@@ -69,7 +69,7 @@ enum {
dis_slot_bits = 6,
start_dis_model = 4,
end_dis_model = 14,
- modeled_distances = 1 << (end_dis_model / 2), // 128
+ modeled_distances = 1 << ( end_dis_model / 2 ), // 128
dis_align_bits = 4,
dis_align_size = 1 << dis_align_bits,
@@ -130,8 +130,9 @@ public:
const CRC32 crc32;
-typedef uint8_t Lzip_header[6]; // 0-3 magic, 4 version, 5 coded_dict_size
-
+typedef uint8_t Lzip_header[6]; // 0-3 magic bytes
+ // 4 version
+ // 5 coded dictionary size
typedef uint8_t Lzip_trailer[20];
// 0-3 CRC32 of the uncompressed data
// 4-11 size of the uncompressed data
@@ -139,16 +140,18 @@ typedef uint8_t Lzip_trailer[20];
class Range_decoder
{
+ unsigned long long member_pos;
uint32_t code;
uint32_t range;
public:
- Range_decoder() : code( 0 ), range( 0xFFFFFFFFU )
+ Range_decoder() : member_pos( 6 ), code( 0 ), range( 0xFFFFFFFFU )
{
- for( int i = 0; i < 5; ++i ) code = (code << 8) | get_byte();
+ for( int i = 0; i < 5; ++i ) code = ( code << 8 ) | get_byte();
}
- uint8_t get_byte() { return std::getc( stdin ); }
+ uint8_t get_byte() { ++member_pos; return std::getc( stdin ); }
+ unsigned long long member_position() const { return member_pos; }
unsigned decode( const int num_bits )
{
@@ -159,7 +162,7 @@ public:
symbol <<= 1;
if( code >= range ) { code -= range; symbol |= 1; }
if( range <= 0x00FFFFFFU ) // normalize
- { range <<= 8; code = (code << 8) | get_byte(); }
+ { range <<= 8; code = ( code << 8 ) | get_byte(); }
}
return symbol;
}
@@ -171,7 +174,8 @@ public:
if( code < bound )
{
range = bound;
- bm.probability += (bit_model_total - bm.probability) >> bit_model_move_bits;
+ bm.probability +=
+ ( bit_model_total - bm.probability ) >> bit_model_move_bits;
symbol = 0;
}
else
@@ -182,7 +186,7 @@ public:
symbol = 1;
}
if( range <= 0x00FFFFFFU ) // normalize
- { range <<= 8; code = (code << 8) | get_byte(); }
+ { range <<= 8; code = ( code << 8 ) | get_byte(); }
return symbol;
}
@@ -191,7 +195,7 @@ public:
unsigned symbol = 1;
for( int i = 0; i < num_bits; ++i )
symbol = ( symbol << 1 ) | decode_bit( bm[symbol] );
- return symbol - (1 << num_bits);
+ return symbol - ( 1 << num_bits );
}
unsigned decode_tree_reversed( Bit_model bm[], const int num_bits )
@@ -278,7 +282,11 @@ public:
~LZ_decoder() { delete[] buffer; }
unsigned crc() const { return crc_ ^ 0xFFFFFFFFU; }
- unsigned long long data_position() const { return partial_data_pos + pos; }
+ unsigned long long data_position() const
+ { return partial_data_pos + pos; }
+ uint8_t get_byte() { return rdec.get_byte(); }
+ unsigned long long member_position() const
+ { return rdec.member_position(); }
bool decode_member();
};
@@ -290,7 +298,6 @@ void LZ_decoder::flush_data()
{
const unsigned size = pos - stream_pos;
crc32.update_buf( crc_, buffer + stream_pos, size );
- errno = 0;
if( std::fwrite( buffer + stream_pos, 1, size, stdout ) != size )
{ std::fprintf( stderr, "Write error: %s\n", std::strerror( errno ) );
std::exit( 1 ); }
@@ -301,7 +308,7 @@ void LZ_decoder::flush_data()
}
-bool LZ_decoder::decode_member() // Returns false if error
+bool LZ_decoder::decode_member() // Returns false if error
{
Bit_model bm_literal[1<<literal_context_bits][0x300];
Bit_model bm_match[State::states][pos_states];
@@ -381,7 +388,8 @@ bool LZ_decoder::decode_member() // Returns false if error
direct_bits );
else
{
- rep0 += rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits;
+ rep0 +=
+ rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits;
rep0 += rdec.decode_tree_reversed( bm_align, dis_align_bits );
if( rep0 == 0xFFFFFFFFU ) // marker found
{
@@ -403,20 +411,21 @@ bool LZ_decoder::decode_member() // Returns false if error
int main( const int argc, const char * const argv[] )
{
- if( argc > 1 )
+ if( argc > 2 || ( argc == 2 && std::strcmp( argv[1], "-d" ) != 0 ) )
{
- std::printf( "Lzd %s - Educational decompressor for the lzip format.\n",
- PROGVERSION );
- std::printf( "Study the source to learn how a lzip decompressor works.\n"
- "See the lzip manual for an explanation of the code.\n"
- "It is not safe to use lzd for any real work.\n"
- "\nUsage: %s < file.lz > file\n", argv[0] );
- std::printf( "Lzd decompresses from standard input to standard output.\n"
- "\nCopyright (C) 2019 Antonio Diaz Diaz.\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.\n"
- "Report bugs to lzip-bug@nongnu.org\n"
- "Lzd home page: http://www.nongnu.org/lzip/lzd.html\n" );
+ std::printf(
+ "Lzd %s - Educational decompressor for the lzip format.\n"
+ "Study the source to learn how a lzip decompressor works.\n"
+ "See the lzip manual for an explanation of the code.\n"
+ "\nUsage: %s [-d] < file.lz > file\n"
+ "Lzd decompresses from standard input to standard output.\n"
+ "\nCopyright (C) 2021 Antonio Diaz Diaz.\n"
+ "License 2-clause BSD.\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n"
+ "Report bugs to lzip-bug@nongnu.org\n"
+ "Lzd home page: http://www.nongnu.org/lzip/lzd.html\n",
+ PROGVERSION, argv[0] );
return 0;
}
@@ -432,9 +441,9 @@ int main( const int argc, const char * const argv[] )
if( std::feof( stdin ) || std::memcmp( header, "LZIP\x01", 5 ) != 0 )
{
if( first_member )
- { std::fputs( "Bad magic number (file not in lzip format).\n", stderr );
- return 2; }
- break;
+ { std::fputs( "Bad magic number (file not in lzip format).\n",
+ stderr ); return 2; }
+ break; // ignore trailing data
}
unsigned dict_size = 1 << ( header[5] & 0x1F );
dict_size -= ( dict_size / 16 ) * ( ( header[5] >> 5 ) & 7 );
@@ -447,17 +456,29 @@ int main( const int argc, const char * const argv[] )
{ std::fputs( "Data error\n", stderr ); return 2; }
Lzip_trailer trailer; // verify trailer
- for( int i = 0; i < 20; ++i ) trailer[i] = std::getc( stdin );
+ for( int i = 0; i < 20; ++i ) trailer[i] = decoder.get_byte();
+ int retval = 0;
unsigned crc = 0;
- for( int i = 3; i >= 0; --i ) { crc <<= 8; crc += trailer[i]; }
+ for( int i = 3; i >= 0; --i ) crc = ( crc << 8 ) + trailer[i];
+ if( crc != decoder.crc() )
+ { std::fputs( "CRC mismatch\n", stderr ); retval = 2; }
+
unsigned long long data_size = 0;
- for( int i = 11; i >= 4; --i ) { data_size <<= 8; data_size += trailer[i]; }
- if( crc != decoder.crc() || data_size != decoder.data_position() )
- { std::fputs( "CRC error\n", stderr ); return 2; }
+ for( int i = 11; i >= 4; --i )
+ data_size = ( data_size << 8 ) + trailer[i];
+ if( data_size != decoder.data_position() )
+ { std::fputs( "Data size mismatch\n", stderr ); retval = 2; }
+
+ unsigned long long member_size = 0;
+ for( int i = 19; i >= 12; --i )
+ member_size = ( member_size << 8 ) + trailer[i];
+ if( member_size != decoder.member_position() )
+ { std::fputs( "Member size mismatch\n", stderr ); retval = 2; }
+ if( retval ) return retval;
}
if( std::fclose( stdout ) != 0 )
- { std::fprintf( stderr, "Error closing stdout: %s\n", std::strerror( errno ) );
- return 1; }
+ { std::fprintf( stderr, "Error closing stdout: %s\n",
+ std::strerror( errno ) ); return 1; }
return 0;
}
diff --git a/testsuite/check.sh b/testsuite/check.sh
index eb83163..c1f86e6 100755
--- a/testsuite/check.sh
+++ b/testsuite/check.sh
@@ -1,9 +1,9 @@
#! /bin/sh
# check script for Lzd - Educational decompressor for the lzip format
-# Copyright (C) 2013-2019 Antonio Diaz Diaz.
+# Copyright (C) 2013-2021 Antonio Diaz Diaz.
#
# This script is free software: you have unlimited permission
-# to copy, distribute and modify it.
+# to copy, distribute, and modify it.
LC_ALL=C
export LC_ALL
@@ -30,6 +30,8 @@ cd "${objdir}"/tmp || framework_failure
in="${testdir}"/test.txt
in_lz="${testdir}"/test.txt.lz
+in_em="${testdir}"/test_em.txt.lz
+fox_lz="${testdir}"/fox.lz
fail=0
test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
@@ -38,16 +40,38 @@ printf "testing lzd-%s..." "$2"
"${LZIP}" < "${in}" 2> /dev/null
[ $? = 2 ] || test_failed $LINENO
-"${LZIP}" < "${in_lz}" > copy || test_failed $LINENO
-cmp "${in}" copy || test_failed $LINENO
+for i in "${in_lz}" "${in_em}" ; do
+ "${LZIP}" < "$i" > copy || test_failed $LINENO "$i"
+ cmp "${in}" copy || test_failed $LINENO "$i"
+done
cat "${in}" "${in}" > in2 || framework_failure
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure
"${LZIP}" < in2.lz > copy2 || test_failed $LINENO
cmp in2 copy2 || test_failed $LINENO
+cat in2.lz > copy2.lz || framework_failure
+printf "\ngarbage" >> copy2.lz || framework_failure
+"${LZIP}" -d < copy2.lz > copy2 || test_failed $LINENO
+cmp in2 copy2 || test_failed $LINENO
+rm -f in2 copy2 copy2.lz || framework_failure
+
printf "\ntesting bad input..."
+for i in fox_bm.lz fox_v2.lz fox_s11.lz fox_de20.lz \
+ fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
+ "${LZIP}" < "${testdir}"/$i > /dev/null 2>&1
+ [ $? = 2 ] || test_failed $LINENO $i
+done
+
+"${LZIP}" < "${fox_lz}" > fox || test_failed $LINENO
+for i in fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
+ "${LZIP}" < "${testdir}"/$i > out 2> /dev/null
+ [ $? = 2 ] || test_failed $LINENO $i
+ cmp fox out || test_failed $LINENO $i
+done
+rm -f fox out || 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 &&
[ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then
diff --git a/testsuite/fox.lz b/testsuite/fox.lz
new file mode 100644
index 0000000..509da82
--- /dev/null
+++ b/testsuite/fox.lz
Binary files differ
diff --git a/testsuite/fox_bcrc.lz b/testsuite/fox_bcrc.lz
new file mode 100644
index 0000000..8f6a7c4
--- /dev/null
+++ b/testsuite/fox_bcrc.lz
Binary files differ
diff --git a/testsuite/fox_bm.lz b/testsuite/fox_bm.lz
new file mode 100644
index 0000000..d71914f
--- /dev/null
+++ b/testsuite/fox_bm.lz
Binary files differ
diff --git a/testsuite/fox_crc0.lz b/testsuite/fox_crc0.lz
new file mode 100644
index 0000000..1abe926
--- /dev/null
+++ b/testsuite/fox_crc0.lz
Binary files differ
diff --git a/testsuite/fox_das46.lz b/testsuite/fox_das46.lz
new file mode 100644
index 0000000..43ed9f9
--- /dev/null
+++ b/testsuite/fox_das46.lz
Binary files differ
diff --git a/testsuite/fox_de20.lz b/testsuite/fox_de20.lz
new file mode 100644
index 0000000..10949d8
--- /dev/null
+++ b/testsuite/fox_de20.lz
Binary files differ
diff --git a/testsuite/fox_mes81.lz b/testsuite/fox_mes81.lz
new file mode 100644
index 0000000..d50ef2e
--- /dev/null
+++ b/testsuite/fox_mes81.lz
Binary files differ
diff --git a/testsuite/fox_s11.lz b/testsuite/fox_s11.lz
new file mode 100644
index 0000000..dca909c
--- /dev/null
+++ b/testsuite/fox_s11.lz
Binary files differ
diff --git a/testsuite/fox_v2.lz b/testsuite/fox_v2.lz
new file mode 100644
index 0000000..8620981
--- /dev/null
+++ b/testsuite/fox_v2.lz
Binary files differ
diff --git a/testsuite/test_em.txt.lz b/testsuite/test_em.txt.lz
new file mode 100644
index 0000000..7e96250
--- /dev/null
+++ b/testsuite/test_em.txt.lz
Binary files differ