diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2018-09-24 12:33:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2018-09-24 12:33:59 +0000 |
commit | 49939235e7e9dc44be30d428909a83bcb6893222 (patch) | |
tree | b08fea28574729e30050cd927b0abe77d39d8345 /in_place.c | |
parent | Adding upstream version 0.3. (diff) | |
download | xlunzip-upstream/0.4.tar.xz xlunzip-upstream/0.4.zip |
Adding upstream version 0.4.upstream/0.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'in_place.c')
-rw-r--r-- | in_place.c | 41 |
1 files changed, 21 insertions, 20 deletions
@@ -1,4 +1,4 @@ -/* Xlunzip - Test tool for the lunzip linux module +/* Xlunzip - Test tool for the lzip_decompress linux module Copyright (C) 2016-2018 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify @@ -78,7 +78,6 @@ uint8_t * read_file( const int infd, long * const buffer_sizep, if( errno ) { show_file_error( pp->name, "Error reading file", errno ); free( buffer ); return 0; } - close( infd ); *buffer_sizep = buffer_size; *file_sizep = file_size; return buffer; @@ -87,8 +86,8 @@ uint8_t * read_file( const int infd, long * const buffer_sizep, struct File_sizes { - long long csize; - long long dsize; + unsigned long long csize; + unsigned long long dsize; long trailing; }; @@ -96,25 +95,31 @@ const char * set_file_sizes( struct File_sizes * const file_sizes, const uint8_t * const buffer, const long file_size ) { if( file_size < min_member_size ) return "Input file is too short."; - const Lzip_header * header = (Lzip_header *)buffer; + const Lzip_header * header = (const Lzip_header *)buffer; if( !Lh_verify_magic( *header ) ) return "Bad magic number (file not in lzip format)."; if( !Lh_verify_version( *header ) ) return "Version of lzip member format not supported."; file_sizes->csize = file_sizes->dsize = file_sizes->trailing = 0; - long long pos = file_size; /* always points to a header or to EOF */ + unsigned long pos = file_size; /* always points to a header or to EOF */ while( pos >= min_member_size ) { const Lzip_trailer * const trailer = - (Lzip_trailer *)( buffer + pos - Lt_size ); - const long long member_size = Lt_get_member_size( *trailer ); + (const Lzip_trailer *)( buffer + pos - Lt_size ); + const unsigned long long member_size = Lt_get_member_size( *trailer ); if( member_size < min_member_size || member_size > pos ) { - if( file_sizes->csize == 0 ) { --pos; continue; } /* maybe trailing data */ + if( file_sizes->csize == 0 ) /* maybe trailing data */ + { + if( member_size == 0 ) /* skip trailing zeros */ + while( pos > Lt_size && buffer[pos-8] == 0 ) --pos; + else --pos; + continue; + } return "Member size in trailer is corrupt."; } - header = (Lzip_header *)( buffer + pos - member_size ); + header = (const Lzip_header *)( buffer + pos - member_size ); if( !Lh_verify_magic( *header ) || !Lh_verify_version( *header ) ) { if( file_sizes->csize == 0 ) { --pos; continue; } /* maybe trailing data */ @@ -123,7 +128,7 @@ 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; - header = (Lzip_header *)( buffer + pos ); + header = (const Lzip_header *)( buffer + pos ); if( file_size - pos > Lh_size && Lh_verify_magic( *header ) && Lh_verify_version( *header ) ) return "Last member in input file is truncated or corrupt."; @@ -133,8 +138,10 @@ const char * set_file_sizes( struct File_sizes * const file_sizes, file_sizes->dsize += Lt_get_data_size( *trailer ); } if( pos != 0 || file_sizes->csize == 0 ) return "Can't get file sizes."; - if( file_sizes->csize + file_sizes->trailing != file_size ) + if( file_sizes->csize + file_sizes->trailing != (unsigned long)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."; return 0; } @@ -165,15 +172,9 @@ int decompress_in_place( const int infd, struct Pretty_print * const pp, const char * emsg = set_file_sizes( &file_sizes, buffer, file_size ); if( emsg ) { show_file_error( pp->name, emsg, 0 ); return 2; } - const long long csize = file_sizes.csize; - const long long dsize = file_sizes.dsize; + const long csize = file_sizes.csize; + const long dsize = file_sizes.dsize; /* const long trailing = file_sizes.trailing; */ - if( csize <= 0 || csize > LONG_MAX ) - { show_file_error( pp->name, "File is larger than LONG_MAX.", 0 ); - return 2; } - if( dsize < 0 || dsize > LONG_MAX ) - { show_file_error( pp->name, "Data is larger than LONG_MAX.", 0 ); - return 2; } /* ( (csize-36+63) >> 6 ) + 36 never failed with single member */ const long rextra = ( csize >> 5 ) + 72; if( buffer_size < dsize + rextra ) /* avoid realloc if big enough */ |