diff options
Diffstat (limited to '')
-rw-r--r-- | lzd.cc | 22 |
1 files changed, 13 insertions, 9 deletions
@@ -1,5 +1,5 @@ /* Lzd - Educational decompressor for the lzip format - Copyright (C) 2013-2024 Antonio Diaz Diaz. + Copyright (C) 2013-2025 Antonio Diaz Diaz. This program is free software. Redistribution and use in source and binary forms, with or without modification, are permitted provided @@ -149,7 +149,8 @@ public: Range_decoder() : member_pos( header_size ), code( 0 ), range( 0xFFFFFFFFU ) { - get_byte(); // discard first byte of the LZMA stream + if( get_byte() != 0 ) // check first LZMA byte + { std::fputs( "Nonzero first LZMA byte.\n", stderr ); std::exit( 2 ); } for( int i = 0; i < 4; ++i ) code = ( code << 8 ) | get_byte(); } @@ -392,8 +393,7 @@ bool LZ_decoder::decode_member() // Return false if error direct_bits ); else { - rep0 += - rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits; + rep0 += rdec.decode( direct_bits-dis_align_bits ) << dis_align_bits; rep0 += rdec.decode_tree_reversed( bm_align, dis_align_bits ); if( rep0 == 0xFFFFFFFFU ) // marker found { @@ -423,7 +423,7 @@ int main( const int argc, const char * const argv[] ) "See the lzip manual for an explanation of the code.\n" "\nUsage: %s [-d] < file.lz > file\n" "Lzd decompresses from standard input to standard output.\n" - "\nCopyright (C) 2024 Antonio Diaz Diaz.\n" + "\nCopyright (C) 2025 Antonio Diaz Diaz.\n" "License 2-clause BSD.\n" "This is free software: you are free to change and redistribute " "it.\nThere is NO WARRANTY, to the extent permitted by law.\n" @@ -438,6 +438,7 @@ int main( const int argc, const char * const argv[] ) setmode( STDOUT_FILENO, O_BINARY ); #endif + bool empty = false, multi = false; for( bool first_member = true; ; first_member = false ) { Lzip_header header; // check header @@ -457,7 +458,7 @@ int main( const int argc, const char * const argv[] ) LZ_decoder decoder( dict_size ); // decode LZMA stream if( !decoder.decode_member() ) - { std::fputs( "Data error\n", stderr ); return 2; } + { std::fputs( "Data error.\n", stderr ); return 2; } Lzip_trailer trailer; // check trailer for( int i = 0; i < trailer_size; ++i ) trailer[i] = decoder.get_byte(); @@ -465,24 +466,27 @@ int main( const int argc, const char * const argv[] ) unsigned crc = 0; for( int i = 3; i >= 0; --i ) crc = ( crc << 8 ) + trailer[i]; if( crc != decoder.crc() ) - { std::fputs( "CRC mismatch\n", stderr ); retval = 2; } + { std::fputs( "CRC mismatch.\n", stderr ); retval = 2; } unsigned long long data_size = 0; for( int i = 11; i >= 4; --i ) data_size = ( data_size << 8 ) + trailer[i]; if( data_size != decoder.data_position() ) - { std::fputs( "Data size mismatch\n", stderr ); retval = 2; } + { std::fputs( "Data size mismatch.\n", stderr ); retval = 2; } + multi = !first_member; if( data_size == 0 ) empty = true; unsigned long long member_size = 0; for( int i = 19; i >= 12; --i ) member_size = ( member_size << 8 ) + trailer[i]; if( member_size != decoder.member_position() ) - { std::fputs( "Member size mismatch\n", stderr ); retval = 2; } + { std::fputs( "Member size mismatch.\n", stderr ); retval = 2; } if( retval ) return retval; } if( std::fclose( stdout ) != 0 ) { std::fprintf( stderr, "Error closing stdout: %s\n", std::strerror( errno ) ); return 1; } + if( empty && multi ) + { std::fputs( "Empty member not allowed.\n", stderr ); return 2; } return 0; } |