Bug fix: a call to OutputJar::ReserveCdh potentially invalidates the addresses
returned by the previous calls of the same method. Keep each such address in a
separate scope.
RELNOTES: Crash in OutputJar::Close has been fixed
@@ -777,10 +777,8 @@ bool OutputJar::Close() {
size_t cen_size = cen_size_; // Save it before ReserveCdh updates it.
if (write_zip64_ecd) {
+ {
ECD64 *ecd64 = reinterpret_cast<ECD64 *>(ReserveCdh(sizeof(ECD64)));
- ECD64Locator *ecd64_locator =
- reinterpret_cast<ECD64Locator *>(ReserveCdh(sizeof(ECD64Locator)));
- ECD *ecd = reinterpret_cast<ECD *>(ReserveCdh(sizeof(ECD)));
ecd64->signature();
ecd64->remaining_size(sizeof(ECD64) - 12);
ecd64->version(0x031E); // Unix, version 3.0
@@ -789,9 +787,16 @@ bool OutputJar::Close() {
ecd64->total_entries(entries_);
ecd64->cen_size(cen_size);
ecd64->cen_offset(output_position);
+ }
+ {
+ ECD64Locator *ecd64_locator =
+ reinterpret_cast<ECD64Locator *>(ReserveCdh(sizeof(ECD64Locator)));
ecd64_locator->signature();
ecd64_locator->ecd64_offset(output_position + cen_size);
ecd64_locator->total_disks(1);
+ }
+ {
+ ECD *ecd = reinterpret_cast<ECD *>(ReserveCdh(sizeof(ECD)));
ecd->signature();
ecd->this_disk_entries16(0xFFFF);
ecd->total_entries16(0xFFFF);
@@ -804,6 +809,7 @@ bool OutputJar::Close() {
ecd->cen_size32(std::min(cen_size, static_cast<size_t>(0xFFFFFFFFUL)));
ecd->cen_offset32(
std::min(output_position, static_cast<off_t>(0x0FFFFFFFFL)));
+ }
} else {
ECD *ecd = reinterpret_cast<ECD *>(ReserveCdh(sizeof(ECD)));
ecd->signature();
