summaryrefslogtreecommitdiffstats
path: root/file_index.cc
diff options
context:
space:
mode:
Diffstat (limited to 'file_index.cc')
-rw-r--r--file_index.cc42
1 files changed, 22 insertions, 20 deletions
diff --git a/file_index.cc b/file_index.cc
index f2f81e7..b3d7d70 100644
--- a/file_index.cc
+++ b/file_index.cc
@@ -1,5 +1,5 @@
/* Lziprecover - Data recovery tool for the lzip format
- Copyright (C) 2009-2017 Antonio Diaz Diaz.
+ Copyright (C) 2009-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
@@ -56,8 +56,9 @@ void File_index::set_num_error( const char * const msg, unsigned long long num )
// If successful, push last member and set pos to member header.
-bool File_index::skip_trailing_data( const int fd, const bool ignore_bad_ds,
- long long & pos )
+bool File_index::skip_trailing_data( const int fd, long long & pos,
+ const bool ignore_bad_ds,
+ const bool ignore_trailing, const bool loose_trailing )
{
enum { block_size = 16384,
buffer_size = block_size + File_trailer::size - 1 + File_header::size };
@@ -92,10 +93,13 @@ bool File_index::skip_trailing_data( const int fd, const bool ignore_bad_ds,
if( !header.verify_magic() || !header.verify_version() ||
( !ignore_bad_ds && !isvalid_ds( dictionary_size ) ) ) continue;
if( (*(File_header *)( buffer + i )).verify_prefix( bsize - i ) )
- {
- error_ = "Last member in input file is truncated or corrupt.";
- retval_ = 2; return false;
- }
+ { error_ = "Last member in input file is truncated or corrupt.";
+ retval_ = 2; return false; }
+ if( !loose_trailing && bsize - i >= File_header::size &&
+ (*(File_header *)( buffer + i )).verify_corrupt() )
+ { error_ = corrupt_mm_msg; retval_ = 2; return false; }
+ if( !ignore_trailing )
+ { error_ = trailing_msg; retval_ = 2; return false; }
pos = ipos + i - member_size;
member_vector.push_back( Member( 0, trailer.data_size(), pos,
member_size, dictionary_size ) );
@@ -114,7 +118,7 @@ bool File_index::skip_trailing_data( const int fd, const bool ignore_bad_ds,
File_index::File_index( const int infd, const bool ignore_bad_ds,
- const bool ignore_trailing )
+ const bool ignore_trailing, const bool loose_trailing )
: isize( lseek( infd, 0, SEEK_END ) ), retval_( 0 )
{
if( isize < 0 )
@@ -145,11 +149,10 @@ File_index::File_index( const int infd, const bool ignore_bad_ds,
const unsigned long long member_size = trailer.member_size();
if( member_size < min_member_size || member_size > (unsigned long long)pos )
{
- if( !member_vector.empty() )
- set_num_error( "Member size in trailer is corrupt at pos ", pos - 8 );
- else if( skip_trailing_data( infd, ignore_bad_ds, pos ) )
- { if( ignore_trailing ) continue;
- error_ = trailing_msg; retval_ = 2; return; }
+ if( member_vector.empty() )
+ { if( skip_trailing_data( infd, pos, ignore_bad_ds, ignore_trailing,
+ loose_trailing ) ) continue; else return; }
+ set_num_error( "Member size in trailer is corrupt at pos ", pos - 8 );
break;
}
if( seek_read( infd, header.data, File_header::size,
@@ -159,11 +162,10 @@ File_index::File_index( const int infd, const bool ignore_bad_ds,
if( !header.verify_magic() || !header.verify_version() ||
( !ignore_bad_ds && !isvalid_ds( dictionary_size ) ) )
{
- if( !member_vector.empty() )
- set_num_error( "Bad header at pos ", pos - member_size );
- else if( skip_trailing_data( infd, ignore_bad_ds, pos ) )
- { if( ignore_trailing ) continue;
- error_ = trailing_msg; retval_ = 2; return; }
+ if( member_vector.empty() )
+ { if( skip_trailing_data( infd, pos, ignore_bad_ds, ignore_trailing,
+ loose_trailing ) ) continue; else return; }
+ set_num_error( "Bad header at pos ", pos - member_size );
break;
}
pos -= member_size;
@@ -261,8 +263,8 @@ File_index::File_index( const std::vector< int > & infd_vector,
}
}
pos -= member_size;
- member_vector.push_back( Member( 0, trailer.data_size(),
- pos, member_size, 0 ) );
+ member_vector.push_back( Member( 0, trailer.data_size(), pos,
+ member_size, 0 ) );
}
error:
if( pos != 0 || member_vector.empty() )