diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | NEWS | 20 | ||||
-rw-r--r-- | README | 26 | ||||
-rw-r--r-- | carg_parser.c | 2 | ||||
-rw-r--r-- | carg_parser.h | 2 | ||||
-rwxr-xr-x | configure | 6 | ||||
-rw-r--r-- | decompress_lunzip.c | 2 | ||||
-rw-r--r-- | doc/xlunzip.1 | 6 | ||||
-rw-r--r-- | in_place.c | 21 | ||||
-rw-r--r-- | linux_lzip.h | 2 | ||||
-rw-r--r-- | lzip.h | 5 | ||||
-rw-r--r-- | lzip_decompress.c | 2 | ||||
-rw-r--r-- | main.c | 37 | ||||
-rwxr-xr-x | testsuite/check.sh | 6 |
15 files changed, 74 insertions, 74 deletions
@@ -1,3 +1,8 @@ +2021-01-01 Antonio Diaz Diaz <antonio@gnu.org> + + * Version 0.7 released. + * main.c (main): Do not open output if input is a terminal. + 2020-06-24 Antonio Diaz Diaz <antonio@gnu.org> * Version 0.6 released. @@ -51,7 +56,7 @@ * Tests the code shipped in linux patches before june 2018. -Copyright (C) 2016-2020 Antonio Diaz Diaz. +Copyright (C) 2016-2021 Antonio Diaz Diaz. This file is a collection of facts, and thus it is not copyrightable, but just in case, you have unlimited permission to copy, distribute, and @@ -1,6 +1,6 @@ Requirements ------------ -You will need a C99 compiler. (gcc 2.95 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 4.1.2, but the code should compile with any standards compliant compiler. Gcc is available at http://gcc.gnu.org. @@ -69,7 +69,7 @@ After running 'configure', you can run 'make' and 'make install' as explained above. -Copyright (C) 2016-2020 Antonio Diaz Diaz. +Copyright (C) 2016-2021 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute, and modify it. @@ -1,19 +1,3 @@ -Changes in version 0.6: +Changes in version 0.7: -Option '-o, --output' now behaves like '-c, --stdout', but sending the -output unconditionally to a file instead of to standard output. See the new -description of '-o' in the manual. This change is not backwards compatible. -Therefore commands like: - xlunzip -d -o foo - bar.lz < foo.lz -must now be split into: - xlunzip -d -o foo - < foo.lz - xlunzip -d bar.lz -or rewritten as: - xlunzip -d - bar.lz < foo.lz > foo - -In-place decompression of concatenated files should now work for any -combination of files as long as they fit in memory and their total -decompressed size is smaller than LONG_MAX minus a small extra space. - -The README file now includes an analysis of the amount of memory required -for in-place decompression. +Xlunzip now does not even open the output file if the input file is a terminal. @@ -18,7 +18,7 @@ masked by a low compression ratio in the last members. The xlunzip tarball contains a copy of the lzip_decompress module and can be compiled and tested without downloading or applying the patch to the kernel. - + My lzip patch for linux can be found at http://download.savannah.gnu.org/releases/lzip/kernel/ @@ -61,8 +61,8 @@ data is uncompressible. The worst case is very compressible data followed by uncompressible data because in this case the output pointer increases faster when the input pointer is smaller. - | * <-- input pointer - | * , <-- output pointer + | * <-- input pointer (*) + | * , <-- output pointer (,) | * , ' | x ' <-- overrun (x) memory | * ,' @@ -71,7 +71,7 @@ address | * ,' | ,' | ,' |,' - `-------------------------- + '-------------------------- time All we need to know to calculate the minimum required extra space is: @@ -82,19 +82,23 @@ All we need to know to calculate the minimum required extra space is: The maximum expansion ratio of LZMA data is of about 1.4%. Rounding this up to 1/64 (1.5625%) and adding 36 bytes per input member, the extra space required to decompress lzip data in place is: + extra_bytes = ( compressed_size >> 6 ) + members * 36 -Using the compressed size to calculate the extra_bytes (as in the equation +Using the compressed size to calculate the extra_bytes (as in the formula above) may slightly overestimate the amount of space required in the worst case. But calculating the extra_bytes from the uncompressed size (as does -linux) is wrong (and inefficient for high compression ratios). The formula -used in arch/x86/boot/header.S - extra_bytes = (uncompressed_size >> 8) + 65536 -fails with 1 MB of zeros followed by 8 MB of random data, and wastes memory -for compression ratios > 4:1. +linux currently) is wrong (and inefficient for high compression ratios). The +formula used in arch/x86/boot/header.S + + extra_bytes = ( uncompressed_size >> 8 ) + 65536 + +fails to decompress 1 MB of zeros followed by 8 MB of random data, wastes +memory for compression ratios larger than 4:1, and does not even consider +multimember data. -Copyright (C) 2016-2020 Antonio Diaz Diaz. +Copyright (C) 2016-2021 Antonio Diaz Diaz. This file is free documentation: you have unlimited permission to copy, distribute, and modify it. diff --git a/carg_parser.c b/carg_parser.c index 0f60878..d0c05d5 100644 --- a/carg_parser.c +++ b/carg_parser.c @@ -1,5 +1,5 @@ /* Arg_parser - POSIX/GNU command line argument parser. (C version) - Copyright (C) 2006-2020 Antonio Diaz Diaz. + Copyright (C) 2006-2021 Antonio Diaz Diaz. This library is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided diff --git a/carg_parser.h b/carg_parser.h index a442b7b..c5f2352 100644 --- a/carg_parser.h +++ b/carg_parser.h @@ -1,5 +1,5 @@ /* Arg_parser - POSIX/GNU command line argument parser. (C version) - Copyright (C) 2006-2020 Antonio Diaz Diaz. + Copyright (C) 2006-2021 Antonio Diaz Diaz. This library is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -1,12 +1,12 @@ #! /bin/sh # configure script for Xlunzip - Test tool for the lzip_decompress linux module -# Copyright (C) 2016-2020 Antonio Diaz Diaz. +# Copyright (C) 2016-2021 Antonio Diaz Diaz. # # This configure script is free software: you have unlimited permission # to copy, distribute, and modify it. pkgname=xlunzip -pkgversion=0.6 +pkgversion=0.7 progname=xlunzip srctrigger=doc/${progname}.1 @@ -167,7 +167,7 @@ echo "LDFLAGS = ${LDFLAGS}" rm -f Makefile cat > Makefile << EOF # Makefile for Xlunzip - Test tool for the lzip_decompress linux module -# Copyright (C) 2016-2020 Antonio Diaz Diaz. +# Copyright (C) 2016-2021 Antonio Diaz Diaz. # This file was generated automatically by configure. Don't edit. # # This Makefile is free software: you have unlimited permission diff --git a/decompress_lunzip.c b/decompress_lunzip.c index d492095..9586bb5 100644 --- a/decompress_lunzip.c +++ b/decompress_lunzip.c @@ -1,7 +1,7 @@ /* * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd * - * Copyright (C) 2016-2020 Antonio Diaz Diaz. + * Copyright (C) 2016-2021 Antonio Diaz Diaz. * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ diff --git a/doc/xlunzip.1 b/doc/xlunzip.1 index 2f7ccb1..51c800d 100644 --- a/doc/xlunzip.1 +++ b/doc/xlunzip.1 @@ -1,5 +1,5 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1. -.TH XLUNZIP "1" "June 2020" "xlunzip 0.6" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16. +.TH XLUNZIP "1" "January 2021" "xlunzip 0.7" "User Commands" .SH NAME xlunzip \- test tool for the lzip_decompress linux module .SH SYNOPSIS @@ -86,7 +86,7 @@ Report bugs to lzip\-bug@nongnu.org .br Xlunzip home page: http://www.nongnu.org/lzip/xlunzip.html .SH COPYRIGHT -Copyright \(co 2020 Antonio Diaz Diaz. +Copyright \(co 2021 Antonio Diaz Diaz. 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. @@ -1,5 +1,5 @@ /* Xlunzip - Test tool for the lzip_decompress linux module - Copyright (C) 2016-2020 Antonio Diaz Diaz. + Copyright (C) 2016-2021 Antonio Diaz Diaz. 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 @@ -84,14 +84,15 @@ static uint8_t * read_file( const int infd, long * const buffer_sizep, struct File_sizes { - unsigned long long csize; - unsigned long long dsize; + unsigned long long csize; /* compressed size */ + unsigned long long dsize; /* decompressed size */ + unsigned long tsize; /* trailing data size */ long members; - long trailing; }; static const char * set_file_sizes( struct File_sizes * const file_sizes, - const uint8_t * const buffer, const long file_size ) + const uint8_t * const buffer, + const unsigned long file_size ) { if( file_size <= Lh_size ) return "File ends unexpectedly at member header."; if( file_size < min_member_size ) return "Input file is too short."; @@ -101,8 +102,8 @@ static const char * set_file_sizes( struct File_sizes * const file_sizes, if( !Lh_verify_version( *header ) ) return "Version of lzip member format not supported."; - file_sizes->csize = file_sizes->dsize = 0; - file_sizes->members = file_sizes->trailing = 0; + file_sizes->csize = file_sizes->dsize = file_sizes->tsize = 0; + file_sizes->members = 0; unsigned long pos = file_size; /* always points to a header or to EOF */ while( pos >= min_member_size ) { @@ -128,7 +129,7 @@ static 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; + file_sizes->tsize = file_size - pos; header = (const Lzip_header *)( buffer + pos ); if( file_size - pos > Lh_size && Lh_verify_magic( *header ) && Lh_verify_version( *header ) ) @@ -140,7 +141,7 @@ static const char * set_file_sizes( struct File_sizes * const file_sizes, ++file_sizes->members; } if( pos != 0 || file_sizes->csize == 0 ) return "Can't get file sizes."; - if( file_sizes->csize + file_sizes->trailing != (unsigned long)file_size ) + if( file_sizes->csize + file_sizes->tsize != 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."; @@ -192,8 +193,6 @@ int decompress_in_place( const int infd, struct Pretty_print * const pp, buffer_size = target_buffer_size; const long cbegin = buffer_size - csize; /* overwrite trailing data */ if( cbegin > 0 ) memmove( buffer + cbegin, buffer, csize ); -/*fprintf( stderr, "buffer_size = %ld, cbegin = %ld, extra_bytes = %ld\n", - buffer_size, cbegin, extra_bytes );*/ long in_pos, out_pos; int retval; diff --git a/linux_lzip.h b/linux_lzip.h index 90d54e8..398ef84 100644 --- a/linux_lzip.h +++ b/linux_lzip.h @@ -4,7 +4,7 @@ /* * LZIP decompressor * - * Copyright (C) 2016-2020 Antonio Diaz Diaz. + * Copyright (C) 2016-2021 Antonio Diaz Diaz. */ /* Return values (< 0 = Error) */ @@ -1,5 +1,5 @@ /* Xlunzip - Test tool for the lzip_decompress linux module - Copyright (C) 2016-2020 Antonio Diaz Diaz. + Copyright (C) 2016-2021 Antonio Diaz Diaz. 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 @@ -75,6 +75,9 @@ static inline unsigned long long Lt_get_member_size( const Lzip_trailer data ) } +static inline void set_retval( int * retval, const int new_val ) + { if( *retval < new_val ) *retval = new_val; } + static const char * const mem_msg = "Not enough memory."; /* defined in in_place.c */ diff --git a/lzip_decompress.c b/lzip_decompress.c index 8fa8bf1..157a798 100644 --- a/lzip_decompress.c +++ b/lzip_decompress.c @@ -1,7 +1,7 @@ /* * LZIP decompressor * - * Copyright (C) 2016-2020 Antonio Diaz Diaz. + * Copyright (C) 2016-2021 Antonio Diaz Diaz. * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ @@ -1,5 +1,5 @@ /* Xlunzip - Test tool for the lzip_decompress linux module - Copyright (C) 2016-2020 Antonio Diaz Diaz. + Copyright (C) 2016-2021 Antonio Diaz Diaz. 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 @@ -75,7 +75,7 @@ static void show_error( const char * const msg, const int errcode, const bool help ); static const char * const program_name = "xlunzip"; -static const char * const program_year = "2020"; +static const char * const program_year = "2021"; static const char * invocation_name = "xlunzip"; /* default value */ static const struct { const char * from; const char * to; } known_extensions[] = { @@ -393,6 +393,19 @@ static void signal_handler( int sig ) } +static bool check_tty_in( const char * const input_filename, const int infd, + const bool testing, int * const retval ) + { + if( isatty( infd ) ) /* for example /dev/tty */ + { show_file_error( input_filename, + "I won't read compressed data from a terminal.", 0 ); + close( infd ); set_retval( retval, 1 ); + if( !testing ) cleanup_and_fail( *retval ); + return false; } + return true; + } + + /* Set permissions, owner, and times. */ static void close_and_set_permissions( const struct stat * const in_statsp ) { @@ -538,9 +551,6 @@ void show_results( struct Pretty_print * const pp, const long in_pos, } -static inline void set_retval( int * retval, const int new_val ) - { if( *retval < new_val ) *retval = new_val; } - static void show_error( const char * const msg, const int errcode, const bool help ) { @@ -692,10 +702,12 @@ int main( const int argc, const char * const argv[] ) struct stat in_stats; const struct stat * in_statsp; + Pp_set_name( &pp, filenames[i] ); if( strcmp( filenames[i], "-" ) == 0 ) { if( stdin_used ) continue; else stdin_used = true; infd = STDIN_FILENO; + if( !check_tty_in( pp.name, infd, testing, &retval ) ) continue; if( one_to_one ) { outfd = STDOUT_FILENO; output_filename[0] = 0; } } else @@ -703,24 +715,15 @@ int main( const int argc, const char * const argv[] ) input_filename = filenames[i]; infd = open_instream( input_filename, &in_stats, one_to_one ); if( infd < 0 ) { set_retval( &retval, 1 ); continue; } - if( one_to_one ) + if( !check_tty_in( pp.name, infd, testing, &retval ) ) continue; + if( one_to_one ) /* open outfd after verifying infd */ { set_d_outname( input_filename, extension_index( input_filename ) ); if( !open_outstream( force, true ) ) - { set_retval( &retval, 1 ); close( infd ); infd = -1; continue; } + { close( infd ); infd = -1; set_retval( &retval, 1 ); continue; } } } - Pp_set_name( &pp, input_filename ); - if( isatty( infd ) ) /* for example /dev/tty */ - { - show_file_error( pp.name, - "I won't read compressed data from a terminal.", 0 ); - set_retval( &retval, 1 ); - if( testing ) { close( infd ); infd = -1; continue; } - cleanup_and_fail( retval ); - } - if( to_file && outfd < 0 ) /* open outfd after verifying infd */ { output_filename = resize_buffer( output_filename, diff --git a/testsuite/check.sh b/testsuite/check.sh index 5625ac2..5609a88 100755 --- a/testsuite/check.sh +++ b/testsuite/check.sh @@ -1,6 +1,6 @@ #! /bin/sh # check script for Xlunzip - Test tool for the lzip_decompress linux module -# Copyright (C) 2016-2020 Antonio Diaz Diaz. +# Copyright (C) 2016-2021 Antonio Diaz Diaz. # # This script is free software: you have unlimited permission # to copy, distribute, and modify it. @@ -104,6 +104,8 @@ printf "to be overwritten" > copy || framework_failure cmp in copy || test_failed $LINENO printf "to be overwritten" > copy || framework_failure +"${LZIP}" -d -o copy < "${in_lz}" 2> /dev/null +[ $? = 1 ] || test_failed $LINENO "${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO cmp in copy || test_failed $LINENO rm -f out copy || framework_failure @@ -228,9 +230,9 @@ cat "${in_lz}" > ingin.lz || framework_failure printf "g" >> 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}" -cd ingin.lz > copy || test_failed $LINENO cmp in copy || test_failed $LINENO -"${LZIP}" -t < ingin.lz || test_failed $LINENO "${LZIP}" -d < ingin.lz > copy || test_failed $LINENO cmp in copy || test_failed $LINENO |