summaryrefslogtreecommitdiffstats
path: root/minilzip.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--minilzip.c43
1 files changed, 26 insertions, 17 deletions
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 );