diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | Makefile.in | 8 | ||||
-rw-r--r-- | NEWS | 14 | ||||
-rwxr-xr-x | configure | 6 | ||||
-rw-r--r-- | decompress_lunzip.c | 8 | ||||
-rw-r--r-- | doc/xlunzip.1 | 4 | ||||
-rw-r--r-- | in_place.c | 41 | ||||
-rw-r--r-- | linux_lunzip.h | 15 | ||||
-rw-r--r-- | linux_module.h | 8 | ||||
-rw-r--r-- | lzip.h | 2 | ||||
-rw-r--r-- | lzip_decompress.c (renamed from lzip.c) | 9 | ||||
-rw-r--r-- | main.c | 53 | ||||
-rwxr-xr-x | testsuite/check.sh | 3 |
14 files changed, 114 insertions, 72 deletions
@@ -1,6 +1,17 @@ +2018-09-18 Antonio Diaz Diaz <antonio@gnu.org> + + * Version 0.4 released. + * lzip_decompress module updated to version 4.18.1-2. + * lzip.c: Renamed to lzip_decompress.c. + * lzip_decompress.c (LZd_init): Fixed a warning on 32 bit systems. + * in_place.c (set_file_sizes): Skip trailing zeros efficiently. + * main.c: Check return value of close( infd ). + * INSTALL: Document use of '-D __USE_MINGW_ANSI_STDIO'. + 2018-07-10 Antonio Diaz Diaz <antonio@gnu.org> * Version 0.3 released. + * lzip_decompress module updated to version 4.14.40-3. * lzip.c: Use a precalculated CRC table as lzlib does. 2018-07-09 Antonio Diaz Diaz <antonio@gnu.org> @@ -43,6 +43,10 @@ the main archive. install the program and any data files and documentation, and link the program to the name 'lzip'. +If you are compiling on MinGW, replace step 3 with: + + make CFLAGS='-Wall -W -O2 -D __USE_MINGW_ANSI_STDIO' + Another way ----------- diff --git a/Makefile.in b/Makefile.in index 7db7662..cb47e49 100644 --- a/Makefile.in +++ b/Makefile.in @@ -7,7 +7,7 @@ INSTALL_DIR = $(INSTALL) -d -m 755 SHELL = /bin/sh CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1 -objs = carg_parser.o decompress_lunzip.o in_place.o lzip.o main.o +objs = carg_parser.o decompress_lunzip.o in_place.o lzip_decompress.o main.o .PHONY : all install install-bin install-info install-man \ @@ -30,9 +30,9 @@ main.o : main.c $(objs) : Makefile carg_parser.o : carg_parser.h -decompress_lunzip.o : linux_lzip.h linux_lunzip.h linux_mm.h lzip.c +decompress_lunzip.o : linux_lzip.h linux_lunzip.h linux_mm.h lzip_decompress.c in_place.o : linux_lunzip.h lzip.h -lzip.o : linux_lzip.h linux_mm.h +lzip_decompress.o : linux_module.h linux_lzip.h linux_mm.h main.o : carg_parser.h linux_lzip.h linux_lunzip.h lzip.h @@ -46,7 +46,7 @@ $(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi man : $(VPATH)/doc/$(progname).1 $(VPATH)/doc/$(progname).1 : $(progname) - help2man -n 'test tool for the lunzip linux module' -o $@ --no-info ./$(progname) + help2man -n 'test tool for the lzip_decompress linux module' -o $@ --no-info ./$(progname) Makefile : $(VPATH)/configure $(VPATH)/Makefile.in ./config.status @@ -1,11 +1,13 @@ -Changes in version 0.3: +Changes in version 0.4: -lzip_decompress module updated to version 4.14.40-3. +The lzip_decompress module has been updated to version 4.18.1-2. -Use a precalculated CRC table as lzlib does. +A harmless warning on 32 bit systems has been fixed. -Improved corrupt header detection to HD=3. +Large amounts of trailing zeros are now skipped more efficiently when +decompressing or testing in place. -'--in-place' now works with both '--decompress' and '--test'. +Errors are now also checked when closing the input file. -Show final diagnostic when testing multiple files. +It has been documented in INSTALL the use of '-D __USE_MINGW_ANSI_STDIO' +when compiling on MinGW. @@ -1,12 +1,12 @@ #! /bin/sh -# configure script for Xlunzip - Test tool for the lunzip linux module +# configure script for Xlunzip - Test tool for the lzip_decompress linux module # Copyright (C) 2016-2018 Antonio Diaz Diaz. # # This configure script is free software: you have unlimited permission # to copy, distribute and modify it. pkgname=xlunzip -pkgversion=0.3 +pkgversion=0.4 progname=xlunzip srctrigger=doc/${progname}.1 @@ -167,7 +167,7 @@ echo "CFLAGS = ${CFLAGS}" echo "LDFLAGS = ${LDFLAGS}" rm -f Makefile cat > Makefile << EOF -# Makefile for Xlunzip - Test tool for the lunzip linux module +# Makefile for Xlunzip - Test tool for the lzip_decompress linux module # Copyright (C) 2016-2018 Antonio Diaz Diaz. # This file was generated automatically by configure. Don't edit. # diff --git a/decompress_lunzip.c b/decompress_lunzip.c index 106c95b..f7da1fc 100644 --- a/decompress_lunzip.c +++ b/decompress_lunzip.c @@ -8,7 +8,7 @@ #ifdef STATIC #define PREBOOT -#include "lzip.c" +#include "lzip_decompress.c" #else #include "linux_lzip.h" #include "linux_lunzip.h" @@ -69,9 +69,9 @@ STATIC int INIT __lunzip(unsigned char *inbuf, long in_len, } #ifndef PREBOOT -/* decompress_fn (see linux/decompress/generic.h) should have an out_size - * argument to prevent overrunning outbuf in case of corruption of the - * compressed data. +/* decompress_fn (see include/linux/decompress/generic.h) should have an + * out_size argument to prevent overflowing outbuf in case of corruption + * of the compressed data. */ STATIC int INIT lunzip(unsigned char *inbuf, long in_len, long (*fill)(void*, unsigned long), diff --git a/doc/xlunzip.1 b/doc/xlunzip.1 index 905b59a..96c4de4 100644 --- a/doc/xlunzip.1 +++ b/doc/xlunzip.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1. -.TH XLUNZIP "1" "July 2018" "xlunzip 0.3" "User Commands" +.TH XLUNZIP "1" "September 2018" "xlunzip 0.4" "User Commands" .SH NAME -xlunzip \- test tool for the lunzip linux module +xlunzip \- test tool for the lzip_decompress linux module .SH SYNOPSIS .B xlunzip [\fI\,options\/\fR] [\fI\,files\/\fR] @@ -1,4 +1,4 @@ -/* Xlunzip - Test tool for the lunzip linux module +/* Xlunzip - Test tool for the lzip_decompress linux module Copyright (C) 2016-2018 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify @@ -78,7 +78,6 @@ uint8_t * read_file( const int infd, long * const buffer_sizep, if( errno ) { show_file_error( pp->name, "Error reading file", errno ); free( buffer ); return 0; } - close( infd ); *buffer_sizep = buffer_size; *file_sizep = file_size; return buffer; @@ -87,8 +86,8 @@ uint8_t * read_file( const int infd, long * const buffer_sizep, struct File_sizes { - long long csize; - long long dsize; + unsigned long long csize; + unsigned long long dsize; long trailing; }; @@ -96,25 +95,31 @@ const char * set_file_sizes( struct File_sizes * const file_sizes, const uint8_t * const buffer, const long file_size ) { if( file_size < min_member_size ) return "Input file is too short."; - const Lzip_header * header = (Lzip_header *)buffer; + const Lzip_header * header = (const Lzip_header *)buffer; if( !Lh_verify_magic( *header ) ) return "Bad magic number (file not in lzip format)."; if( !Lh_verify_version( *header ) ) return "Version of lzip member format not supported."; file_sizes->csize = file_sizes->dsize = file_sizes->trailing = 0; - long long pos = file_size; /* always points to a header or to EOF */ + unsigned long pos = file_size; /* always points to a header or to EOF */ while( pos >= min_member_size ) { const Lzip_trailer * const trailer = - (Lzip_trailer *)( buffer + pos - Lt_size ); - const long long member_size = Lt_get_member_size( *trailer ); + (const Lzip_trailer *)( buffer + pos - Lt_size ); + const unsigned long long member_size = Lt_get_member_size( *trailer ); if( member_size < min_member_size || member_size > pos ) { - if( file_sizes->csize == 0 ) { --pos; continue; } /* maybe trailing data */ + if( file_sizes->csize == 0 ) /* maybe trailing data */ + { + if( member_size == 0 ) /* skip trailing zeros */ + while( pos > Lt_size && buffer[pos-8] == 0 ) --pos; + else --pos; + continue; + } return "Member size in trailer is corrupt."; } - header = (Lzip_header *)( buffer + pos - member_size ); + header = (const Lzip_header *)( buffer + pos - member_size ); if( !Lh_verify_magic( *header ) || !Lh_verify_version( *header ) ) { if( file_sizes->csize == 0 ) { --pos; continue; } /* maybe trailing data */ @@ -123,7 +128,7 @@ const char * set_file_sizes( struct File_sizes * const file_sizes, if( file_sizes->csize == 0 && file_size - pos > 0 ) { file_sizes->trailing = file_size - pos; - header = (Lzip_header *)( buffer + pos ); + header = (const Lzip_header *)( buffer + pos ); if( file_size - pos > Lh_size && Lh_verify_magic( *header ) && Lh_verify_version( *header ) ) return "Last member in input file is truncated or corrupt."; @@ -133,8 +138,10 @@ const char * set_file_sizes( struct File_sizes * const file_sizes, file_sizes->dsize += Lt_get_data_size( *trailer ); } if( pos != 0 || file_sizes->csize == 0 ) return "Can't get file sizes."; - if( file_sizes->csize + file_sizes->trailing != file_size ) + if( file_sizes->csize + file_sizes->trailing != (unsigned long)file_size ) return "Error getting file sizes."; + if( file_sizes->csize > LONG_MAX ) return "File is larger than LONG_MAX."; + if( file_sizes->dsize > LONG_MAX ) return "Data is larger than LONG_MAX."; return 0; } @@ -165,15 +172,9 @@ int decompress_in_place( const int infd, struct Pretty_print * const pp, const char * emsg = set_file_sizes( &file_sizes, buffer, file_size ); if( emsg ) { show_file_error( pp->name, emsg, 0 ); return 2; } - const long long csize = file_sizes.csize; - const long long dsize = file_sizes.dsize; + const long csize = file_sizes.csize; + const long dsize = file_sizes.dsize; /* const long trailing = file_sizes.trailing; */ - if( csize <= 0 || csize > LONG_MAX ) - { show_file_error( pp->name, "File is larger than LONG_MAX.", 0 ); - return 2; } - if( dsize < 0 || dsize > LONG_MAX ) - { show_file_error( pp->name, "Data is larger than LONG_MAX.", 0 ); - return 2; } /* ( (csize-36+63) >> 6 ) + 36 never failed with single member */ const long rextra = ( csize >> 5 ) + 72; if( buffer_size < dsize + rextra ) /* avoid realloc if big enough */ diff --git a/linux_lunzip.h b/linux_lunzip.h index 8aafbad..5518d30 100644 --- a/linux_lunzip.h +++ b/linux_lunzip.h @@ -9,10 +9,15 @@ int lunzip(unsigned char *inbuf, long in_len, long *in_posp, void (*error)(char *x)); +/* This internal function is required because the decompress_fn above + * (see include/linux/decompress/generic.h) should have an out_size + * argument to prevent overflowing outbuf in case of corruption of the + * compressed data. + */ int __lunzip(unsigned char *inbuf, long in_len, - long (*fill)(void*, unsigned long), - long (*flush)(void*, unsigned long), - unsigned char *outbuf, long out_size, - long *in_posp, long *out_posp, - void (*error)(char *x)); + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *outbuf, long out_size, + long *in_posp, long *out_posp, + void (*error)(char *x)); #endif diff --git a/linux_module.h b/linux_module.h new file mode 100644 index 0000000..4f2d0c4 --- /dev/null +++ b/linux_module.h @@ -0,0 +1,8 @@ +#ifndef _LINUX_MODULE_H +#define _LINUX_MODULE_H + +#define MODULE_LICENSE(_license) +#define MODULE_AUTHOR(_author) +#define MODULE_DESCRIPTION(_description) + +#endif /* _LINUX_MODULE_H */ @@ -1,4 +1,4 @@ -/* Xlunzip - Test tool for the lunzip linux module +/* Xlunzip - Test tool for the lzip_decompress linux module Copyright (C) 2016-2018 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify diff --git a/lzip.c b/lzip_decompress.c index 7c96975..9c5b8fb 100644 --- a/lzip.c +++ b/lzip_decompress.c @@ -6,12 +6,13 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +#include "linux_module.h" #include "linux_lzip.h" #include "linux_mm.h" /* * STATIC_RW_DATA is used in the pre-boot environment on some architectures. - * See <linux/decompress/mm.h> for details. + * See include/linux/decompress/mm.h for details. */ #ifndef STATIC_RW_DATA #define STATIC_RW_DATA static @@ -637,7 +638,7 @@ static inline bool LZd_init(struct LZ_decoder * const d, Lm_init(&d->rep_len_model); d->buffer_given = (outbuf && out_size > 0); - d->buffer_size = d->buffer_given ? out_size : dict_size; + d->buffer_size = d->buffer_given ? (unsigned long)out_size : dict_size; d->dictionary_size = min_t(unsigned long, d->buffer_size, dict_size); d->buffer = d->buffer_given ? outbuf : large_malloc(d->buffer_size); if (!d->buffer) @@ -686,7 +687,7 @@ static bool LZd_verify_trailer(struct LZ_decoder * const d) } -/* Return value: 0 = OK, < 0 = error (see <linux/lzip.h>). */ +/* Return value: 0 = OK, < 0 = error (see include/linux/lzip.h). */ static int LZd_decode_member(struct LZ_decoder * const d) { struct Range_decoder * const rdec = d->rdec; @@ -875,7 +876,7 @@ int lzip_decompress(unsigned char *inbuf, long in_len, #ifndef STATIC EXPORT_SYMBOL_GPL(lzip_decompress); +#endif MODULE_DESCRIPTION("LZIP Decompressor"); MODULE_AUTHOR("Antonio Diaz Diaz <antonio@gnu.org>"); MODULE_LICENSE("GPL"); -#endif @@ -1,4 +1,4 @@ -/* Xlunzip - Test tool for the lunzip linux module +/* Xlunzip - Test tool for the lzip_decompress linux module Copyright (C) 2016-2018 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify @@ -79,8 +79,10 @@ const struct { const char * from; const char * to; } known_extensions[] = { { ".tlz", ".tar" }, { 0, 0 } }; -char * output_filename = 0; int infd = -1; /* needed by the fill function */ +/* Variables used in signal handler context. + They are not declared volatile because the handler never returns. */ +char * output_filename = 0; int outfd = -1; bool delete_output_on_interrupt = false; @@ -283,7 +285,7 @@ static int open_instream( const char * const name, struct stat * const in_statsp fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n", program_name, name, ( can_read && !no_ofile ) ? - ",\n and '--stdout' was not specified" : "" ); + ",\n and '--stdout' was not specified" : "" ); close( infd ); infd = -1; } @@ -315,8 +317,17 @@ static bool open_outstream( const bool force, const bool from_stdin ) } +static void set_signals( void (*action)(int) ) + { + signal( SIGHUP, action ); + signal( SIGINT, action ); + signal( SIGTERM, action ); + } + + void cleanup_and_fail( const int retval ) { + set_signals( SIG_IGN ); /* ignore signals */ if( delete_output_on_interrupt ) { delete_output_on_interrupt = false; @@ -331,6 +342,14 @@ void cleanup_and_fail( const int retval ) } +void signal_handler( int sig ) + { + if( sig ) {} /* keep compiler happy */ + show_error( "Control-C or similar caught, quitting.", 0, false ); + cleanup_and_fail( 1 ); + } + + /* Set permissions, owner and times. */ static void close_and_set_permissions( const struct stat * const in_statsp ) { @@ -416,7 +435,7 @@ long flush( void * buf, unsigned long size ) return sz; } -const char * global_name; +const char * global_name; /* copy of filename for 'error' */ static void error(char *x) { show_file_error( global_name, x, 0 ); } @@ -471,22 +490,6 @@ static int decompress( struct Pretty_print * const pp, const long cl_insize, } -void signal_handler( int sig ) - { - if( sig ) {} /* keep compiler happy */ - show_error( "Control-C or similar caught, quitting.", 0, false ); - cleanup_and_fail( 1 ); - } - - -static void set_signals( void ) - { - signal( SIGHUP, signal_handler ); - signal( SIGINT, signal_handler ); - signal( SIGTERM, signal_handler ); - } - - void show_error( const char * const msg, const int errcode, const bool help ) { if( verbosity < 0 ) return; @@ -619,7 +622,7 @@ int main( const int argc, const char * const argv[] ) if( !to_stdout && !testing && ( filenames_given || default_output_filename[0] ) ) - set_signals(); + set_signals( signal_handler ); Pp_init( &pp, filenames, num_filenames ); @@ -690,6 +693,13 @@ int main( const int argc, const char * const argv[] ) tmp = decompress_in_place( infd, &pp, testing ); else tmp = decompress( &pp, cl_insize, cl_outsize, nofill, noflush, testing ); + if( close( infd ) != 0 ) + { + show_error( input_filename[0] ? "Error closing input file" : + "Error closing stdin", errno, false ); + if( tmp < 1 ) tmp = 1; + } + infd = -1; if( tmp > retval ) retval = tmp; if( tmp ) { if( !testing ) cleanup_and_fail( retval ); @@ -699,7 +709,6 @@ int main( const int argc, const char * const argv[] ) close_and_set_permissions( in_statsp ); if( input_filename[0] ) { - close( infd ); infd = -1; if( !keep_input_files && !to_stdout && !testing ) remove( input_filename ); } diff --git a/testsuite/check.sh b/testsuite/check.sh index 3fc9f12..7ed18f4 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -1,5 +1,5 @@ #! /bin/sh -# check script for Xlunzip - Test tool for the lunzip linux module +# check script for Xlunzip - Test tool for the lzip_decompress linux module # Copyright (C) 2016-2018 Antonio Diaz Diaz. # # This script is free software: you have unlimited permission @@ -129,6 +129,7 @@ cmp in2 copy2 || test_failed $LINENO cat in2.lz > copy2.lz || framework_failure printf "\ngarbage" >> copy2.lz || framework_failure +"${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO printf "to be overwritten" > copy2 || framework_failure "${LZIP}" -df copy2.lz || test_failed $LINENO cmp in2 copy2 || test_failed $LINENO |