1
0
Fork 0

Adding upstream version 0.9.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-17 22:53:36 +01:00
parent 7559b1f0d1
commit 4a3010ccc6
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
22 changed files with 270 additions and 201 deletions

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.

View file

@ -1,3 +1,11 @@
2025-01-06 Antonio Diaz Diaz <antonio@gnu.org>
* Version 0.9 released.
* main.c (decompress): Return 2 if empty member in multimember file.
(Pp_free): New function.
* lzip_decompress.c (Rd_load): Check first byte of the LZMA stream.
* check.sh: Use 'cp' instead of 'cat'.
2024-01-18 Antonio Diaz Diaz <antonio@gnu.org> 2024-01-18 Antonio Diaz Diaz <antonio@gnu.org>
* Version 0.8 released. * Version 0.8 released.
@ -67,8 +75,7 @@
* Tests the code shipped in linux patches before june 2018. * Tests the code shipped in linux patches before june 2018.
Copyright (C) 2016-2024 Antonio Diaz Diaz. Copyright (C) 2016-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

@ -3,7 +3,8 @@ Requirements
You will need a C99 compiler. (gcc 3.3.6 or newer is recommended). You will need a C99 compiler. (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
The operating system must allow signal handlers read access to objects with The operating system must allow signal handlers read access to objects with
static storage duration so that the cleanup handler for Control-C can delete static storage duration so that the cleanup handler for Control-C can delete
@ -74,7 +75,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above. explained above.
Copyright (C) 2016-2024 Antonio Diaz Diaz. Copyright (C) 2016-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
@ -30,7 +30,8 @@ main.o : main.c
# prevent 'make' from trying to remake source files # prevent 'make' from trying to remake source files
$(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ; $(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ;
%.h %.c : ; MAKEFLAGS += -r
.SUFFIXES :
$(objs) : Makefile $(objs) : Makefile
carg_parser.o : carg_parser.h carg_parser.o : carg_parser.h
@ -122,11 +123,10 @@ dist : doc
$(DISTNAME)/*.c \ $(DISTNAME)/*.c \
$(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/zero.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

21
NEWS
View file

@ -1,18 +1,7 @@
Changes in version 0.8: Changes in version 0.9:
File diagnostics have been reformatted as 'PROGRAM: FILE: MESSAGE'. xlunzip now exits with error status 2 if any empty member is found in a
multimember file.
In case of error in a numerical argument to a command line option, lunzip xlunzip now exits with error status 2 if the first byte of the LZMA stream
now shows the name of the option and the range of valid values. is not 0.
Diagnostics caused by invalid arguments to command-line options now show the
argument and the name of the option.
The option '-o, --output' now preserves dates, permissions, and ownership of
the file, when decompressing exactly one file.
The variable MAKEINFO has been added to configure and Makefile.in.
It has been documented in INSTALL that when choosing a C standard, the POSIX
features need to be enabled explicitly:
./configure CFLAGS+='--std=c99 -D_XOPEN_SOURCE=500'

8
README
View file

@ -1,3 +1,5 @@
See the file INSTALL for compilation and installation instructions.
Description Description
Xlunzip is a test tool for the lzip decompression code of my lzip patch for Xlunzip is a test tool for the lzip decompression code of my lzip patch for
@ -98,7 +100,11 @@ memory for compression ratios larger than 4:1, and does not even consider
multimember data. multimember data.
Copyright (C) 2016-2024 Antonio Diaz Diaz. Xlunzip uses Arg_parser for command-line argument parsing:
http://www.nongnu.org/arg-parser/arg_parser.html
Copyright (C) 2016-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

@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command-line argument parser. (C version) /* Arg_parser - POSIX/GNU command-line argument parser. (C version)
Copyright (C) 2006-2024 Antonio Diaz Diaz. Copyright (C) 2006-2025 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and This library 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
@ -32,15 +32,15 @@ static void * ap_resize_buffer( void * buf, const int min_size )
} }
static char push_back_record( struct Arg_parser * const ap, const int code, static char push_back_record( Arg_parser * const ap, const int code,
const char * const long_name, const char * const long_name,
const char * const argument ) const char * const argument )
{ {
struct ap_Record * p; ap_Record * p;
void * tmp = ap_resize_buffer( ap->data, void * tmp = ap_resize_buffer( ap->data,
( ap->data_size + 1 ) * sizeof (struct ap_Record) ); ( ap->data_size + 1 ) * sizeof (ap_Record) );
if( !tmp ) return 0; if( !tmp ) return 0;
ap->data = (struct ap_Record *)tmp; ap->data = (ap_Record *)tmp;
p = &(ap->data[ap->data_size]); p = &(ap->data[ap->data_size]);
p->code = code; p->code = code;
if( long_name ) if( long_name )
@ -71,7 +71,7 @@ static char push_back_record( struct Arg_parser * const ap, const int code,
} }
static char add_error( struct Arg_parser * const ap, const char * const msg ) static char add_error( Arg_parser * const ap, const char * const msg )
{ {
const int len = strlen( msg ); const int len = strlen( msg );
void * tmp = ap_resize_buffer( ap->error, ap->error_size + len + 1 ); void * tmp = ap_resize_buffer( ap->error, ap->error_size + len + 1 );
@ -83,7 +83,7 @@ static char add_error( struct Arg_parser * const ap, const char * const msg )
} }
static void free_data( struct Arg_parser * const ap ) static void free_data( Arg_parser * const ap )
{ {
int i; int i;
for( i = 0; i < ap->data_size; ++i ) for( i = 0; i < ap->data_size; ++i )
@ -94,10 +94,9 @@ static void free_data( struct Arg_parser * const ap )
/* Return 0 only if out of memory. */ /* Return 0 only if out of memory. */
static char parse_long_option( struct Arg_parser * const ap, static char parse_long_option( Arg_parser * const ap,
const char * const opt, const char * const arg, const char * const opt, const char * const arg,
const struct ap_Option options[], const ap_Option options[], int * const argindp )
int * const argindp )
{ {
unsigned len; unsigned len;
int index = -1, i; int index = -1, i;
@ -148,21 +147,21 @@ static char parse_long_option( struct Arg_parser * const ap,
add_error( ap, "' requires an argument" ); add_error( ap, "' requires an argument" );
return 1; return 1;
} }
return push_back_record( ap, options[index].code, return push_back_record( ap, options[index].code, options[index].long_name,
options[index].long_name, &opt[len+3] ); &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, "option '--" ); add_error( ap, options[index].long_name );
add_error( ap, "' requires an argument" ); add_error( ap, "' requires an argument" );
return 1; return 1;
} }
++*argindp; ++*argindp;
return push_back_record( ap, options[index].code, return push_back_record( ap, options[index].code, options[index].long_name,
options[index].long_name, arg ); arg ); /* argument may be empty */
} }
return push_back_record( ap, options[index].code, return push_back_record( ap, options[index].code,
@ -171,10 +170,9 @@ static char parse_long_option( struct Arg_parser * const ap,
/* Return 0 only if out of memory. */ /* Return 0 only if out of memory. */
static char parse_short_option( struct Arg_parser * const ap, static char parse_short_option( Arg_parser * const ap,
const char * const opt, const char * const arg, const char * const opt, const char * const arg,
const struct ap_Option options[], const ap_Option options[], int * const argindp )
int * const argindp )
{ {
int cind = 1; /* character index in opt */ int cind = 1; /* character index in opt */
@ -204,15 +202,15 @@ static char parse_short_option( struct Arg_parser * const ap,
if( !push_back_record( ap, c, 0, &opt[cind] ) ) return 0; if( !push_back_record( ap, c, 0, &opt[cind] ) ) return 0;
++*argindp; cind = 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, "option requires an argument -- '" );
add_error( ap, code_str ); add_error( ap, "'" ); add_error( ap, code_str ); add_error( ap, "'" );
return 1; return 1;
} }
++*argindp; cind = 0; ++*argindp; cind = 0; /* argument may be empty */
if( !push_back_record( ap, c, 0, arg ) ) return 0; if( !push_back_record( ap, c, 0, arg ) ) return 0;
} }
else if( !push_back_record( ap, c, 0, 0 ) ) return 0; else if( !push_back_record( ap, c, 0, 0 ) ) return 0;
@ -221,9 +219,9 @@ static char parse_short_option( struct Arg_parser * const ap,
} }
char ap_init( struct Arg_parser * const ap, char ap_init( Arg_parser * const ap,
const int argc, const char * const argv[], const int argc, const char * const argv[],
const struct ap_Option options[], const char in_order ) const ap_Option options[], const char in_order )
{ {
const char ** non_options = 0; /* skipped non-options */ const char ** non_options = 0; /* skipped non-options */
int non_options_size = 0; /* number of skipped non-options */ int non_options_size = 0; /* number of skipped non-options */
@ -282,7 +280,7 @@ out: if( non_options ) free( non_options );
} }
void ap_free( struct Arg_parser * const ap ) void ap_free( Arg_parser * const ap )
{ {
free_data( ap ); free_data( ap );
if( ap->error ) { free( ap->error ); ap->error = 0; } if( ap->error ) { free( ap->error ); ap->error = 0; }
@ -290,29 +288,25 @@ void ap_free( struct Arg_parser * const ap )
} }
const char * ap_error( const struct Arg_parser * const ap ) const char * ap_error( const Arg_parser * const ap ) { return ap->error; }
{ return ap->error; }
int ap_arguments( const Arg_parser * const ap ) { return ap->data_size; }
int ap_arguments( const struct Arg_parser * const ap ) int ap_code( const Arg_parser * const ap, const int i )
{ return ap->data_size; }
int ap_code( const struct Arg_parser * const ap, const int i )
{ {
if( i < 0 || i >= ap_arguments( ap ) ) return 0; if( i < 0 || i >= ap_arguments( ap ) ) return 0;
return ap->data[i].code; return ap->data[i].code;
} }
const char * ap_parsed_name( const struct Arg_parser * const ap, const int i ) const char * ap_parsed_name( const Arg_parser * const ap, const int i )
{ {
if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].parsed_name ) return ""; if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].parsed_name ) return "";
return ap->data[i].parsed_name; return ap->data[i].parsed_name;
} }
const char * ap_argument( const struct Arg_parser * const ap, const int i ) const char * ap_argument( const Arg_parser * const ap, const int i )
{ {
if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].argument ) return ""; if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].argument ) return "";
return ap->data[i].argument; return ap->data[i].argument;

View file

@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command-line argument parser. (C version) /* Arg_parser - POSIX/GNU command-line argument parser. (C version)
Copyright (C) 2006-2024 Antonio Diaz Diaz. Copyright (C) 2006-2025 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and This library 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
@ -37,60 +37,65 @@
The argument '--' terminates all options; any following arguments are The argument '--' terminates all options; any following arguments are
treated as non-option arguments, even if they begin with a hyphen. treated as non-option arguments, even if they begin with a hyphen.
The syntax for optional option arguments is '-<short_option><argument>' The syntax of options with an optional argument is
(without whitespace), or '--<long_option>=<argument>'. '-<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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
enum ap_Has_arg { ap_no, ap_yes, ap_maybe }; /* ap_yme = yes but maybe empty */
typedef enum ap_Has_arg { ap_no, ap_yes, ap_maybe, ap_yme } ap_Has_arg;
struct ap_Option typedef struct ap_Option
{ {
int code; /* Short option letter or code ( code != 0 ) */ int code; /* Short option letter or code ( code != 0 ) */
const char * long_name; /* Long option name (maybe null) */ const char * long_name; /* Long option name (maybe null) */
enum ap_Has_arg has_arg; ap_Has_arg has_arg;
}; } ap_Option;
struct ap_Record typedef struct ap_Record
{ {
int code; int code;
char * parsed_name; char * parsed_name;
char * argument; char * argument;
}; } ap_Record;
struct Arg_parser typedef struct Arg_parser
{ {
struct ap_Record * data; ap_Record * data;
char * error; char * error;
int data_size; int data_size;
int error_size; int error_size;
}; } Arg_parser;
char ap_init( struct Arg_parser * const ap, char ap_init( Arg_parser * const ap,
const int argc, const char * const argv[], const int argc, const char * const argv[],
const struct ap_Option options[], const char in_order ); const ap_Option options[], const char in_order );
void ap_free( struct Arg_parser * const ap ); void ap_free( Arg_parser * const ap );
const char * ap_error( const struct Arg_parser * const ap ); const char * ap_error( const Arg_parser * const ap );
/* The number of arguments parsed. May be different from argc. */ /* The number of arguments parsed. May be different from argc. */
int ap_arguments( const struct Arg_parser * const ap ); int ap_arguments( const Arg_parser * const ap );
/* If ap_code( i ) is 0, ap_argument( i ) is a non-option. /* If ap_code( i ) is 0, ap_argument( i ) is a non-option.
Else ap_argument( i ) is the option's argument (or empty). */ Else ap_argument( i ) is the option's argument (or empty). */
int ap_code( const struct Arg_parser * const ap, const int i ); int ap_code( const Arg_parser * const ap, const int i );
/* Full name of the option parsed (short or long). */ /* Full name of the option parsed (short or long). */
const char * ap_parsed_name( const struct Arg_parser * const ap, const int i ); const char * ap_parsed_name( const Arg_parser * const ap, const int i );
const char * ap_argument( const struct Arg_parser * const ap, const int i ); const char * ap_argument( const Arg_parser * const ap, const int i );
#ifdef __cplusplus #ifdef __cplusplus
} }

8
configure vendored
View file

@ -1,12 +1,12 @@
#! /bin/sh #! /bin/sh
# configure script for Xlunzip - Test tool for the lzip_decompress linux module # configure script for Xlunzip - Test tool for the lzip_decompress linux module
# Copyright (C) 2016-2024 Antonio Diaz Diaz. # Copyright (C) 2016-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=xlunzip pkgname=xlunzip
pkgversion=0.8 pkgversion=0.9
progname=xlunzip progname=xlunzip
srctrigger=doc/${progname}.1 srctrigger=doc/${progname}.1
@ -109,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
@ -171,7 +171,7 @@ echo "MAKEINFO = ${MAKEINFO}"
rm -f Makefile rm -f Makefile
cat > Makefile << EOF cat > Makefile << EOF
# Makefile for Xlunzip - Test tool for the lzip_decompress linux module # Makefile for Xlunzip - Test tool for the lzip_decompress linux module
# Copyright (C) 2016-2024 Antonio Diaz Diaz. # Copyright (C) 2016-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

View file

@ -1,7 +1,7 @@
/* /*
* Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
* *
* Copyright (C) 2016-2024 Antonio Diaz Diaz. * Copyright (C) 2016-2025 Antonio Diaz Diaz.
* *
* Licensed under GPLv2 or later, see file LICENSE in this source tree. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/ */
@ -62,6 +62,9 @@ STATIC int INIT __lunzip(unsigned char *inbuf, long in_len,
case LZIP_BAD_CRC: case LZIP_BAD_CRC:
error("CRC mismatch in LZIP-compressed data."); error("CRC mismatch in LZIP-compressed data.");
break; break;
case LZIP_EMPTY_MEMBER:
error("Empty member in LZIP multimember data.");
break;
default: error("Bug in the LZIP decompressor."); default: error("Bug in the LZIP decompressor.");
} }
return retval; return retval;

View file

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
.TH XLUNZIP "1" "January 2024" "xlunzip 0.8" "User Commands" .TH XLUNZIP "1" "January 2025" "xlunzip 0.9" "User Commands"
.SH NAME .SH NAME
xlunzip \- test tool for the lzip_decompress linux module xlunzip \- test tool for the lzip_decompress linux module
.SH SYNOPSIS .SH SYNOPSIS
@ -86,7 +86,7 @@ Report bugs to lzip\-bug@nongnu.org
.br .br
Xlunzip home page: http://www.nongnu.org/lzip/xlunzip.html Xlunzip home page: http://www.nongnu.org/lzip/xlunzip.html
.SH COPYRIGHT .SH COPYRIGHT
Copyright \(co 2024 Antonio Diaz Diaz. Copyright \(co 2025 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html> License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br .br
This is free software: you are free to change and redistribute it. This is free software: you are free to change and redistribute it.

View file

@ -1,5 +1,5 @@
/* Xlunzip - Test tool for the lzip_decompress linux module /* Xlunzip - Test tool for the lzip_decompress linux module
Copyright (C) 2016-2024 Antonio Diaz Diaz. Copyright (C) 2016-2025 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -95,7 +95,7 @@ static const char * set_file_sizes( struct File_sizes * const file_sizes,
const unsigned long file_size ) const unsigned long file_size )
{ {
if( file_size <= Lh_size ) return "File ends unexpectedly at member header."; if( file_size <= Lh_size ) return "File ends unexpectedly at member header.";
if( file_size < min_member_size ) return "Input file is too short."; if( file_size < min_member_size ) return "Input file is truncated.";
const Lzip_header * header = (const Lzip_header *)buffer; const Lzip_header * header = (const Lzip_header *)buffer;
if( !Lh_check_magic( *header ) ) if( !Lh_check_magic( *header ) )
return "Bad magic number (file not in lzip format)."; return "Bad magic number (file not in lzip format).";
@ -167,7 +167,7 @@ static void error(char *x) { show_file_error( global_name, x, 0 ); }
* |-------- decompressed data ---------| * |-------- decompressed data ---------|
*/ */
int decompress_in_place( const int infd, struct Pretty_print * const pp, int decompress_in_place( const int infd, Pretty_print * const pp,
const bool testing ) const bool testing )
{ {
long buffer_size = 0, file_size = 0; long buffer_size = 0, file_size = 0;

View file

@ -4,7 +4,7 @@
/* /*
* LZIP decompressor * LZIP decompressor
* *
* Copyright (C) 2016-2024 Antonio Diaz Diaz. * Copyright (C) 2016-2025 Antonio Diaz Diaz.
*/ */
/* Return values (< 0 = Error) */ /* Return values (< 0 = Error) */
@ -20,7 +20,8 @@ enum {
LZIP_WRITE_ERROR = -9, LZIP_WRITE_ERROR = -9,
LZIP_BAD_DATA = -10, LZIP_BAD_DATA = -10,
LZIP_DATA_EOF = -11, LZIP_DATA_EOF = -11,
LZIP_BAD_CRC = -12 LZIP_BAD_CRC = -12,
LZIP_EMPTY_MEMBER = -13
}; };
int lzip_decompress(unsigned char *inbuf, long in_len, int lzip_decompress(unsigned char *inbuf, long in_len,

10
lzip.h
View file

@ -1,5 +1,5 @@
/* Xlunzip - Test tool for the lzip_decompress linux module /* Xlunzip - Test tool for the lzip_decompress linux module
Copyright (C) 2016-2024 Antonio Diaz Diaz. Copyright (C) 2016-2025 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -30,14 +30,14 @@ enum {
min_member_size = 36 }; min_member_size = 36 };
struct Pretty_print typedef struct Pretty_print
{ {
const char * name; const char * name;
char * padded_name; char * padded_name;
const char * stdin_name; const char * stdin_name;
unsigned longest_name; unsigned longest_name;
bool first_post; bool first_post;
}; } Pretty_print;
static const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */ static const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
@ -81,13 +81,13 @@ static inline void set_retval( int * retval, const int new_val )
static const char * const mem_msg = "Not enough memory."; static const char * const mem_msg = "Not enough memory.";
/* defined in in_place.c */ /* defined in in_place.c */
int decompress_in_place( const int infd, struct Pretty_print * const pp, int decompress_in_place( const int infd, Pretty_print * const pp,
const bool testing ); const bool testing );
/* defined in main.c */ /* defined in main.c */
int convert_retval( const int retval ); int convert_retval( const int retval );
long flush( void * buf, unsigned long size ); long flush( void * buf, unsigned long size );
void show_results( struct Pretty_print * const pp, const long in_pos, void show_results( Pretty_print * const pp, const long in_pos,
const long out_pos, const bool testing ); const long out_pos, const bool testing );
void show_file_error( const char * const filename, const char * const msg, void show_file_error( const char * const filename, const char * const msg,
const int errcode ); const int errcode );

View file

@ -1,7 +1,7 @@
/* /*
* LZIP decompressor * LZIP decompressor
* *
* Copyright (C) 2016-2024 Antonio Diaz Diaz. * Copyright (C) 2016-2025 Antonio Diaz Diaz.
* *
* Licensed under GPLv2 or later, see file LICENSE in this source tree. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/ */
@ -40,7 +40,7 @@ static inline State St_set_rep(const State st)
return (st < 7) ? 8 : 11; return (st < 7) ? 8 : 11;
} }
static inline State St_set_short_rep(const State st) static inline State St_set_shortrep(const State st)
{ {
return (st < 7) ? 9 : 11; return (st < 7) ? 9 : 11;
} }
@ -359,14 +359,17 @@ static inline uint8_t Rd_get_byte(struct Range_decoder * const rdec)
return rdec->buffer[rdec->pos++]; return rdec->buffer[rdec->pos++];
} }
static inline void Rd_load(struct Range_decoder * const rdec) static inline bool Rd_load(struct Range_decoder * const rdec)
{ {
int i; int i;
rdec->code = 0; rdec->code = 0;
rdec->range = 0xFFFFFFFFU; rdec->range = 0xFFFFFFFFU;
Rd_get_byte(rdec); /* discard first byte of the LZMA stream */ /* check first byte of the LZMA stream */
if (Rd_get_byte(rdec) != 0)
return false;
for (i = 0; i < 4; ++i) rdec->code = (rdec->code << 8) | Rd_get_byte(rdec); for (i = 0; i < 4; ++i) rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
return true;
} }
static inline void Rd_normalize(struct Range_decoder * const rdec) static inline void Rd_normalize(struct Range_decoder * const rdec)
@ -693,7 +696,8 @@ static int LZd_decode_member(struct LZ_decoder * const d)
unsigned rep3 = 0; unsigned rep3 = 0;
State state = 0; State state = 0;
Rd_load(rdec); if (!Rd_load(rdec))
return LZIP_BAD_DATA;
while (!Rd_finished(rdec)) { while (!Rd_finished(rdec)) {
int len; int len;
const int pos_state = LZd_data_position(d) & pos_state_mask; const int pos_state = LZd_data_position(d) & pos_state_mask;
@ -715,7 +719,7 @@ static int LZd_decode_member(struct LZ_decoder * const d)
if (Rd_decode_bit(rdec, &d->bm_rep[state]) != 0) { if (Rd_decode_bit(rdec, &d->bm_rep[state]) != 0) {
if (Rd_decode_bit(rdec, &d->bm_rep0[state]) == 0) { if (Rd_decode_bit(rdec, &d->bm_rep0[state]) == 0) {
if (Rd_decode_bit(rdec, &d->bm_len[state][pos_state]) == 0) { if (Rd_decode_bit(rdec, &d->bm_len[state][pos_state]) == 0) {
state = St_set_short_rep(state); state = St_set_shortrep(state);
LZd_put_byte(d, LZd_peek(d, rep0)); LZd_put_byte(d, LZd_peek(d, rep0));
continue; continue;
} }
@ -739,23 +743,21 @@ static int LZd_decode_member(struct LZ_decoder * const d)
state = St_set_rep(state); state = St_set_rep(state);
len = Rd_decode_len(rdec, &d->rep_len_model, pos_state); len = Rd_decode_len(rdec, &d->rep_len_model, pos_state);
} else { /* match */ } else { /* match */
unsigned distance; rep3 = rep2; rep2 = rep1; rep1 = rep0;
len = Rd_decode_len(rdec, &d->match_len_model, pos_state); len = Rd_decode_len(rdec, &d->match_len_model, pos_state);
distance = Rd_decode_tree6(rdec, d->bm_dis_slot[get_len_state(len)]); rep0 = Rd_decode_tree6(rdec, d->bm_dis_slot[get_len_state(len)]);
if (distance >= start_dis_model) { if (rep0 >= start_dis_model) {
const unsigned dis_slot = distance; const unsigned dis_slot = rep0;
const int direct_bits = (dis_slot >> 1) - 1; const int direct_bits = (dis_slot >> 1) - 1;
distance = (2 | (dis_slot & 1)) << direct_bits; rep0 = (2 | (dis_slot & 1)) << direct_bits;
if (dis_slot < end_dis_model) if (dis_slot < end_dis_model)
distance += Rd_decode_tree_reversed(rdec, rep0 += Rd_decode_tree_reversed(rdec,
d->bm_dis + (distance - dis_slot), direct_bits); d->bm_dis + (rep0 - dis_slot), direct_bits);
else { else {
distance += rep0 += Rd_decode(rdec, direct_bits - dis_align_bits) << dis_align_bits;
Rd_decode(rdec, direct_bits - dis_align_bits) << dis_align_bits; rep0 += Rd_decode_tree_reversed4(rdec, d->bm_align);
distance += Rd_decode_tree_reversed4(rdec, d->bm_align); if (rep0 == 0xFFFFFFFFU) { /* marker found */
if (distance == 0xFFFFFFFFU) { /* marker found */
Rd_normalize(rdec); Rd_normalize(rdec);
LZd_flush_data(d); LZd_flush_data(d);
if (d->write_error) if (d->write_error)
@ -770,7 +772,6 @@ static int LZd_decode_member(struct LZ_decoder * const d)
} }
} }
} }
rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
state = St_set_match(state); state = St_set_match(state);
if (rep0 >= d->dictionary_size || if (rep0 >= d->dictionary_size ||
(rep0 >= d->pos && !d->pos_wrapped)) { (rep0 >= d->pos && !d->pos_wrapped)) {
@ -796,6 +797,7 @@ int lzip_decompress(unsigned char *inbuf, long in_len,
struct LZ_decoder *decoder = 0; struct LZ_decoder *decoder = 0;
int retval = 0; int retval = 0;
bool first_member; bool first_member;
bool empty = false, multi = false;
if (in_posp) if (in_posp)
*in_posp = 0; *in_posp = 0;
@ -849,7 +851,9 @@ int lzip_decompress(unsigned char *inbuf, long in_len,
retval = LZd_decode_member(decoder); retval = LZd_decode_member(decoder);
if (in_posp) if (in_posp)
*in_posp += Rd_member_position(&rdec); *in_posp += Rd_member_position(&rdec);
multi = !first_member;
data_pos = LZd_data_position(decoder); data_pos = LZd_data_position(decoder);
if (data_pos == 0) empty = true;
if (outptr) if (outptr)
outptr += data_pos; outptr += data_pos;
if (out_posp) if (out_posp)
@ -863,6 +867,8 @@ int lzip_decompress(unsigned char *inbuf, long in_len,
if (decoder) if (decoder)
free(decoder); free(decoder);
Rd_free(&rdec); Rd_free(&rdec);
if (empty && multi && retval == 0)
retval = LZIP_EMPTY_MEMBER;
return retval; return retval;
} }

58
main.c
View file

@ -1,5 +1,5 @@
/* Xlunzip - Test tool for the lzip_decompress linux module /* Xlunzip - Test tool for the lzip_decompress linux module
Copyright (C) 2016-2024 Antonio Diaz Diaz. Copyright (C) 2016-2025 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> /* SSIZE_MAX */ #include <limits.h> /* CHAR_BIT, SSIZE_MAX */
#include <signal.h> #include <signal.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> /* SIZE_MAX */ #include <stdint.h> /* SIZE_MAX */
@ -80,7 +80,7 @@ static void show_error( const char * const msg, const int errcode,
const bool help ); const bool help );
static const char * const program_name = "xlunzip"; static const char * const program_name = "xlunzip";
static const char * const program_year = "2024"; static const char * const program_year = "2025";
static const char * invocation_name = "xlunzip"; /* default value */ static const char * invocation_name = "xlunzip"; /* default value */
static const struct { const char * from; const char * to; } known_extensions[] = { static const struct { const char * from; const char * to; } known_extensions[] = {
@ -164,7 +164,7 @@ static void * resize_buffer( void * buf, const unsigned min_size )
} }
static void Pp_init( struct Pretty_print * const pp, static void Pp_init( Pretty_print * const pp,
const char * const filenames[], const int num_filenames ) const char * const filenames[], const int num_filenames )
{ {
pp->name = 0; pp->name = 0;
@ -185,8 +185,10 @@ static void Pp_init( struct Pretty_print * const pp,
if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len; if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len;
} }
static void Pp_set_name( struct Pretty_print * const pp, void Pp_free( Pretty_print * const pp )
const char * const filename ) { if( pp->padded_name ) { free( pp->padded_name ); pp->padded_name = 0; } }
static void Pp_set_name( Pretty_print * const pp, const char * const filename )
{ {
unsigned name_len, padded_name_len, i = 0; unsigned name_len, padded_name_len, i = 0;
@ -204,7 +206,7 @@ static void Pp_set_name( struct Pretty_print * const pp,
pp->first_post = true; pp->first_post = true;
} }
static void Pp_show_msg( struct Pretty_print * const pp, const char * const msg ) static void Pp_show_msg( Pretty_print * const pp, const char * const msg )
{ {
if( verbosity < 0 ) return; if( verbosity < 0 ) return;
if( pp->first_post ) if( pp->first_post )
@ -229,7 +231,7 @@ static const char * format_num3( unsigned long long num )
char * const buf = buffer[current++]; current %= buffers; char * const buf = buffer[current++]; current %= buffers;
char * p = buf + bufsize - 1; /* fill the buffer backwards */ char * p = buf + bufsize - 1; /* fill the buffer backwards */
*p = 0; /* terminator */ *p = 0; /* terminator */
if( num > 1024 ) if( num > 9999 )
{ {
char prefix = 0; /* try binary first, then si */ char prefix = 0; /* try binary first, then si */
for( i = 0; i < n && num != 0 && num % 1024 == 0; ++i ) for( i = 0; i < n && num != 0 && num % 1024 == 0; ++i )
@ -275,7 +277,7 @@ static unsigned long getnum( const char * const arg,
if( !errno && tail[0] ) if( !errno && tail[0] )
{ {
const unsigned factor = ( tail[1] == 'i' ) ? 1024 : 1000; const unsigned factor = (tail[1] == 'i') ? 1024 : 1000;
int exponent = 0; /* 0 = bad multiplier */ int exponent = 0; /* 0 = bad multiplier */
int i; int i;
switch( tail[0] ) switch( tail[0] )
@ -365,9 +367,9 @@ static int open_instream( const char * const name, struct stat * const in_statsp
{ {
const int i = fstat( infd, in_statsp ); const int i = fstat( infd, in_statsp );
const mode_t mode = in_statsp->st_mode; const mode_t mode = in_statsp->st_mode;
const bool can_read = ( i == 0 && const bool can_read = i == 0 &&
( S_ISBLK( mode ) || S_ISCHR( mode ) || ( S_ISBLK( mode ) || S_ISCHR( mode ) ||
S_ISFIFO( mode ) || S_ISSOCK( mode ) ) ); S_ISFIFO( mode ) || S_ISSOCK( mode ) );
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) ) if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
@ -482,10 +484,10 @@ int convert_retval( const int retval )
{ {
switch( retval ) switch( retval )
{ {
case 0: return 0; case 0: return 0;
case LZIP_OOM_INBUF: case LZIP_OOM_INBUF:
case LZIP_OOM_OUTBUF: case LZIP_OOM_OUTBUF:
case LZIP_WRITE_ERROR: return 1; case LZIP_WRITE_ERROR: return 1;
case LZIP_HEADER1_EOF: case LZIP_HEADER1_EOF:
case LZIP_HEADER2_EOF: case LZIP_HEADER2_EOF:
case LZIP_BAD_MAGIC1: case LZIP_BAD_MAGIC1:
@ -494,8 +496,9 @@ int convert_retval( const int retval )
case LZIP_BAD_DICT_SIZE: case LZIP_BAD_DICT_SIZE:
case LZIP_BAD_DATA: case LZIP_BAD_DATA:
case LZIP_DATA_EOF: case LZIP_DATA_EOF:
case LZIP_BAD_CRC: return 2; case LZIP_BAD_CRC:
default: return 3; case LZIP_EMPTY_MEMBER: return 2;
default: return 3;
} }
} }
@ -519,7 +522,7 @@ static long fill( void * buf, unsigned long size )
long flush( void * buf, unsigned long size ) long flush( void * buf, unsigned long size )
{ {
unsigned long sz = ( outfd >= 0 ) ? 0 : size; unsigned long sz = (outfd >= 0) ? 0 : size;
errno = 0; errno = 0;
while( sz < size ) while( sz < size )
{ {
@ -535,7 +538,7 @@ static const char * global_name; /* copy of filename for 'error' */
static void error(char *x) { show_file_error( global_name, x, 0 ); } static void error(char *x) { show_file_error( global_name, x, 0 ); }
static int decompress( const int infd, struct Pretty_print * const pp, static int decompress( const int infd, Pretty_print * const pp,
const long cl_insize, const long cl_outsize, const long cl_insize, const long cl_outsize,
const bool nofill, const bool noflush, const bool testing ) const bool nofill, const bool noflush, const bool testing )
{ {
@ -574,7 +577,7 @@ static int decompress( const int infd, struct Pretty_print * const pp,
} }
void show_results( struct Pretty_print * const pp, const long in_pos, void show_results( Pretty_print * const pp, const long in_pos,
const long out_pos, const bool testing ) const long out_pos, const bool testing )
{ {
if( verbosity >= 1 ) Pp_show_msg( pp, 0 ); if( verbosity >= 1 ) Pp_show_msg( pp, 0 );
@ -631,7 +634,6 @@ int main( const int argc, const char * const argv[] )
const char * default_output_filename = ""; const char * default_output_filename = "";
long cl_insize = 0; long cl_insize = 0;
long cl_outsize = 0; long cl_outsize = 0;
int i;
bool force = false; bool force = false;
bool in_place = false; bool in_place = false;
bool keep_input_files = false; bool keep_input_files = false;
@ -642,7 +644,7 @@ int main( const int argc, const char * const argv[] )
if( argc > 0 ) invocation_name = argv[0]; if( argc > 0 ) invocation_name = argv[0];
enum { opt_insize = 256, opt_outsize, opt_nofill, opt_noflush }; enum { opt_insize = 256, opt_outsize, opt_nofill, opt_noflush };
const struct ap_Option options[] = const ap_Option options[] =
{ {
{ 'c', "stdout", ap_no }, { 'c', "stdout", ap_no },
{ 'd', "decompress", ap_no }, { 'd', "decompress", ap_no },
@ -656,14 +658,14 @@ int main( const int argc, const char * const argv[] )
{ 't', "test", ap_no }, { 't', "test", ap_no },
{ 'v', "verbose", ap_no }, { 'v', "verbose", ap_no },
{ 'V', "version", ap_no }, { 'V', "version", ap_no },
{ opt_insize, "insize", ap_maybe }, { opt_insize, "insize", ap_maybe },
{ opt_outsize, "outsize", ap_maybe }, { opt_outsize, "outsize", ap_maybe },
{ opt_nofill, "nofill", ap_no }, { opt_nofill, "nofill", ap_no },
{ opt_noflush, "noflush", ap_no }, { opt_noflush, "noflush", ap_no },
{ 0, 0, ap_no } }; { 0, 0, ap_no } };
/* static because valgrind complains and memory management in C sucks */ /* static because valgrind complains and memory management in C sucks */
static struct Arg_parser parser; static Arg_parser parser;
if( !ap_init( &parser, argc, argv, options, 0 ) ) if( !ap_init( &parser, argc, argv, options, 0 ) )
{ show_error( mem_msg, 0, false ); return 1; } { show_error( mem_msg, 0, false ); return 1; }
if( ap_error( &parser ) ) /* bad option */ if( ap_error( &parser ) ) /* bad option */
@ -684,7 +686,7 @@ int main( const int argc, const char * const argv[] )
case 'h': show_help(); return 0; case 'h': show_help(); return 0;
case 'I': in_place = true; break; case 'I': in_place = true; break;
case 'k': keep_input_files = true; break; case 'k': keep_input_files = true; break;
case 'n': break; case 'n': break; /* ignored */
case 'o': if( strcmp( arg, "-" ) == 0 ) to_stdout = true; case 'o': if( strcmp( arg, "-" ) == 0 ) to_stdout = true;
else { default_output_filename = arg; } break; else { default_output_filename = arg; } break;
case 'q': verbosity = -1; break; case 'q': verbosity = -1; break;
@ -712,6 +714,7 @@ int main( const int argc, const char * const argv[] )
filenames = resize_buffer( filenames, num_filenames * sizeof filenames[0] ); filenames = resize_buffer( filenames, num_filenames * sizeof filenames[0] );
filenames[0] = "-"; filenames[0] = "-";
int i;
bool filenames_given = false; bool filenames_given = false;
for( i = 0; argind + i < ap_arguments( &parser ); ++i ) for( i = 0; argind + i < ap_arguments( &parser ); ++i )
{ {
@ -731,7 +734,7 @@ int main( const int argc, const char * const argv[] )
if( !to_stdout && !testing && ( filenames_given || to_file ) ) if( !to_stdout && !testing && ( filenames_given || to_file ) )
set_signals( signal_handler ); set_signals( signal_handler );
static struct Pretty_print pp; static Pretty_print pp;
Pp_init( &pp, filenames, num_filenames ); Pp_init( &pp, filenames, num_filenames );
int failed_tests = 0; int failed_tests = 0;
@ -807,6 +810,7 @@ int main( const int argc, const char * const argv[] )
program_name, failed_tests, program_name, failed_tests,
( failed_tests == 1 ) ? "file" : "files" ); ( failed_tests == 1 ) ? "file" : "files" );
free( output_filename ); free( output_filename );
Pp_free( &pp );
free( filenames ); free( filenames );
ap_free( &parser ); ap_free( &parser );
return retval; return retval;

View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# check script for Xlunzip - Test tool for the lzip_decompress linux module # check script for Xlunzip - Test tool for the lzip_decompress linux module
# Copyright (C) 2016-2024 Antonio Diaz Diaz. # Copyright (C) 2016-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.
@ -28,11 +28,11 @@ if [ -d tmp ] ; then rm -rf tmp ; fi
mkdir tmp mkdir tmp
cd "${objdir}"/tmp || framework_failure 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_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
zero_lz="${testdir}"/zero.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)" ; }
@ -80,29 +80,24 @@ printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null
printf "\ntesting decompression..." printf "\ntesting decompression..."
for i in "${in_lz}" "${in_em}" ; do "${LZIP}" -t "${in_lz}" || test_failed $LINENO
"${LZIP}" -t "$i" || test_failed $LINENO "$i" "${LZIP}" -d "${in_lz}" -o out || test_failed $LINENO
"${LZIP}" -d "$i" -o out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" "${LZIP}" -cd "${in_lz}" > out || test_failed $LINENO
"${LZIP}" -cd "$i" > out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" "${LZIP}" -d "${in_lz}" -o - > out || test_failed $LINENO
"${LZIP}" -d "$i" -o - > out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" "${LZIP}" -d < "${in_lz}" > out || test_failed $LINENO
"${LZIP}" -d < "$i" > out || test_failed $LINENO "$i" cmp in out || test_failed $LINENO
cmp in out || test_failed $LINENO "$i" rm -f out || framework_failure
rm -f out || framework_failure
done
lines=`"${LZIP}" -tvv "${in_em}" 2>&1 | wc -l` || test_failed $LINENO cp "${in_lz}" out.lz || framework_failure
[ "${lines}" -eq 1 ] || test_failed $LINENO "${lines}"
cat "${in_lz}" > out.lz || framework_failure
"${LZIP}" -dk out.lz || test_failed $LINENO "${LZIP}" -dk out.lz || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
rm -f out || framework_failure rm -f out || framework_failure
"${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO "${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO
cat fox > copy || framework_failure cp fox copy || framework_failure
cat "${in_lz}" > copy.lz || framework_failure cp "${in_lz}" copy.lz || framework_failure
"${LZIP}" -d copy.lz out.lz 2> /dev/null # skip copy, decompress out "${LZIP}" -d copy.lz out.lz 2> /dev/null # skip copy, decompress out
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e out.lz ] || test_failed $LINENO [ ! -e out.lz ] || test_failed $LINENO
@ -116,7 +111,6 @@ rm -f copy out || framework_failure
printf "to be overwritten" > out || framework_failure printf "to be overwritten" > out || framework_failure
"${LZIP}" -df -o out < "${in_lz}" || test_failed $LINENO "${LZIP}" -df -o out < "${in_lz}" || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
rm -f out || framework_failure
"${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO "${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO
cmp in ./- || test_failed $LINENO cmp in ./- || test_failed $LINENO
rm -f ./- || framework_failure rm -f ./- || framework_failure
@ -124,12 +118,12 @@ rm -f ./- || framework_failure
cmp in ./- || test_failed $LINENO cmp in ./- || test_failed $LINENO
rm -f ./- || framework_failure 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 || "${LZIP}" -dv - anyothername - < "${in_lz}" > out 2> /dev/null ||
test_failed $LINENO test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
cmp in anyothername.out || test_failed $LINENO cmp in anyothername.out || test_failed $LINENO
rm -f out anyothername.out || framework_failure rm -f anyothername.out || framework_failure
"${LZIP}" -tq in "${in_lz}" "${LZIP}" -tq in "${in_lz}"
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
@ -142,7 +136,7 @@ cat out in | cmp in - || test_failed $LINENO # out must be empty
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
rm -f out || framework_failure rm -f out || framework_failure
cat "${in_lz}" > out.lz || framework_failure cp "${in_lz}" out.lz || framework_failure
"${LZIP}" -dq in out.lz "${LZIP}" -dq in out.lz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
[ -e out.lz ] || test_failed $LINENO [ -e out.lz ] || test_failed $LINENO
@ -166,19 +160,73 @@ cmp in2 out2 || test_failed $LINENO
rm -f out2 || framework_failure rm -f out2 || framework_failure
cat "${in_lz}" "${in_lz}" > out2.lz || 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 1 ] || test_failed $LINENO "${lines}"
printf "\ngarbage" >> out2.lz || framework_failure printf "\ngarbage" >> out2.lz || framework_failure
"${LZIP}" -tvvvv out2.lz 2> /dev/null || test_failed $LINENO "${LZIP}" -tvvvv out2.lz 2> /dev/null || test_failed $LINENO
printf "to be overwritten" > out2 || framework_failure printf "to be overwritten" > out2 || framework_failure
"${LZIP}" -df out2.lz || test_failed $LINENO "${LZIP}" -df out2.lz || test_failed $LINENO
cmp in2 out2 || test_failed $LINENO cmp in2 out2 || test_failed $LINENO
touch empty || framework_failure
cp "${em_lz}" em.lz || framework_failure
"${LZIP}" -dk em.lz || test_failed $LINENO
cmp empty em || test_failed $LINENO
printf "\ntesting bad input..." printf "\ntesting bad input..."
cat em.lz em.lz | "${LZIP}" -tq
[ $? = 2 ] || test_failed $LINENO
cat em.lz em.lz | "${LZIP}" -dq > em
[ $? = 2 ] || test_failed $LINENO
cmp empty em || test_failed $LINENO
cat em.lz "${in_lz}" | "${LZIP}" -tq
[ $? = 2 ] || test_failed $LINENO
cat em.lz "${in_lz}" | "${LZIP}" -dq > out
[ $? = 2 ] || test_failed $LINENO
cmp in out || test_failed $LINENO
cat "${in_lz}" em.lz | "${LZIP}" -tq
[ $? = 2 ] || test_failed $LINENO
cat "${in_lz}" em.lz | "${LZIP}" -dq > out
[ $? = 2 ] || test_failed $LINENO
cmp in out || test_failed $LINENO
cat em.lz em.lz > ee.lz || framework_failure
"${LZIP}" -tq < ee.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -dq < ee.lz > em
[ $? = 2 ] || test_failed $LINENO
cmp empty em || test_failed $LINENO
"${LZIP}" -tq ee.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -dq ee.lz
[ $? = 2 ] || test_failed $LINENO
[ ! -e ee ] || test_failed $LINENO
"${LZIP}" -cdq ee.lz > em
[ $? = 2 ] || test_failed $LINENO
cmp empty em || test_failed $LINENO
rm -f em || framework_failure
cat "${in_lz}" em.lz "${in_lz}" > inein.lz || framework_failure
"${LZIP}" -tq < inein.lz
[ $? = 2 ] || test_failed $LINENO
"${LZIP}" -dq < inein.lz > out2
[ $? = 2 ] || 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 em.lz || framework_failure
headers='LZIp LZiP LZip LzIP LzIp LziP lZIP lZIp lZiP lzIP' 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' 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'
cat "${in_lz}" > int.lz || framework_failure cp "${in_lz}" int.lz || framework_failure
printf "LZIP${body}" >> int.lz || framework_failure printf "LZIP${body}" >> int.lz || framework_failure
if "${LZIP}" -tq int.lz ; then if "${LZIP}" -t int.lz ; then
for header in ${headers} ; do for header in ${headers} ; do
printf "${header}${body}" > int.lz || framework_failure printf "${header}${body}" > int.lz || framework_failure
"${LZIP}" -tq int.lz # first member "${LZIP}" -tq int.lz # first member
@ -187,7 +235,7 @@ if "${LZIP}" -tq int.lz ; then
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -cdq int.lz > /dev/null "${LZIP}" -cdq int.lz > /dev/null
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 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 printf "${header}${body}" >> int.lz || framework_failure
"${LZIP}" -tq int.lz # trailing data "${LZIP}" -tq int.lz # trailing data
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
@ -197,10 +245,13 @@ if "${LZIP}" -tq int.lz ; then
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
done done
else else
printf "\nwarning: skipping header test: 'printf' does not work on your system." printf "warning: skipping header test: 'printf' does not work on your system."
fi fi
rm -f int.lz || framework_failure 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 \ 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}" -tq "${testdir}"/$i "${LZIP}" -tq "${testdir}"/$i
@ -212,13 +263,13 @@ 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
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 dd if=in3.lz of=trunc.lz bs=$i count=1 2> /dev/null
"${LZIP}" -tq trunc.lz "${LZIP}" -tq trunc.lz
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
@ -230,15 +281,17 @@ if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
[ $? = 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 trunc.lz || framework_failure rm -f 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}" -t ingin.lz || test_failed $LINENO "${LZIP}" -t ingin.lz || 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 "${LZIP}" -cd ingin.lz > out || test_failed $LINENO
cmp in out || test_failed $LINENO cmp in out || test_failed $LINENO
"${LZIP}" -d < ingin.lz > out || test_failed $LINENO "${LZIP}" -d < ingin.lz > out || test_failed $LINENO
@ -274,7 +327,7 @@ for i in =18KiB =65536 =262144 ; do
cmp in out || test_failed $LINENO $i cmp in out || test_failed $LINENO $i
done done
for i in =36388 =65536 =262144 ; do for i in =36301 =65536 =262144 ; do
"${LZIP}" -t --outsize$i --noflush "${in_lz}" || "${LZIP}" -t --outsize$i --noflush "${in_lz}" ||
test_failed $LINENO $i test_failed $LINENO $i
"${LZIP}" -cd --outsize$i --noflush "${in_lz}" > out || "${LZIP}" -cd --outsize$i --noflush "${in_lz}" > out ||
@ -282,7 +335,7 @@ for i in =36388 =65536 =262144 ; do
cmp in out || test_failed $LINENO $i cmp in out || test_failed $LINENO $i
done done
for i in =36387 ; do for i in =36300 ; do
"${LZIP}" -tq --outsize$i --noflush "${in_lz}" "${LZIP}" -tq --outsize$i --noflush "${in_lz}"
[ $? = 1 ] || test_failed $LINENO $i [ $? = 1 ] || test_failed $LINENO $i
"${LZIP}" -cdq --outsize$i --noflush "${in_lz}" > out "${LZIP}" -cdq --outsize$i --noflush "${in_lz}" > out
@ -352,18 +405,21 @@ for i in in2 in3 ; do
done done
"${LZIP}" -tq --in-place ingin.lz "${LZIP}" -tq --in-place ingin.lz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
rm -f out out2 ingin.lz in2 in2.lz in3 in3.lz || framework_failure rm -f out2 ingin.lz in2 in2.lz in3 in3.lz || framework_failure
cat "${in_lz}" > inz.lz || framework_failure cat "${in_lz}" "${em_lz}" > ine.lz || framework_failure
counter=0 "${LZIP}" -tq --in-place ine.lz
while [ ${counter} -lt 20 ] ; do [ $? = 2 ] || test_failed $LINENO
cat "${zero_lz}" >> inz.lz || framework_failure "${LZIP}" -cdq --in-place ine.lz > out
"${LZIP}" -t --in-place inz.lz || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -cd --in-place inz.lz > out || test_failed $LINENO cmp empty out || test_failed $LINENO
cmp in out || test_failed $LINENO cat "${em_lz}" "${in_lz}" > ine.lz || framework_failure
counter=$((counter+1)) "${LZIP}" -tq --in-place ine.lz
done [ $? = 2 ] || test_failed $LINENO
rm -f out inz.lz || framework_failure "${LZIP}" -cdq --in-place ine.lz > out
[ $? = 2 ] || test_failed $LINENO
cmp empty out || test_failed $LINENO
rm -f ine.lz empty || framework_failure
# decompress with trailing data in place # decompress with trailing data in place
cat "${in_lz}" in in in in > int.lz || framework_failure cat "${in_lz}" in in in in > int.lz || framework_failure

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.