Skip to content

Commit f197f4c

Browse files
authored
Merge pull request #82660 from akrieger/corrupted_corruption_handling
Fix zzip corruption recovery miscalculating when a frame runs past EOF
2 parents 3aa1b84 + 4ec6709 commit f197f4c

File tree

1 file changed

+12
-19
lines changed

1 file changed

+12
-19
lines changed

src/zzip.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -854,36 +854,29 @@ bool zzip::rewrite_footer()
854854
size_t zzip_remaining = zzip_len - scan_offset;
855855

856856
// For each entry we expect at least a filename and checksum header.
857-
void *file_ptr = nullptr; ;
858-
size_t file_len = 0;
859-
std::tie( file_ptr, file_len ) = read_and_skip_entry_metadata(
860-
file_base_plus( scan_offset ),
861-
zzip_remaining,
862-
&filename_opt,
863-
&checksum_opt );
864-
if( file_ptr == nullptr || file_len == 0 || file_len > zzip_remaining ) {
857+
void *file_ptr = nullptr;
858+
std::tie( file_ptr, zzip_remaining ) = read_and_skip_entry_metadata(
859+
file_base_plus( scan_offset ),
860+
zzip_remaining,
861+
&filename_opt,
862+
&checksum_opt );
863+
if( file_ptr == nullptr || zzip_remaining == 0 ) {
865864
break;
866865
}
867-
// zzip_remaining = length of zzip from start of entry
868-
// file_len = length of zzip from start of compressed file frame
869-
// -> offset of file from start of entry = zzip_remaining - file_len
870-
file_offset = scan_offset + ( zzip_remaining - file_len );
866+
867+
file_offset = zzip_len - zzip_remaining;
871868

872869
if( !filename_opt.has_value() || !checksum_opt.has_value() ) {
873870
// Missing required metadata.
874871
break;
875872
}
876-
if( file_offset >= file_len ) {
877-
// We've run off the end of the file and read past the original footer.
878-
break;
879-
}
880873

881-
void *file_frame_begin = file_base_plus( file_offset );
882-
size_t file_frame_size = ZSTD_findFrameCompressedSize( file_frame_begin, file_len );
874+
size_t file_frame_size = ZSTD_findFrameCompressedSize( file_ptr, zzip_remaining );
883875
if( ZSTD_isError( file_frame_size ) ) {
884876
break;
885877
}
886-
uint64_t checksum = XXH64( file_frame_begin, file_frame_size, kCheckumSeed );
878+
879+
uint64_t checksum = XXH64( file_ptr, file_frame_size, kCheckumSeed );
887880
if( checksum != checksum_opt ) {
888881
// Corruption in the compressed frame. Don't try to recover it, assume
889882
// everything after is lost.

0 commit comments

Comments
 (0)