From 00184d655a72ed5a71aa80449250255fb8ac2caa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 23 Jan 2024 06:36:41 +0100 Subject: Merging upstream version 1.14~rc1. Signed-off-by: Daniel Baumann --- lzip_index.c | 90 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 42 deletions(-) (limited to 'lzip_index.c') diff --git a/lzip_index.c b/lzip_index.c index 559fd7a..688a370 100644 --- a/lzip_index.c +++ b/lzip_index.c @@ -1,5 +1,5 @@ /* Lunzip - Decompressor for the lzip format - Copyright (C) 2010-2022 Antonio Diaz Diaz. + Copyright (C) 2010-2023 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 @@ -88,17 +88,17 @@ static void Li_reverse_member_vector( struct Lzip_index * const li ) } -static bool Li_check_header_error( struct Lzip_index * const li, - const Lzip_header header ) +static bool Li_check_header( struct Lzip_index * const li, + const Lzip_header header ) { - if( !Lh_verify_magic( header ) ) - { add_error( li, bad_magic_msg ); li->retval = 2; return true; } - if( !Lh_verify_version( header ) ) + if( !Lh_check_magic( header ) ) + { add_error( li, bad_magic_msg ); li->retval = 2; return false; } + if( !Lh_check_version( header ) ) { add_error( li, bad_version( Lh_version( header ) ) ); li->retval = 2; - return true; } + return false; } if( !isvalid_ds( Lh_get_dictionary_size( header ) ) ) - { add_error( li, bad_dict_msg ); li->retval = 2; return true; } - return false; + { add_error( li, bad_dict_msg ); li->retval = 2; return false; } + return true; } static void Li_set_errno_error( struct Lzip_index * const li, @@ -119,10 +119,13 @@ static void Li_set_num_error( struct Lzip_index * const li, static bool Li_read_header( struct Lzip_index * const li, const int fd, - Lzip_header header, const long long pos ) + Lzip_header header, const long long pos, const bool ignore_marking ) { if( seek_read( fd, header, Lh_size, pos ) != Lh_size ) { Li_set_errno_error( li, "Error reading member header: " ); return false; } + uint8_t byte; + if( !ignore_marking && readblock( fd, &byte, 1 ) == 1 && byte != 0 ) + { add_error( li, marking_msg ); li->retval = 2; return false; } return true; } @@ -130,8 +133,7 @@ static bool Li_read_header( struct Lzip_index * const li, const int fd, /* If successful, push last member and set pos to member header. */ static bool Li_skip_trailing_data( struct Lzip_index * const li, const int fd, unsigned long long * const pos, - const bool ignore_trailing, - const bool loose_trailing ) + const struct Cl_options * const cl_opts ) { if( *pos < min_member_size ) return false; enum { block_size = 16384, @@ -157,31 +159,34 @@ static bool Li_skip_trailing_data( struct Lzip_index * const li, const int fd, const unsigned long long member_size = Lt_get_member_size( *trailer ); if( member_size == 0 ) /* skip trailing zeros */ { while( i > Lt_size && buffer[i-9] == 0 ) --i; continue; } - if( member_size > ipos + i || !Lt_verify_consistency( *trailer ) ) + if( member_size > ipos + i || !Lt_check_consistency( *trailer ) ) continue; Lzip_header header; - if( !Li_read_header( li, fd, header, ipos + i - member_size ) ) - return false; - if( !Lh_verify( header ) ) continue; + if( !Li_read_header( li, fd, header, ipos + i - member_size, + cl_opts->ignore_marking ) ) return false; + if( !Lh_check( header ) ) continue; const Lzip_header * header2 = (const Lzip_header *)( buffer + i ); const bool full_h2 = bsize - i >= Lh_size; - if( Lh_verify_prefix( *header2, bsize - i ) ) /* last member */ + if( Lh_check_prefix( *header2, bsize - i ) ) /* last member */ { if( !full_h2 ) add_error( li, "Last member in input file is truncated." ); - else if( !Li_check_header_error( li, *header2 ) ) + else if( Li_check_header( li, *header2 ) ) add_error( li, "Last member in input file is truncated or corrupt." ); li->retval = 2; return false; } - if( !loose_trailing && full_h2 && Lh_verify_corrupt( *header2 ) ) + if( !cl_opts->loose_trailing && full_h2 && Lh_check_corrupt( *header2 ) ) { add_error( li, corrupt_mm_msg ); li->retval = 2; return false; } - if( !ignore_trailing ) + if( !cl_opts->ignore_trailing ) { add_error( li, trailing_msg ); li->retval = 2; return false; } - *pos = ipos + i - member_size; + const unsigned long long data_size = Lt_get_data_size( *trailer ); + if( !cl_opts->ignore_empty && data_size == 0 ) + { add_error( li, empty_msg ); li->retval = 2; return false; } + *pos = ipos + i - member_size; /* good member */ const unsigned dictionary_size = Lh_get_dictionary_size( header ); if( li->dictionary_size < dictionary_size ) li->dictionary_size = dictionary_size; - return push_back_member( li, 0, Lt_get_data_size( *trailer ), *pos, - member_size, dictionary_size ); + return push_back_member( li, 0, data_size, *pos, member_size, + dictionary_size ); } if( ipos == 0 ) { Li_set_num_error( li, "Bad trailer at pos ", *pos - Lt_size ); @@ -196,7 +201,7 @@ static bool Li_skip_trailing_data( struct Lzip_index * const li, const int fd, bool Li_init( struct Lzip_index * const li, const int infd, - const bool ignore_trailing, const bool loose_trailing ) + const struct Cl_options * const cl_opts ) { li->member_vector = 0; li->error = 0; @@ -215,8 +220,8 @@ bool Li_init( struct Lzip_index * const li, const int infd, li->retval = 2; return false; } Lzip_header header; - if( !Li_read_header( li, infd, header, 0 ) ) return false; - if( Li_check_header_error( li, header ) ) return false; + if( !Li_read_header( li, infd, header, 0, cl_opts->ignore_marking ) || + !Li_check_header( li, header ) ) return false; unsigned long long pos = li->insize; /* always points to a header or to EOF */ while( pos >= min_member_size ) @@ -225,32 +230,33 @@ bool Li_init( struct Lzip_index * const li, const int infd, if( seek_read( infd, trailer, Lt_size, pos - Lt_size ) != Lt_size ) { Li_set_errno_error( li, "Error reading member trailer: " ); break; } const unsigned long long member_size = Lt_get_member_size( trailer ); - if( member_size > pos || !Lt_verify_consistency( trailer ) ) + if( member_size > pos || !Lt_check_consistency( trailer ) ) { /* bad trailer */ if( li->members <= 0 ) - { if( Li_skip_trailing_data( li, infd, &pos, ignore_trailing, - loose_trailing ) ) continue; else return false; } - Li_set_num_error( li, "Bad trailer at pos ", pos - Lt_size ); - break; + { if( Li_skip_trailing_data( li, infd, &pos, cl_opts ) ) continue; + return false; } + Li_set_num_error( li, "Bad trailer at pos ", pos - Lt_size ); break; } - if( !Li_read_header( li, infd, header, pos - member_size ) ) break; - if( !Lh_verify( header ) ) /* bad header */ + if( !Li_read_header( li, infd, header, pos - member_size, + cl_opts->ignore_marking ) ) break; + if( !Lh_check( header ) ) /* bad header */ { if( li->members <= 0 ) - { if( Li_skip_trailing_data( li, infd, &pos, ignore_trailing, - loose_trailing ) ) continue; else return false; } - Li_set_num_error( li, "Bad header at pos ", pos - member_size ); - break; + { if( Li_skip_trailing_data( li, infd, &pos, cl_opts ) ) continue; + return false; } + Li_set_num_error( li, "Bad header at pos ", pos - member_size ); break; } - pos -= member_size; + const unsigned long long data_size = Lt_get_data_size( trailer ); + if( !cl_opts->ignore_empty && data_size == 0 ) + { add_error( li, empty_msg ); li->retval = 2; break; } + pos -= member_size; /* good member */ const unsigned dictionary_size = Lh_get_dictionary_size( header ); if( li->dictionary_size < dictionary_size ) li->dictionary_size = dictionary_size; - if( !push_back_member( li, 0, Lt_get_data_size( trailer ), pos, - member_size, dictionary_size ) ) - return false; + if( !push_back_member( li, 0, data_size, pos, member_size, + dictionary_size ) ) return false; } - if( pos != 0 || li->members <= 0 ) + if( pos != 0 || li->members <= 0 || li->retval != 0 ) { Li_free_member_vector( li ); if( li->retval == 0 ) -- cgit v1.2.3