Skip to content

Commit f419d5f

Browse files
committed
#840 Restore stream position after reading data descriptor in read close
The data descriptor reading in mz_zip_entry_read_close seeks the stream to the local header and skips forward to read CRC and sizes. This left the stream at an incorrect position, corrupting subsequent mz_zip_goto_next_entry calls. Fix by saving and restoring the stream position and disk number around the seek-and-read block, matching the pattern used in mz_zip_entry_write_close.
1 parent b59f684 commit f419d5f

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

mz_zip.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,8 @@ int32_t mz_zip_entry_write(void *handle, const void *buf, int32_t len) {
20882088

20892089
int32_t mz_zip_entry_read_close(void *handle, uint32_t *crc32, int64_t *compressed_size, int64_t *uncompressed_size) {
20902090
mz_zip *zip = (mz_zip *)handle;
2091+
int64_t end_pos = 0;
2092+
int64_t end_disk_number = 0;
20912093
int64_t total_in = 0;
20922094
int32_t err = MZ_OK;
20932095
uint8_t zip64 = 0;
@@ -2110,6 +2112,10 @@ int32_t mz_zip_entry_read_close(void *handle, uint32_t *crc32, int64_t *compress
21102112

21112113
if ((zip->file_info.flag & MZ_ZIP_FLAG_DATA_DESCRIPTOR) &&
21122114
((zip->file_info.flag & MZ_ZIP_FLAG_MASK_LOCAL_INFO) == 0) && (crc32 || compressed_size || uncompressed_size)) {
2115+
/* Save the disk number and position we are to seek back after reading data descriptor */
2116+
end_pos = mz_stream_tell(zip->stream);
2117+
mz_stream_get_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, &end_disk_number);
2118+
21132119
/* Check to see if data descriptor is zip64 bit format or not */
21142120
if (mz_zip_extrafield_contains(zip->local_file_info.extrafield, zip->local_file_info.extrafield_size,
21152121
MZ_ZIP_EXTENSION_ZIP64, NULL) == MZ_OK) {
@@ -2129,6 +2135,10 @@ int32_t mz_zip_entry_read_close(void *handle, uint32_t *crc32, int64_t *compress
21292135
/* Read data descriptor */
21302136
if (err == MZ_OK)
21312137
err = mz_zip_entry_read_descriptor(zip->stream, zip64, crc32, compressed_size, uncompressed_size);
2138+
2139+
/* Restore disk number and position */
2140+
mz_stream_set_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, end_disk_number);
2141+
mz_stream_seek(zip->stream, end_pos, MZ_SEEK_SET);
21322142
}
21332143

21342144
/* If entire entry was not read verification will fail */

0 commit comments

Comments
 (0)