summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--COPYING.GPL3
-rw-r--r--ChangeLog7
-rw-r--r--Makefile.in17
-rw-r--r--NEWS8
-rw-r--r--README2
-rw-r--r--carg_parser.c18
-rw-r--r--carg_parser.h11
-rwxr-xr-xconfigure8
-rw-r--r--decoder.c15
-rw-r--r--decoder.h14
-rw-r--r--doc/lzlib.info92
-rw-r--r--doc/lzlib.texi101
-rw-r--r--doc/minilzip.18
-rw-r--r--encoder_base.c3
-rw-r--r--lzlib.c2
-rw-r--r--lzlib.h2
-rw-r--r--minilzip.c43
-rwxr-xr-xtestsuite/check.sh77
-rw-r--r--testsuite/fox_nz.lzbin0 -> 80 bytes
-rw-r--r--testsuite/test.txt6
-rw-r--r--testsuite/test.txt.lzbin7376 -> 7341 bytes
-rw-r--r--testsuite/test_em.txt.lzbin14024 -> 0 bytes
-rw-r--r--testsuite/test_sync.lzbin7568 -> 7367 bytes
23 files changed, 249 insertions, 188 deletions
diff --git a/COPYING.GPL b/COPYING.GPL
index 4ad17ae..42fe735 100644
--- a/COPYING.GPL
+++ b/COPYING.GPL
@@ -1,8 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/ChangeLog b/ChangeLog
index a945949..33f023c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2024-10-16 Antonio Diaz Diaz <antonio@gnu.org>
+
+ * Version 1.15-pre2 released.
+ * decoder.h (Rd_try_reload): Reject a nonzero first LZMA byte.
+ * minilzip.c (do_decompress): Reject empty member in multimember.
+ * configure, Makefile.in: Don't use '--soname'; create 'liblz.so.1'.
+
2024-04-19 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.15-pre1 released.
diff --git a/Makefile.in b/Makefile.in
index cf90c91..6d9035c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -27,16 +27,16 @@ lib : $(libname_static) $(libname_shared)
lib$(libname).a : lzlib.o
$(AR) $(ARFLAGS) $@ $<
-lib$(libname).so.$(pkgversion) : lzlib_sh.o
- $(CC) $(CFLAGS) $(LDFLAGS) -fpic -fPIC -shared -Wl,--soname=lib$(libname).so.$(soversion) -o $@ $<
+lib$(libname).so.$(soversion) : lzlib_sh.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -fpic -fPIC -shared -o $@ $<
bin : $(progname_static) $(progname_shared)
$(progname) : $(objs) lib$(libname).a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(objs) lib$(libname).a
-$(progname)_shared : $(objs) lib$(libname).so.$(pkgversion)
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(objs) lib$(libname).so.$(pkgversion)
+$(progname)_shared : $(objs) lib$(libname).so.$(soversion)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(objs) lib$(libname).so.$(soversion)
bbexample : bbexample.o lib$(libname).a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ bbexample.o lib$(libname).a
@@ -113,15 +113,14 @@ install-lib : lib
$(INSTALL_DATA) ./lib$(libname).a "$(DESTDIR)$(libdir)/lib$(libname).a" ; \
fi
if [ -n "$(libname_shared)" ] ; then \
- $(INSTALL_PROGRAM) ./lib$(libname).so.$(pkgversion) "$(DESTDIR)$(libdir)/lib$(libname).so.$(pkgversion)" ; \
if [ -e "$(DESTDIR)$(libdir)/lib$(libname).so.$(soversion)" ] ; then \
run_ldconfig=no ; \
else run_ldconfig=yes ; \
fi ; \
rm -f "$(DESTDIR)$(libdir)/lib$(libname).so" ; \
rm -f "$(DESTDIR)$(libdir)/lib$(libname).so.$(soversion)" ; \
- cd "$(DESTDIR)$(libdir)" && ln -s lib$(libname).so.$(pkgversion) lib$(libname).so ; \
- cd "$(DESTDIR)$(libdir)" && ln -s lib$(libname).so.$(pkgversion) lib$(libname).so.$(soversion) ; \
+ $(INSTALL_PROGRAM) ./lib$(libname).so.$(soversion) "$(DESTDIR)$(libdir)/lib$(libname).so.$(soversion)" ; \
+ cd "$(DESTDIR)$(libdir)" && ln -s lib$(libname).so.$(soversion) lib$(libname).so ; \
if [ "${disable_ldconfig}" != yes ] && [ $${run_ldconfig} = yes ] && \
[ -x "$(LDCONFIG)" ] ; then "$(LDCONFIG)" -n "$(DESTDIR)$(libdir)" || true ; fi ; \
fi
@@ -162,7 +161,6 @@ uninstall-lib :
-rm -f "$(DESTDIR)$(libdir)/lib$(libname).a"
-rm -f "$(DESTDIR)$(libdir)/lib$(libname).so"
-rm -f "$(DESTDIR)$(libdir)/lib$(libname).so.$(soversion)"
- -rm -f "$(DESTDIR)$(libdir)/lib$(libname).so.$(pkgversion)"
uninstall-info :
-if $(CAN_RUN_INSTALLINFO) ; then \
@@ -196,8 +194,7 @@ dist : doc
$(DISTNAME)/testsuite/fox.lz \
$(DISTNAME)/testsuite/fox_*.lz \
$(DISTNAME)/testsuite/test_sync.lz \
- $(DISTNAME)/testsuite/test.txt.lz \
- $(DISTNAME)/testsuite/test_em.txt.lz
+ $(DISTNAME)/testsuite/test.txt.lz
rm -f $(DISTNAME)
lzip -v -9 $(DISTNAME).tar
diff --git a/NEWS b/NEWS
index 94f6a9a..d7da1c1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
Changes in version 1.15:
+Lzlib now reports a nonzero first LZMA byte as a LZ_data_error.
+
+minilzip now exits with error status 2 if any empty member is found in a
+multimember file.
+
The targets 'lib' and 'bin' have been added to Makefile.in. 'lib' is the new
default and builds just the library. 'bin' builds both the library and
minilzip.
@@ -9,3 +14,6 @@ minilzip is no longer built by default.
'install-bin' installs minilzip and its man page again.
The use of the target 'bin' has been documented in INSTALL.
+
+To improve portability, the linker option '--soname' is no longer used.
+Instead the shared library is written to 'liblz.so.1'.
diff --git a/README b/README
index 2207fb5..ec3a5a0 100644
--- a/README
+++ b/README
@@ -3,7 +3,7 @@ Description
Lzlib is a data compression library providing in-memory LZMA compression and
decompression functions, including integrity checking of the decompressed
data. The compressed data format used by the library is the lzip format.
-Lzlib is written in C.
+Lzlib is written in C and is distributed under a 2-clause BSD license.
The lzip file format is designed for data sharing and long-term archiving,
taking into account both data integrity and decoder availability:
diff --git a/carg_parser.c b/carg_parser.c
index edb4eb9..e16fa73 100644
--- a/carg_parser.c
+++ b/carg_parser.c
@@ -148,21 +148,21 @@ static char parse_long_option( struct Arg_parser * const ap,
add_error( ap, "' requires an argument" );
return 1;
}
- return push_back_record( ap, options[index].code,
- options[index].long_name, &opt[len+3] );
+ return push_back_record( ap, options[index].code, options[index].long_name,
+ &opt[len+3] ); /* argument may be empty */
}
- if( options[index].has_arg == ap_yes )
+ if( options[index].has_arg == ap_yes || options[index].has_arg == ap_yme )
{
- if( !arg || !arg[0] )
+ if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) )
{
add_error( ap, "option '--" ); add_error( ap, options[index].long_name );
add_error( ap, "' requires an argument" );
return 1;
}
++*argindp;
- return push_back_record( ap, options[index].code,
- options[index].long_name, arg );
+ return push_back_record( ap, options[index].code, options[index].long_name,
+ arg ); /* argument may be empty */
}
return push_back_record( ap, options[index].code,
@@ -204,15 +204,15 @@ static char parse_short_option( struct Arg_parser * const ap,
if( !push_back_record( ap, c, 0, &opt[cind] ) ) return 0;
++*argindp; cind = 0;
}
- else if( options[index].has_arg == ap_yes )
+ else if( options[index].has_arg == ap_yes || options[index].has_arg == ap_yme )
{
- if( !arg || !arg[0] )
+ if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) )
{
add_error( ap, "option requires an argument -- '" );
add_error( ap, code_str ); add_error( ap, "'" );
return 1;
}
- ++*argindp; cind = 0;
+ ++*argindp; cind = 0; /* argument may be empty */
if( !push_back_record( ap, c, 0, arg ) ) return 0;
}
else if( !push_back_record( ap, c, 0, 0 ) ) return 0;
diff --git a/carg_parser.h b/carg_parser.h
index 69ce271..65a6d7d 100644
--- a/carg_parser.h
+++ b/carg_parser.h
@@ -37,15 +37,20 @@
The argument '--' terminates all options; any following arguments are
treated as non-option arguments, even if they begin with a hyphen.
- The syntax for optional option arguments is '-<short_option><argument>'
- (without whitespace), or '--<long_option>=<argument>'.
+ The syntax of options with an optional argument is
+ '-<short_option><argument>' (without whitespace), or
+ '--<long_option>=<argument>'.
+
+ The syntax of options with an empty argument is '-<short_option> ""',
+ '--<long_option> ""', or '--<long_option>=""'.
*/
#ifdef __cplusplus
extern "C" {
#endif
-enum ap_Has_arg { ap_no, ap_yes, ap_maybe };
+/* ap_yme = yes but maybe empty */
+enum ap_Has_arg { ap_no, ap_yes, ap_maybe, ap_yme };
struct ap_Option
{
diff --git a/configure b/configure
index b24d769..7fa49d2 100755
--- a/configure
+++ b/configure
@@ -6,7 +6,7 @@
# to copy, distribute, and modify it.
pkgname=lzlib
-pkgversion=1.15-pre1
+pkgversion=1.15-pre2
soversion=1
libname=lz
libname_static=lib${libname}.a
@@ -118,12 +118,12 @@ while [ $# != 0 ] ; do
--no-create) no_create=yes ;;
--disable-static)
libname_static=
- libname_shared=lib${libname}.so.${pkgversion}
progname_static=
+ libname_shared=lib${libname}.so.${soversion}
progname_shared=${progname}_shared
progname_lzip=${progname}_shared ;;
--enable-shared)
- libname_shared=lib${libname}.so.${pkgversion}
+ libname_shared=lib${libname}.so.${soversion}
progname_shared=${progname}_shared
progname_lzip=${progname}_shared ;;
--disable-ldconfig) disable_ldconfig=yes ;;
@@ -146,7 +146,7 @@ while [ $# != 0 ] ; do
exit 1 ;;
esac
- # Check if the option took a separate argument
+ # Check whether the option took a separate argument
if [ "${arg2}" = yes ] ; then
if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift
else echo "configure: Missing argument to '${option}'" 1>&2
diff --git a/decoder.c b/decoder.c
index d1fbe54..7b90d6e 100644
--- a/decoder.c
+++ b/decoder.c
@@ -35,7 +35,7 @@ static int LZd_try_check_trailer( struct LZ_decoder * const d )
/* Return value: 0 = OK, 1 = decoder error, 2 = unexpected EOF,
3 = trailer error, 4 = unknown marker found,
- 5 = library error. */
+ 5 = nonzero first LZMA byte found, 6 = library error. */
static int LZd_decode_member( struct LZ_decoder * const d )
{
struct Range_decoder * const rdec = d->rdec;
@@ -43,14 +43,15 @@ static int LZd_decode_member( struct LZ_decoder * const d )
unsigned old_mpos = rdec->member_position;
if( d->member_finished ) return 0;
- if( !Rd_try_reload( rdec ) )
- { if( !rdec->at_stream_end ) return 0; else return 2; }
+ const int tmp = Rd_try_reload( rdec );
+ if( tmp > 1 ) return 5;
+ if( !tmp ) { if( !rdec->at_stream_end ) return 0; else return 2; }
if( d->check_trailer_pending ) return LZd_try_check_trailer( d );
while( !Rd_finished( rdec ) )
{
const unsigned mpos = rdec->member_position;
- if( mpos - old_mpos > rd_min_available_bytes ) return 5;
+ if( mpos - old_mpos > rd_min_available_bytes ) return 6;
old_mpos = mpos;
if( !Rd_enough_available_bytes( rdec ) ) /* check unexpected EOF */
{ if( !rdec->at_stream_end ) return 0;
@@ -117,7 +118,7 @@ static int LZd_decode_member( struct LZ_decoder * const d )
{
Rd_normalize( rdec );
const unsigned mpos = rdec->member_position;
- if( mpos - old_mpos > rd_min_available_bytes ) return 5;
+ if( mpos - old_mpos > rd_min_available_bytes ) return 6;
old_mpos = mpos;
if( len == min_match_len ) /* End Of Stream marker */
{
@@ -127,7 +128,9 @@ static int LZd_decode_member( struct LZ_decoder * const d )
if( len == min_match_len + 1 ) /* Sync Flush marker */
{
rdec->reload_pending = true;
- if( Rd_try_reload( rdec ) ) continue;
+ const int tmp = Rd_try_reload( rdec );
+ if( tmp > 1 ) return 5;
+ if( tmp ) continue;
if( !rdec->at_stream_end ) return 0; else break;
}
return 4;
diff --git a/decoder.h b/decoder.h
index 4b91fec..57e47cb 100644
--- a/decoder.h
+++ b/decoder.h
@@ -133,13 +133,15 @@ static inline bool Rd_unread_data( struct Range_decoder * const rdec,
return true;
}
-static bool Rd_try_reload( struct Range_decoder * const rdec )
+static int Rd_try_reload( struct Range_decoder * const rdec )
{
if( rdec->reload_pending && Rd_available_bytes( rdec ) >= 5 )
{
rdec->reload_pending = false;
rdec->code = 0;
rdec->range = 0xFFFFFFFFU;
+ /* check first byte of the LZMA stream without reading it */
+ if( rdec->cb.buffer[rdec->cb.get] != 0 ) return 2;
Rd_get_byte( rdec ); /* discard first byte of the LZMA stream */
int i; for( i = 0; i < 4; ++i )
rdec->code = (rdec->code << 8) | Rd_get_byte( rdec );
@@ -164,7 +166,7 @@ static inline unsigned Rd_decode( struct Range_decoder * const rdec,
rdec->range >>= 1;
/* symbol <<= 1; */
/* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */
- const bool bit = ( rdec->code >= rdec->range );
+ const bool bit = rdec->code >= rdec->range;
symbol <<= 1; symbol += bit;
rdec->code -= rdec->range & ( 0U - bit );
}
@@ -387,14 +389,14 @@ static inline void LZd_copy_block( struct LZ_decoder * const d,
bool fast, fast2;
if( lpos > distance )
{
- fast = ( len < d->cb.buffer_size - lpos );
- fast2 = ( fast && len <= lpos - i );
+ fast = len < d->cb.buffer_size - lpos;
+ fast2 = fast && len <= lpos - i;
}
else
{
i += d->cb.buffer_size;
- fast = ( len < d->cb.buffer_size - i ); /* (i == pos) may happen */
- fast2 = ( fast && len <= i - lpos );
+ fast = len < d->cb.buffer_size - i; /* (i == pos) may happen */
+ fast2 = fast && len <= i - lpos;
}
if( fast ) /* no wrap */
{
diff --git a/doc/lzlib.info b/doc/lzlib.info
index 314c98a..44bf3ce 100644
--- a/doc/lzlib.info
+++ b/doc/lzlib.info
@@ -11,7 +11,7 @@ File: lzlib.info, Node: Top, Next: Introduction, Up: (dir)
Lzlib Manual
************
-This manual is for Lzlib (version 1.15-pre1, 19 April 2024).
+This manual is for Lzlib (version 1.15-pre2, 16 October 2024).
* Menu:
@@ -24,7 +24,7 @@ This manual is for Lzlib (version 1.15-pre1, 19 April 2024).
* Error codes:: Meaning of codes returned by functions
* Error messages:: Error messages corresponding to error codes
* Invoking minilzip:: Command-line interface of the test program
-* Data format:: Detailed format of the compressed data
+* File format:: Detailed format of the compressed file
* Examples:: A small tutorial with examples
* Problems:: Reporting bugs
* Concept index:: Index of concepts
@@ -44,7 +44,7 @@ File: lzlib.info, Node: Introduction, Next: Library version, Prev: Top, Up:
Lzlib is a data compression library providing in-memory LZMA compression and
decompression functions, including integrity checking of the decompressed
data. The compressed data format used by the library is the lzip format.
-Lzlib is written in C.
+Lzlib is written in C and is distributed under a 2-clause BSD license.
The lzip file format is designed for data sharing and long-term
archiving, taking into account both data integrity and decoder availability:
@@ -339,7 +339,7 @@ except 'LZ_compress_open' whose return value must be checked by calling
between applications using lzlib, but is useless and wasteful in a
file, and is excluded from the media type 'application/lzip'. The LZMA
marker '2' ("End Of Stream" marker) is the only marker allowed in lzip
- files. *Note Data format::.
+ files. *Note File format::.
Repeated use of 'LZ_compress_sync_flush' may degrade compression
ratio, so use it only when needed. If the interval between calls to
@@ -459,7 +459,7 @@ except 'LZ_decompress_open' whose return value must be checked by calling
-- Function: int LZ_decompress_reset ( struct LZ_Decoder * const DECODER )
Resets the internal state of DECODER as it was just after opening it
with the function 'LZ_decompress_open'. Data stored in the internal
- buffers is discarded. Position counters are set to 0.
+ buffers are discarded. Position counters are set to 0.
-- Function: int LZ_decompress_sync_to_member ( struct LZ_Decoder * const
DECODER )
@@ -618,9 +618,10 @@ failed. If the call failed, then you can examine 'LZ_(de)compress_errno'.
-- Constant: enum LZ_Errno LZ_data_error
The data stream is corrupt. If 'LZ_decompress_member_position' is 6 or
less, it indicates either a format version not supported, an invalid
- dictionary size, a corrupt header in a multimember data stream, or
- trailing data too similar to a valid lzip header. Lziprecover can be
- used to remove conflicting trailing data from a file.
+ dictionary size, a nonzero first LZMA byte, a corrupt header in a
+ multimember data stream, or trailing data too similar to a valid lzip
+ header. Lziprecover can be used to repair some of these errors and to
+ remove conflicting trailing data from a file.
-- Constant: enum LZ_Errno LZ_library_error
A bug was detected in the library. Please, report it. *Note Problems::.
@@ -641,7 +642,7 @@ File: lzlib.info, Node: Error messages, Next: Invoking minilzip, Prev: Error
'LZ_(de)compress_errno'.

-File: lzlib.info, Node: Invoking minilzip, Next: Data format, Prev: Error messages, Up: Top
+File: lzlib.info, Node: Invoking minilzip, Next: File format, Prev: Error messages, Up: Top
9 Invoking minilzip
*******************
@@ -658,8 +659,8 @@ maximum dictionary size is 512 MiB so that any lzip file can be decompressed
on 32-bit machines. Lzip provides accurate and robust 3-factor integrity
checking. Lzip can compress about as fast as gzip (lzip -0) or compress most
files more than bzip2 (lzip -9). Decompression speed is intermediate between
-gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery
-perspective. Lzip has been designed, written, and tested with great care to
+gzip and bzip2. Lzip provides better data recovery capabilities than gzip
+and bzip2. Lzip has been designed, written, and tested with great care to
replace gzip and bzip2 as the standard general-purpose compressed format for
Unix-like systems.
@@ -673,7 +674,7 @@ means standard input. It can be mixed with other FILES and is read just
once, the first time it appears in the command line. Remember to prepend
'./' to any file name beginning with a hyphen, or use '--'.
- minilzip supports the following options: *Note Argument syntax:
+minilzip supports the following options: *Note Argument syntax:
(arg_parser)Argument syntax.
'-h'
@@ -818,6 +819,7 @@ once, the first time it appears in the command line. Remember to prepend
'-s64MiB -m273'
Level Dictionary size (-s) Match length limit (-m)
+ ------------------------------------------------------
-0 64 KiB 16 bytes
-1 1 MiB 5 bytes
-2 1.5 MiB 6 bytes
@@ -858,6 +860,7 @@ and may be followed by a multiplier and an optional 'B' for "byte".
Table of SI and binary prefixes (unit multipliers):
Prefix Value | Prefix Value
+----------------------------------------------------------------------
k kilobyte (10^3 = 1000) | Ki kibibyte (2^10 = 1024)
M megabyte (10^6) | Mi mebibyte (2^20)
G gigabyte (10^9) | Gi gibibyte (2^30)
@@ -876,16 +879,15 @@ corrupt or invalid input file, 3 for an internal consistency error (e.g.,
bug) which caused minilzip to panic.

-File: lzlib.info, Node: Data format, Next: Examples, Prev: Invoking minilzip, Up: Top
+File: lzlib.info, Node: File format, Next: Examples, Prev: Invoking minilzip, Up: Top
-10 Data format
+10 File format
**************
Perfection is reached, not when there is no longer anything to add, but
when there is no longer anything to take away.
-- Antoine de Saint-Exupery
-
In the diagram below, a box like this:
+---+
@@ -900,12 +902,12 @@ when there is no longer anything to take away.
represents a variable number of bytes.
-
- Lzip data consist of one or more independent "members" (compressed data
-sets). The members simply appear one after another in the data stream, with
-no additional information before, between, or after them. Each member can
+A lzip file consists of one or more independent "members" (compressed data
+sets). The members simply appear one after another in the file, with no
+additional information before, between, or after them. Each member can
encode in compressed form up to 16 EiB - 1 byte of uncompressed data. The
-size of a multimember data stream is unlimited.
+size of a multimember file is unlimited. Empty members (data size = 0) are
+not allowed in multimember files.
Each member has the following structure:
@@ -933,7 +935,7 @@ size of a multimember data stream is unlimited.
Valid values for dictionary size range from 4 KiB to 512 MiB.
'LZMA stream'
- The LZMA stream, finished by an "End Of Stream" marker. Uses default
+ The LZMA stream, terminated by an "End Of Stream" marker. Uses default
values for encoder properties. *Note Stream format: (lzip)Stream
format, for a complete description.
Lzip only uses the LZMA marker '2' ("End Of Stream" marker). Lzlib
@@ -955,7 +957,7 @@ size of a multimember data stream is unlimited.

-File: lzlib.info, Node: Examples, Next: Problems, Prev: Data format, Up: Top
+File: lzlib.info, Node: Examples, Next: Problems, Prev: File format, Up: Top
11 A small tutorial with examples
*********************************
@@ -1287,13 +1289,13 @@ Concept index
* buffering: Buffering. (line 6)
* bugs: Problems. (line 6)
* compression functions: Compression functions. (line 6)
-* data format: Data format. (line 6)
* decompression functions: Decompression functions. (line 6)
* error codes: Error codes. (line 6)
* error messages: Error messages. (line 6)
* examples: Examples. (line 6)
* file compression: File compression. (line 6)
* file decompression: File decompression. (line 6)
+* file format: File format. (line 6)
* getting help: Problems. (line 6)
* introduction: Introduction. (line 6)
* invoking: Invoking minilzip. (line 6)
@@ -1307,28 +1309,28 @@ Concept index

Tag Table:
Node: Top215
-Node: Introduction1341
-Node: Library version6781
-Node: Buffering9332
-Node: Parameter limits10557
-Node: Compression functions11511
-Ref: member_size13304
-Ref: sync_flush15066
-Node: Decompression functions19754
-Node: Error codes27311
-Node: Error messages29601
-Node: Invoking minilzip30180
-Node: Data format40774
-Ref: coded-dict-size42220
-Node: Examples43625
-Node: Buffer compression44586
-Node: Buffer decompression46106
-Node: File compression47520
-Node: File decompression48503
-Node: File compression mm49507
-Node: Skipping data errors52536
-Node: Problems53841
-Node: Concept index54402
+Node: Introduction1343
+Node: Library version6831
+Node: Buffering9382
+Node: Parameter limits10607
+Node: Compression functions11561
+Ref: member_size13354
+Ref: sync_flush15116
+Node: Decompression functions19804
+Node: Error codes27362
+Node: Error messages29719
+Node: Invoking minilzip30298
+Node: File format41020
+Ref: coded-dict-size42518
+Node: Examples43925
+Node: Buffer compression44886
+Node: Buffer decompression46406
+Node: File compression47820
+Node: File decompression48803
+Node: File compression mm49807
+Node: Skipping data errors52836
+Node: Problems54141
+Node: Concept index54702

End Tag Table
diff --git a/doc/lzlib.texi b/doc/lzlib.texi
index 462c840..23bbbfb 100644
--- a/doc/lzlib.texi
+++ b/doc/lzlib.texi
@@ -6,8 +6,8 @@
@finalout
@c %**end of header
-@set UPDATED 19 April 2024
-@set VERSION 1.15-pre1
+@set UPDATED 16 October 2024
+@set VERSION 1.15-pre2
@dircategory Compression
@direntry
@@ -45,7 +45,7 @@ This manual is for Lzlib (version @value{VERSION}, @value{UPDATED}).
* Error codes:: Meaning of codes returned by functions
* Error messages:: Error messages corresponding to error codes
* Invoking minilzip:: Command-line interface of the test program
-* Data format:: Detailed format of the compressed data
+* File format:: Detailed format of the compressed file
* Examples:: A small tutorial with examples
* Problems:: Reporting bugs
* Concept index:: Index of concepts
@@ -67,7 +67,7 @@ distribute, and modify it.
is a data compression library providing in-memory LZMA compression and
decompression functions, including integrity checking of the decompressed
data. The compressed data format used by the library is the lzip format.
-Lzlib is written in C.
+Lzlib is written in C and is distributed under a 2-clause BSD license.
The lzip file format is designed for data sharing and long-term archiving,
taking into account both data integrity and decoder availability:
@@ -103,16 +103,16 @@ lziprecover, losing an entire archive just because of a corrupt byte near
the beginning is a thing of the past.
The functions and variables forming the interface of the compression library
-are declared in the file @samp{lzlib.h}. Usage examples of the library are
-given in the files @samp{bbexample.c}, @samp{ffexample.c}, and
-@samp{minilzip.c} from the source distribution.
+are declared in the file @file{lzlib.h}. Usage examples of the library are
+given in the files @file{bbexample.c}, @file{ffexample.c}, and
+@file{minilzip.c} from the source distribution.
-As @samp{lzlib.h} can be used by C and C++ programs, it must not impose a
+As @file{lzlib.h} can be used by C and C++ programs, it must not impose a
choice of system headers on the program by including one of them. Therefore
it is the responsibility of the program using lzlib to include before
-@samp{lzlib.h} some header that declares the type @samp{uint8_t}. There are
-at least four such headers in C and C++: @samp{stdint.h}, @samp{cstdint},
-@samp{inttypes.h}, and @samp{cinttypes}.
+@file{lzlib.h} some header that declares the type @samp{uint8_t}. There are
+at least four such headers in C and C++: @file{stdint.h}, @file{cstdint},
+@file{inttypes.h}, and @file{cinttypes}.
All the library functions are thread safe. The library does not install any
signal handler. The decoder checks the consistency of the compressed data,
@@ -183,10 +183,10 @@ versions of itself down to 1.0. Any application working with an older lzlib
should work with a newer lzlib. Installing a newer lzlib should not break
anything. This chapter describes the constants and functions that the
application can use to discover the version of the library being used. All
-of them are declared in @samp{lzlib.h}.
+of them are declared in @file{lzlib.h}.
@defvr Constant LZ_API_VERSION
-This constant is defined in @samp{lzlib.h} and works as a version test
+This constant is defined in @file{lzlib.h} and works as a version test
macro. The application should check at compile time that LZ_API_VERSION is
greater than or equal to the version required by the application:
@@ -207,7 +207,7 @@ which allow the application to announce to the library its desire to have
certain symbols and prototypes exposed.
@deftypefun int LZ_api_version ( void )
-If LZ_API_VERSION >= 1012, this function is declared in @samp{lzlib.h} (else
+If LZ_API_VERSION >= 1012, this function is declared in @file{lzlib.h} (else
it doesn't exist). It returns the LZ_API_VERSION of the library object code
being used. The application should check at run time that the value
returned by @code{LZ_api_version} is greater than or equal to the version
@@ -225,7 +225,7 @@ the functionality required by the application.
@end deftypefun
@deftypevr Constant {const char *} LZ_version_string
-This string constant is defined in the header file @samp{lzlib.h} and
+This string constant is defined in the header file @file{lzlib.h} and
represents the version of the library being used at compile time.
@end deftypevr
@@ -385,7 +385,7 @@ lzip files; it is a device for interactive communication between
applications using lzlib, but is useless and wasteful in a file, and is
excluded from the media type @samp{application/lzip}. The LZMA marker
@samp{2} ("End Of Stream" marker) is the only marker allowed in lzip files.
-@xref{Data format}.
+@xref{File format}.
Repeated use of @samp{LZ_compress_sync_flush} may degrade compression
ratio, so use it only when needed. If the interval between calls to
@@ -524,7 +524,7 @@ detecting a truncated member.
@deftypefun int LZ_decompress_reset ( struct LZ_Decoder * const @var{decoder} )
Resets the internal state of @var{decoder} as it was just after opening
it with the function @samp{LZ_decompress_open}. Data stored in the
-internal buffers is discarded. Position counters are set to 0.
+internal buffers are discarded. Position counters are set to 0.
@end deftypefun
@@ -670,7 +670,7 @@ necessarily LZ_ok, and you should not use @samp{LZ_(de)compress_errno}
to determine whether a call failed. If the call failed, then you can
examine @samp{LZ_(de)compress_errno}.
-The error codes are defined in the header file @samp{lzlib.h}.
+The error codes are defined in the header file @file{lzlib.h}.
@deftypevr Constant {enum LZ_Errno} LZ_ok
The value of this constant is 0 and is used to indicate that there is no error.
@@ -693,8 +693,8 @@ finished.
@end deftypevr
@deftypevr Constant {enum LZ_Errno} LZ_header_error
-An invalid member header (one with the wrong magic bytes) was read. If
-this happens at the end of the data stream it may indicate trailing data.
+An invalid member header (one with the wrong magic bytes) was read. If this
+happens at the end of the data stream it may indicate trailing data.
@end deftypevr
@deftypevr Constant {enum LZ_Errno} LZ_unexpected_eof
@@ -702,11 +702,12 @@ The end of the data stream was reached in the middle of a member.
@end deftypevr
@deftypevr Constant {enum LZ_Errno} LZ_data_error
-The data stream is corrupt. If @samp{LZ_decompress_member_position} is 6
-or less, it indicates either a format version not supported, an invalid
-dictionary size, a corrupt header in a multimember data stream, or
-trailing data too similar to a valid lzip header. Lziprecover can be
-used to remove conflicting trailing data from a file.
+The data stream is corrupt. If @samp{LZ_decompress_member_position} is 6 or
+less, it indicates either a format version not supported, an invalid
+dictionary size, a nonzero first LZMA byte, a corrupt header in a multimember
+data stream, or trailing data too similar to a valid lzip header.
+Lziprecover can be used to repair some of these errors and to remove
+conflicting trailing data from a file.
@end deftypevr
@deftypevr Constant {enum LZ_Errno} LZ_library_error
@@ -747,8 +748,8 @@ maximum dictionary size is 512 MiB so that any lzip file can be decompressed
on 32-bit machines. Lzip provides accurate and robust 3-factor integrity
checking. Lzip can compress about as fast as gzip @w{(lzip -0)} or compress most
files more than bzip2 @w{(lzip -9)}. Decompression speed is intermediate between
-gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery
-perspective. Lzip has been designed, written, and tested with great care to
+gzip and bzip2. Lzip provides better data recovery capabilities than gzip
+and bzip2. Lzip has been designed, written, and tested with great care to
replace gzip and bzip2 as the standard general-purpose compressed format for
Unix-like systems.
@@ -766,6 +767,7 @@ argument means standard input. It can be mixed with other @var{files} and is
read just once, the first time it appears in the command line. Remember to
prepend @file{./} to any file name beginning with a hyphen, or use @samp{--}.
+@noindent
minilzip supports the following
@uref{http://www.nongnu.org/arg-parser/manual/arg_parser_manual.html#Argument-syntax,,options}:
@ifnothtml
@@ -823,7 +825,7 @@ Force overwrite of output files.
@item -F
@itemx --recompress
When compressing, force re-compression of files whose name already has
-the @samp{.lz} or @samp{.tlz} suffix.
+the @file{.lz} or @file{.tlz} suffix.
@item -k
@itemx --keep
@@ -846,8 +848,8 @@ when reading from a named pipe (fifo) or from a device. @w{@option{-o -}} is
equivalent to @option{-c}. @option{-o} has no effect when testing.
When compressing and splitting the output in volumes, @var{file} is used as
-a prefix, and several files named @samp{@var{file}00001.lz},
-@samp{@var{file}00002.lz}, etc, are created. In this case, only one input
+a prefix, and several files named @file{@var{file}00001.lz},
+@file{@var{file}00002.lz}, etc, are created. In this case, only one input
file is allowed.
@item -q
@@ -873,7 +875,7 @@ is affected at compression time by the choice of dictionary size limit.
@itemx --volume-size=@var{bytes}
When compressing, and @option{-c} has not been also specified, split the
compressed output into several volume files with names
-@samp{original_name00001.lz}, @samp{original_name00002.lz}, etc, and set the
+@file{original_name00001.lz}, @file{original_name00002.lz}, etc, and set the
volume size limit to @var{bytes}. Input files are kept unchanged. Each
volume is a complete, maybe multimember, lzip file. A small volume size may
degrade compression ratio, so use it only when needed. Valid values range
@@ -892,11 +894,10 @@ files.
@item -v
@itemx --verbose
Verbose mode.@*
-When compressing, show the compression ratio and size for each file
-processed.@*
-When decompressing or testing, further -v's (up to 4) increase the
-verbosity level, showing status, compression ratio, dictionary size,
-and trailer contents (CRC, data size, member size).
+When compressing, show the compression ratio and size for each file processed.@*
+When decompressing or testing, further -v's (up to 4) increase the verbosity
+level, showing status, compression ratio, dictionary size, and trailer
+contents (CRC, data size, member size).
@item -0 .. -9
Compression level. Set the compression parameters (dictionary size and
@@ -915,7 +916,7 @@ given, the last setting is used. For example @w{@option{-9 -s64MiB}} is
equivalent to @w{@option{-s64MiB -m273}}
@multitable {Level} {Dictionary size (-s)} {Match length limit (-m)}
-@item Level @tab Dictionary size (-s) @tab Match length limit (-m)
+@headitem Level @tab Dictionary size (-s) @tab Match length limit (-m)
@item -0 @tab 64 KiB @tab 16 bytes
@item -1 @tab 1 MiB @tab 5 bytes
@item -2 @tab 1.5 MiB @tab 6 bytes
@@ -960,7 +961,7 @@ and may be followed by a multiplier and an optional @samp{B} for "byte".
Table of SI and binary prefixes (unit multipliers):
@multitable {Prefix} {kilobyte (10^3 = 1000)} {|} {Prefix} {kibibyte (2^10 = 1024)}
-@item Prefix @tab Value @tab | @tab Prefix @tab Value
+@headitem Prefix @tab Value @tab | @tab Prefix @tab Value
@item k @tab kilobyte (10^3 = 1000) @tab | @tab Ki @tab kibibyte (2^10 = 1024)
@item M @tab megabyte (10^6) @tab | @tab Mi @tab mebibyte (2^20)
@item G @tab gigabyte (10^9) @tab | @tab Gi @tab gibibyte (2^30)
@@ -980,15 +981,14 @@ indicate a corrupt or invalid input file, 3 for an internal consistency
error (e.g., bug) which caused minilzip to panic.
-@node Data format
-@chapter Data format
-@cindex data format
+@node File format
+@chapter File format
+@cindex file format
Perfection is reached, not when there is no longer anything to add, but
when there is no longer anything to take away.@*
--- Antoine de Saint-Exupery
-@sp 1
In the diagram below, a box like this:
@verbatim
@@ -1007,12 +1007,13 @@ represents one byte; a box like this:
represents a variable number of bytes.
-@sp 1
-Lzip data consist of one or more independent "members" (compressed data
-sets). The members simply appear one after another in the data stream, with
-no additional information before, between, or after them. Each member can
+@noindent
+A lzip file consists of one or more independent "members" (compressed data
+sets). The members simply appear one after another in the file, with no
+additional information before, between, or after them. Each member can
encode in compressed form up to @w{16 EiB - 1 byte} of uncompressed data.
-The size of a multimember data stream is unlimited.
+The size of a multimember file is unlimited. Empty members (data size = 0)
+are not allowed in multimember files.
Each member has the following structure:
@@ -1043,7 +1044,7 @@ Example: 0xD3 = 2^19 - 6 * 2^15 = 512 KiB - 6 * 32 KiB = 320 KiB@*
Valid values for dictionary size range from 4 KiB to 512 MiB.
@item LZMA stream
-The LZMA stream, finished by an "End Of Stream" marker. Uses default values
+The LZMA stream, terminated by an "End Of Stream" marker. Uses default values
for encoder properties.
@ifnothtml
@xref{Stream format,,,lzip},
@@ -1077,8 +1078,8 @@ overflowing.
@cindex examples
This chapter provides real code examples for the most common uses of the
-library. See these examples in context in the files @samp{bbexample.c} and
-@samp{ffexample.c} from the source distribution of lzlib.
+library. See these examples in context in the files @file{bbexample.c} and
+@file{ffexample.c} from the source distribution of lzlib.
Note that the interface of lzlib is symmetrical. That is, the code for
normal compression and decompression is identical except because one calls
diff --git a/doc/minilzip.1 b/doc/minilzip.1
index 22ad101..c60e528 100644
--- a/doc/minilzip.1
+++ b/doc/minilzip.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
-.TH MINILZIP "1" "April 2024" "minilzip 1.15-pre1" "User Commands"
+.TH MINILZIP "1" "October 2024" "minilzip 1.15-pre2" "User Commands"
.SH NAME
minilzip \- reduces the size of files
.SH SYNOPSIS
@@ -16,8 +16,8 @@ maximum dictionary size is 512 MiB so that any lzip file can be decompressed
on 32\-bit machines. Lzip provides accurate and robust 3\-factor integrity
checking. Lzip can compress about as fast as gzip (lzip \fB\-0\fR) or compress most
files more than bzip2 (lzip \fB\-9\fR). Decompression speed is intermediate between
-gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery
-perspective. Lzip has been designed, written, and tested with great care to
+gzip and bzip2. Lzip provides better data recovery capabilities than gzip
+and bzip2. Lzip has been designed, written, and tested with great care to
replace gzip and bzip2 as the standard general\-purpose compressed format for
Unix\-like systems.
.SH OPTIONS
@@ -120,7 +120,7 @@ License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
-Using lzlib 1.15\-pre1
+Using lzlib 1.15\-pre2
Using LZ_API_VERSION = 1015
.SH "SEE ALSO"
The full documentation for
diff --git a/encoder_base.c b/encoder_base.c
index d2ed53c..cd790fb 100644
--- a/encoder_base.c
+++ b/encoder_base.c
@@ -168,7 +168,6 @@ static void LZeb_reset( struct LZ_encoder_base * const eb,
{
const unsigned long long min_member_size = min_dictionary_size;
const unsigned long long max_member_size = 0x0008000000000000ULL; /* 2 PiB */
- int i;
Mb_reset( &eb->mb );
eb->member_size_limit = min( max( min_member_size, member_size ),
max_member_size ) - Lt_size - max_marker_size;
@@ -186,7 +185,7 @@ static void LZeb_reset( struct LZ_encoder_base * const eb,
Lm_init( &eb->match_len_model );
Lm_init( &eb->rep_len_model );
Re_reset( &eb->renc, eb->mb.dictionary_size );
- for( i = 0; i < num_rep_distances; ++i ) eb->reps[i] = 0;
+ int i; for( i = 0; i < num_rep_distances; ++i ) eb->reps[i] = 0;
eb->state = 0;
eb->member_finished = false;
}
diff --git a/lzlib.c b/lzlib.c
index 4105205..23dd0ac 100644
--- a/lzlib.c
+++ b/lzlib.c
@@ -486,7 +486,7 @@ int LZ_decompress_read( struct LZ_Decoder * const d,
{ d->rdec->member_position += Cb_used_bytes( &d->rdec->cb );
Cb_reset( &d->rdec->cb );
d->lz_errno = LZ_unexpected_eof; }
- else if( result == 5 ) d->lz_errno = LZ_library_error;
+ else if( result == 6 ) d->lz_errno = LZ_library_error;
else d->lz_errno = LZ_data_error;
d->fatal = true;
if( Cb_empty( &d->lz_decoder->cb ) ) return -1;
diff --git a/lzlib.h b/lzlib.h
index 7a52342..431a736 100644
--- a/lzlib.h
+++ b/lzlib.h
@@ -26,7 +26,7 @@ extern "C" {
#define LZ_API_VERSION 1015
-static const char * const LZ_version_string = "1.15-pre1";
+static const char * const LZ_version_string = "1.15-pre2";
enum LZ_Errno { LZ_ok = 0, LZ_bad_argument, LZ_mem_error,
LZ_sequence_error, LZ_header_error, LZ_unexpected_eof,
diff --git a/minilzip.c b/minilzip.c
index c0e542a..db6a4d0 100644
--- a/minilzip.c
+++ b/minilzip.c
@@ -125,8 +125,8 @@ static void show_help( void )
"on 32-bit machines. Lzip provides accurate and robust 3-factor integrity\n"
"checking. Lzip can compress about as fast as gzip (lzip -0) or compress most\n"
"files more than bzip2 (lzip -9). Decompression speed is intermediate between\n"
- "gzip and bzip2. Lzip is better than gzip and bzip2 from a data recovery\n"
- "perspective. Lzip has been designed, written, and tested with great care to\n"
+ "gzip and bzip2. Lzip provides better data recovery capabilities than gzip\n"
+ "and bzip2. Lzip has been designed, written, and tested with great care to\n"
"replace gzip and bzip2 as the standard general-purpose compressed format for\n"
"Unix-like systems.\n"
"\nUsage: %s [options] [files]\n", invocation_name );
@@ -348,7 +348,7 @@ static void show_header( const unsigned dictionary_size )
}
-/* separate numbers of 5 or more digits in groups of 3 digits using '_' */
+/* separate numbers of 6 or more digits in groups of 3 digits using '_' */
static const char * format_num3( unsigned long long num )
{
enum { buffers = 8, bufsize = 4 * sizeof num, n = 10 };
@@ -360,7 +360,7 @@ static const char * format_num3( unsigned long long num )
char * const buf = buffer[current++]; current %= buffers;
char * p = buf + bufsize - 1; /* fill the buffer backwards */
*p = 0; /* terminator */
- if( num > 1024 )
+ if( num > 9999 )
{
char prefix = 0; /* try binary first, then si */
for( i = 0; i < n && num != 0 && num % 1024 == 0; ++i )
@@ -371,7 +371,7 @@ static const char * format_num3( unsigned long long num )
{ num /= 1000; prefix = si_prefix[i]; }
if( prefix ) *(--p) = prefix;
}
- const bool split = num >= 10000;
+ const bool split = num >= 100000;
for( i = 0; ; )
{
@@ -530,7 +530,7 @@ static int open_instream( const char * const name, struct stat * const in_statsp
if( program_mode == m_compress && !recompress && eindex >= 0 )
{
if( verbosity >= 0 )
- fprintf( stderr, "%s: %s: Input file already has '%s' suffix.\n",
+ fprintf( stderr, "%s: %s: Input file already has '%s' suffix, ignored.\n",
program_name, name, known_extensions[eindex].from );
return -1;
}
@@ -845,13 +845,15 @@ static int compress( const unsigned long long member_size,
static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
- struct Pretty_print * const pp, const bool ignore_trailing,
- const bool loose_trailing, const bool testing )
+ struct Pretty_print * const pp, const bool from_stdin,
+ const bool ignore_trailing, const bool loose_trailing,
+ const bool testing )
{
enum { buffer_size = 65536 };
uint8_t buffer[buffer_size]; /* read/write buffer */
unsigned long long total_in = 0; /* to detect library stall */
bool first_member;
+ bool empty = false, nonempty = false;
for( first_member = true; ; )
{
@@ -890,9 +892,11 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
else if( rd < 0 ) { out_size = rd; break; }
if( LZ_decompress_member_finished( decoder ) == 1 )
{
+ const unsigned long long data_size = LZ_decompress_data_position( decoder );
+ if( !from_stdin )
+ { if( data_size == 0 ) empty = true; else nonempty = true; }
if( verbosity >= 1 )
{
- const unsigned long long data_size = LZ_decompress_data_position( decoder );
const unsigned long long member_size = LZ_decompress_member_position( decoder );
if( verbosity >= 2 || ( verbosity == 1 && first_member ) )
Pp_show_msg( pp, 0 );
@@ -943,6 +947,8 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
LZ_decompress_member_version( decoder ) ); } }
else if( member_pos == 5 )
Pp_show_msg( pp, "Invalid dictionary size in member header." );
+ else if( member_pos == 6 )
+ Pp_show_msg( pp, "Nonzero first LZMA byte." );
else if( first_member ) /* for lzlib older than 1.10 */
Pp_show_msg( pp, "Bad version or dictionary size in member header." );
else if( !loose_trailing )
@@ -982,12 +988,14 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
}
}
if( verbosity == 1 ) fputs( testing ? "ok\n" : "done\n", stderr );
+ if( empty && nonempty )
+ { show_file_error( pp->name, "Empty member not allowed.", 0 ); return 2; }
return 0;
}
static int decompress( const int infd, struct Pretty_print * const pp,
- const bool ignore_trailing,
+ const bool from_stdin, const bool ignore_trailing,
const bool loose_trailing, const bool testing )
{
struct LZ_Decoder * const decoder = LZ_decompress_open();
@@ -995,7 +1003,7 @@ static int decompress( const int infd, struct Pretty_print * const pp,
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok )
{ Pp_show_msg( pp, mem_msg ); retval = 1; }
- else retval = do_decompress( decoder, infd, pp, ignore_trailing,
+ else retval = do_decompress( decoder, infd, pp, from_stdin, ignore_trailing,
loose_trailing, testing );
LZ_decompress_close( decoder );
return retval;
@@ -1098,7 +1106,7 @@ int main( const int argc, const char * const argv[] )
{ 'V', "version", ap_no },
{ opt_chk, "check-lib", ap_no },
{ opt_lt, "loose-trailing", ap_no },
- { 0, 0, ap_no } };
+ { 0, 0, ap_no } };
/* static because valgrind complains and memory management in C sucks */
static struct Arg_parser parser;
@@ -1116,8 +1124,8 @@ int main( const int argc, const char * const argv[] )
const char * const arg = ap_argument( &parser, argind );
switch( code )
{
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
encoder_options = option_mapping[code-'0']; break;
case 'a': ignore_trailing = false; break;
case 'b': member_size = getnum( arg, pn, 100000, max_member_size ); break;
@@ -1130,7 +1138,7 @@ int main( const int argc, const char * const argv[] )
case 'm': encoder_options.match_len_limit =
getnum( arg, pn, LZ_min_match_len_limit(),
LZ_max_match_len_limit() ); break;
- case 'n': break;
+ case 'n': break; /* ignored */
case 'o': if( strcmp( arg, "-" ) == 0 ) to_stdout = true;
else { default_output_filename = arg; } break;
case 'q': verbosity = -1; break;
@@ -1212,9 +1220,10 @@ int main( const int argc, const char * const argv[] )
{
const char * input_filename = "";
int infd;
+ const bool from_stdin = strcmp( filenames[i], "-" ) == 0;
Pp_set_name( &pp, filenames[i] );
- if( strcmp( filenames[i], "-" ) == 0 )
+ if( from_stdin )
{
if( stdin_used ) continue; else stdin_used = true;
infd = STDIN_FILENO;
@@ -1260,7 +1269,7 @@ int main( const int argc, const char * const argv[] )
tmp = compress( member_size, volume_size, infd, &encoder_options, &pp,
in_statsp );
else
- tmp = decompress( infd, &pp, ignore_trailing, loose_trailing,
+ tmp = decompress( infd, &pp, from_stdin, ignore_trailing, loose_trailing,
program_mode == m_test );
if( close( infd ) != 0 )
{ show_file_error( pp.name, "Error closing input file", errno );
diff --git a/testsuite/check.sh b/testsuite/check.sh
index 1c5daf7..21f6def 100755
--- a/testsuite/check.sh
+++ b/testsuite/check.sh
@@ -31,11 +31,11 @@ if [ -d tmp ] ; then rm -rf tmp ; fi
mkdir tmp
cd "${objdir}"/tmp || framework_failure
-cat "${testdir}"/test.txt > in || framework_failure
+cp "${testdir}"/test.txt in || framework_failure
in_lz="${testdir}"/test.txt.lz
-in_em="${testdir}"/test_em.txt.lz
fox_lf="${testdir}"/fox_lf
fox_lz="${testdir}"/fox.lz
+fnz_lz="${testdir}"/fox_nz.lz
fail=0
test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
@@ -105,7 +105,7 @@ printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null
printf "\ntesting decompression..."
-for i in "${in_lz}" "${in_em}" "${testdir}"/test_sync.lz ; do
+for i in "${in_lz}" "${testdir}"/test_sync.lz ; do
"${LZIP}" -t "$i" || test_failed $LINENO "$i"
"${LZIP}" -d "$i" -o out || test_failed $LINENO "$i"
cmp in out || test_failed $LINENO "$i"
@@ -118,16 +118,13 @@ for i in "${in_lz}" "${in_em}" "${testdir}"/test_sync.lz ; do
rm -f out || framework_failure
done
-lines=`"${LZIP}" -tvv "${in_em}" 2>&1 | wc -l` || test_failed $LINENO
-[ "${lines}" -eq 8 ] || test_failed $LINENO "${lines}"
-
-cat "${in_lz}" > out.lz || framework_failure
+cp "${in_lz}" out.lz || framework_failure
"${LZIP}" -dk out.lz || test_failed $LINENO
cmp in out || test_failed $LINENO
rm -f out || framework_failure
"${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO
-cat fox > copy || framework_failure
-cat "${in_lz}" > copy.lz || framework_failure
+cp fox copy || framework_failure
+cp "${in_lz}" copy.lz || framework_failure
"${LZIP}" -d copy.lz out.lz 2> /dev/null # skip copy, decompress out
[ $? = 1 ] || test_failed $LINENO
[ ! -e out.lz ] || test_failed $LINENO
@@ -138,7 +135,7 @@ cmp in out || test_failed $LINENO
cmp in copy || test_failed $LINENO
rm -f copy out || framework_failure
-cat "${in_lz}" > out.lz || framework_failure
+cp "${in_lz}" out.lz || framework_failure
"${LZIP}" -d -S100k out.lz || test_failed $LINENO # ignore -S
[ ! -e out.lz ] || test_failed $LINENO
cmp in out || test_failed $LINENO
@@ -154,7 +151,7 @@ rm -f ./- || framework_failure
cmp in ./- || test_failed $LINENO
rm -f ./- || framework_failure
-cat "${in_lz}" > anyothername || framework_failure
+cp "${in_lz}" anyothername || framework_failure
"${LZIP}" -dv - anyothername - < "${in_lz}" > out 2> /dev/null ||
test_failed $LINENO
cmp in out || test_failed $LINENO
@@ -172,7 +169,7 @@ cat out in | cmp in - || test_failed $LINENO # out must be empty
[ $? = 1 ] || test_failed $LINENO
cmp in out || test_failed $LINENO
rm -f out || framework_failure
-cat "${in_lz}" > out.lz || framework_failure
+cp "${in_lz}" out.lz || framework_failure
for i in 1 2 3 4 5 6 7 ; do
printf "g" >> out.lz || framework_failure
"${LZIP}" -atvvvv out.lz "${in_lz}" 2> /dev/null
@@ -201,6 +198,9 @@ cmp in2 out2 || test_failed $LINENO
rm -f out2 || framework_failure
cat "${in_lz}" "${in_lz}" > out2.lz || framework_failure
+lines=`"${LZIP}" -tvv out2.lz 2>&1 | wc -l` || test_failed $LINENO
+[ "${lines}" -eq 2 ] || test_failed $LINENO "${lines}"
+
printf "\ngarbage" >> out2.lz || framework_failure
"${LZIP}" -tvvvv out2.lz 2> /dev/null || test_failed $LINENO
"${LZIP}" -atq out2.lz
@@ -218,6 +218,18 @@ printf "to be overwritten" > out2 || framework_failure
cmp in2 out2 || test_failed $LINENO
rm -f out2 || framework_failure
+touch empty em || framework_failure
+"${LZIP}" -0 em || test_failed $LINENO
+"${LZIP}" -dk em.lz || test_failed $LINENO
+cmp empty em || test_failed $LINENO
+rm -f empty em || framework_failure
+cat em.lz "${in_lz}" | "${LZIP}" -t || test_failed $LINENO
+cat em.lz "${in_lz}" | "${LZIP}" -d > out || test_failed $LINENO
+cmp in out || test_failed $LINENO
+cat "${in_lz}" em.lz | "${LZIP}" -t || test_failed $LINENO
+cat "${in_lz}" em.lz | "${LZIP}" -d > out || test_failed $LINENO
+cmp in out || test_failed $LINENO
+
printf "\ntesting compression..."
"${LZIP}" -c -0 in in in -S100k -o out3.lz > copy2.lz || test_failed $LINENO
@@ -226,7 +238,7 @@ printf "\ntesting compression..."
"${LZIP}" -d copy2.lz -o out2 || test_failed $LINENO
[ -e copy2.lz ] || test_failed $LINENO
cmp in2 out2 || test_failed $LINENO
-rm -f out2 copy2.lz || framework_failure
+rm -f copy2.lz || framework_failure
"${LZIP}" -cf "${in_lz}" > lzlz 2> /dev/null # /dev/null is a tty on OS/2
[ $? = 1 ] || test_failed $LINENO
@@ -293,7 +305,7 @@ rm -f out out.lz00001.lz out.lz00002.lz || framework_failure
"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO
"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO
[ ! -e out00003.lz ] || test_failed $LINENO
-rm -f out00001.lz || framework_failure
+rm -f out00001.lz out00002.lz || framework_failure
"${LZIP}" -1 -S100k -o out < in8.lz || test_failed $LINENO
"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO
"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO
@@ -314,7 +326,8 @@ rm -f in8.lz in8.lz.lz || framework_failure
"${BBEXAMPLE}" "${fox_lf}" || test_failed $LINENO
"${FFEXAMPLE}" -h > /dev/null || test_failed $LINENO
-"${FFEXAMPLE}" > /dev/null && test_failed $LINENO
+"${FFEXAMPLE}" > /dev/null
+[ $? = 1 ] || test_failed $LINENO
rm -f out || framework_failure
"${FFEXAMPLE}" -b in out || test_failed $LINENO
cmp in out || test_failed $LINENO
@@ -322,7 +335,6 @@ cmp in out || test_failed $LINENO
"${FFEXAMPLE}" -b in8 | cmp in8 - || test_failed $LINENO
"${FFEXAMPLE}" -b "${fox_lf}" | cmp "${fox_lf}" - || test_failed $LINENO
"${FFEXAMPLE}" -d "${in_lz}" - | cmp in - || test_failed $LINENO
-"${FFEXAMPLE}" -d "${in_em}" - | cmp in - || test_failed $LINENO
"${FFEXAMPLE}" -c in | "${FFEXAMPLE}" -d | cmp in - || test_failed $LINENO
"${FFEXAMPLE}" -m in | "${FFEXAMPLE}" -d | cmp in - || test_failed $LINENO
"${FFEXAMPLE}" -l in | "${FFEXAMPLE}" -d | cmp in - || test_failed $LINENO
@@ -340,9 +352,23 @@ rm -f in8 || framework_failure
printf "\ntesting bad input..."
+cat "${in_lz}" em.lz "${in_lz}" > inein.lz || framework_failure
+"${LZIP}" -t < inein.lz || test_failed $LINENO
+"${LZIP}" -d < inein.lz > out2 || test_failed $LINENO
+cmp in2 out2 || test_failed $LINENO
+"${LZIP}" -tq inein.lz
+[ $? = 2 ] || test_failed $LINENO
+"${LZIP}" -dq inein.lz
+[ $? = 2 ] || test_failed $LINENO
+[ ! -e inein ] || test_failed $LINENO
+"${LZIP}" -cdq inein.lz > out2
+[ $? = 2 ] || test_failed $LINENO
+cmp in2 out2 || test_failed $LINENO
+rm -f out2 inein.lz || framework_failure
+
headers='LZIp LZiP LZip LzIP LzIp LziP lZIP lZIp lZiP lzIP'
-body='\001\014\000\203\377\373\377\377\300\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000\000\000\000\000'
-cat "${in_lz}" > int.lz || framework_failure
+body='\001\014\000\000\101\376\367\377\377\340\000\200\000\215\357\002\322\001\000\000\000\000\000\000\000\045\000\000\000\000\000\000\000'
+cp "${in_lz}" int.lz || framework_failure
printf "LZIP${body}" >> int.lz || framework_failure
if "${LZIP}" -tq int.lz ; then
for header in ${headers} ; do
@@ -359,7 +385,7 @@ if "${LZIP}" -tq int.lz ; then
[ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -cdq --loose-trailing int.lz > /dev/null
[ $? = 2 ] || test_failed $LINENO ${header}
- cat "${in_lz}" > int.lz || framework_failure
+ cp "${in_lz}" int.lz || framework_failure
printf "${header}${body}" >> int.lz || framework_failure
"${LZIP}" -tq int.lz # trailing data
[ $? = 2 ] || test_failed $LINENO ${header}
@@ -385,6 +411,9 @@ else
fi
rm -f int.lz || framework_failure
+"${LZIP}" -tq "${fnz_lz}"
+[ $? = 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
"${LZIP}" -tq "${testdir}"/$i
@@ -400,9 +429,9 @@ rm -f fox out || framework_failure
cat "${in_lz}" "${in_lz}" > in2.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
- for i in 6 20 14734 14753 14754 14755 14756 14757 14758 ; do
+ for i in 6 20 14664 14683 14684 14685 14686 14687 14688 ; do
dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null
"${LZIP}" -tq trunc.lz
[ $? = 2 ] || test_failed $LINENO $i
@@ -418,7 +447,7 @@ else
fi
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
cat "${in_lz}" >> ingin.lz || framework_failure
"${LZIP}" -atq ingin.lz
@@ -431,13 +460,15 @@ cat "${in_lz}" >> ingin.lz || framework_failure
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -t ingin.lz || test_failed $LINENO
"${LZIP}" -t < ingin.lz || test_failed $LINENO
+"${LZIP}" -dk ingin.lz || test_failed $LINENO
+cmp in ingin || test_failed $LINENO
"${LZIP}" -cd ingin.lz > out || test_failed $LINENO
cmp in out || test_failed $LINENO
"${LZIP}" -d < ingin.lz > out || test_failed $LINENO
cmp in out || test_failed $LINENO
"${FFEXAMPLE}" -d ingin.lz | cmp in - || test_failed $LINENO
"${FFEXAMPLE}" -r ingin.lz | cmp in2 - || test_failed $LINENO
-rm -f in2 out ingin.lz || framework_failure
+rm -f in2 out ingin ingin.lz || framework_failure
echo
if [ ${fail} = 0 ] ; then
diff --git a/testsuite/fox_nz.lz b/testsuite/fox_nz.lz
new file mode 100644
index 0000000..44a4b58
--- /dev/null
+++ b/testsuite/fox_nz.lz
Binary files differ
diff --git a/testsuite/test.txt b/testsuite/test.txt
index 9196a3a..423f0c0 100644
--- a/testsuite/test.txt
+++ b/testsuite/test.txt
@@ -1,8 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -339,8 +338,7 @@ Public License instead of this License.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/testsuite/test.txt.lz b/testsuite/test.txt.lz
index 22cea6e..5dc169f 100644
--- a/testsuite/test.txt.lz
+++ b/testsuite/test.txt.lz
Binary files differ
diff --git a/testsuite/test_em.txt.lz b/testsuite/test_em.txt.lz
deleted file mode 100644
index 7e96250..0000000
--- a/testsuite/test_em.txt.lz
+++ /dev/null
Binary files differ
diff --git a/testsuite/test_sync.lz b/testsuite/test_sync.lz
index db680c3..2a6218b 100644
--- a/testsuite/test_sync.lz
+++ b/testsuite/test_sync.lz
Binary files differ