/* Structural information about the archive. */
struct archive_string format_name;
int64_t central_directory_offset;
- int64_t central_directory_offset_actual;
+ int64_t central_directory_offset_adjusted;
size_t central_directory_entries_total;
size_t central_directory_entries_on_this_disk;
int has_encrypted_entries;
static int
read_eocd(struct zip *zip, const char *p, int64_t current_offset)
{
+ uint16_t disk_num = archive_le16dec(p + 4);
+ uint32_t cd_size = archive_le32dec(p + 12);
+ uint32_t cd_offset = archive_le32dec(p + 16);
+
/* Sanity-check the EOCD we've found. */
/* This must be the first volume. */
- if (archive_le16dec(p + 4) != 0)
+ if (disk_num != 0)
return 0;
/* Central directory must be on this volume. */
- if (archive_le16dec(p + 4) != archive_le16dec(p + 6))
+ if (disk_num != archive_le16dec(p + 6))
return 0;
/* All central directory entries must be on this volume. */
if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
return 0;
/* Central directory can't extend beyond start of EOCD record. */
- if (archive_le32dec(p + 16) + archive_le32dec(p + 12)
- > current_offset)
+ if (cd_offset + cd_size > current_offset)
return 0;
/* Save the central directory location for later use. */
- zip->central_directory_offset = archive_le32dec(p + 16);
- zip->central_directory_offset_actual = current_offset
- - archive_le32dec(p+12) - 1;
+ zip->central_directory_offset = cd_offset;
+ zip->central_directory_offset_adjusted = current_offset - cd_size;
/* This is just a tiny bit higher than the maximum
returned by the streaming Zip bidder. This ensures
/* Save the central directory offset for later use. */
zip->central_directory_offset = archive_le64dec(p + 48);
- zip->central_directory_offset_actual = zip->central_directory_offset;
+ /* TODO: Needs scanning backwards to find the eocd64 instead of assuming */
+ zip->central_directory_offset_adjusted = zip->central_directory_offset;
return 32;
}
* know the correction we need to apply to account for leading
* padding.
*/
- if (__archive_read_seek(a, zip->central_directory_offset_actual, SEEK_SET)
+ if (__archive_read_seek(a, zip->central_directory_offset_adjusted, SEEK_SET)
< 0)
return ARCHIVE_FATAL;