diff options
Diffstat (limited to 'file_index.c')
-rw-r--r-- | file_index.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/file_index.c b/file_index.c index e737608..1872d67 100644 --- a/file_index.c +++ b/file_index.c @@ -1,5 +1,5 @@ /* Lunzip - Decompressor for the lzip format - Copyright (C) 2010-2017 Antonio Diaz Diaz. + Copyright (C) 2010-2018 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 @@ -108,7 +108,9 @@ static void Fi_set_num_error( struct File_index * const fi, /* If successful, push last member and set pos to member header. */ static bool Fi_skip_trailing_data( struct File_index * const fi, - const int fd, long long * const pos ) + const int fd, long long * const pos, + const bool ignore_trailing, + const bool loose_trailing ) { enum { block_size = 16384, buffer_size = block_size + Ft_size - 1 + Fh_size }; @@ -152,6 +154,11 @@ static bool Fi_skip_trailing_data( struct File_index * const fi, add_error( fi, "Last member in input file is truncated or corrupt." ); fi->retval = 2; return false; } + if( !loose_trailing && bsize - i >= Fh_size && + Fh_verify_corrupt( buffer + i ) ) + { add_error( fi, corrupt_mm_msg ); fi->retval = 2; return false; } + if( !ignore_trailing ) + { add_error( fi, trailing_msg ); fi->retval = 2; return false; } *pos = ipos + i - member_size; return push_back_member( fi, 0, Ft_get_data_size( *trailer ), *pos, member_size, dictionary_size ); @@ -170,7 +177,7 @@ static bool Fi_skip_trailing_data( struct File_index * const fi, bool Fi_init( struct File_index * const fi, const int infd, - const bool ignore_trailing ) + const bool ignore_trailing, const bool loose_trailing ) { File_header header; long long pos; @@ -211,12 +218,10 @@ bool Fi_init( struct File_index * const fi, const int infd, member_size = Ft_get_member_size( trailer ); if( member_size < min_member_size || member_size > (unsigned long long)pos ) { - if( fi->members > 0 ) - Fi_set_num_error( fi, "Member size in trailer is corrupt at pos ", - pos - 8 ); - else if( Fi_skip_trailing_data( fi, infd, &pos ) ) - { if( ignore_trailing ) continue; - add_error( fi, trailing_msg ); fi->retval = 2; return false; } + if( fi->members <= 0 ) + { if( Fi_skip_trailing_data( fi, infd, &pos, ignore_trailing, + loose_trailing ) ) continue; else return false; } + Fi_set_num_error( fi, "Member size in trailer is corrupt at pos ", pos - 8 ); break; } if( seek_read( infd, header, Fh_size, pos - member_size ) != Fh_size ) @@ -225,11 +230,10 @@ bool Fi_init( struct File_index * const fi, const int infd, if( !Fh_verify_magic( header ) || !Fh_verify_version( header ) || !isvalid_ds( dictionary_size ) ) { - if( fi->members > 0 ) - Fi_set_num_error( fi, "Bad header at pos ", pos - member_size ); - else if( Fi_skip_trailing_data( fi, infd, &pos ) ) - { if( ignore_trailing ) continue; - add_error( fi, trailing_msg ); fi->retval = 2; return false; } + if( fi->members <= 0 ) + { if( Fi_skip_trailing_data( fi, infd, &pos, ignore_trailing, + loose_trailing ) ) continue; else return false; } + Fi_set_num_error( fi, "Bad header at pos ", pos - member_size ); break; } pos -= member_size; |