zip: avoid signed overflow in encrypted size checks

Avoid adding the encryption overhead directly to entry sizes when deciding
whether Zip64 is needed or when updating the stored compressed size.

For the Zip64 decision, compare against ZIP_4GB_MAX - additional_size. For
stored encrypted entries, use archive_ckd_add_i64() so the size update and
overflow check happen together.
This commit is contained in:
datauwu authored and datauwu committed 2026-07-03 23:48:50 +08:00
1 parent 42b2444920
commit 1c6e7b491f
1 file changed
+9 -3
+9 -3
View File
@@ -68,6 +68,7 @@
#include "archive_entry.h"
#include "archive_entry_locale.h"
#include "archive_hmac_private.h"
#include "archive_integer.h"
#include "archive_private.h"
#include "archive_random_private.h"
#include "archive_time_private.h"
@@ -1065,8 +1066,13 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
default:
break;
}
if (zip->entry_compression == COMPRESSION_STORE)
zip->entry_compressed_size += additional_size;
if (zip->entry_compression == COMPRESSION_STORE &&
archive_ckd_add_i64(&zip->entry_compressed_size,
zip->entry_compressed_size, additional_size)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"File size too large for encrypted ZIP entry");
return (ARCHIVE_FAILED);
}
}
/*
@@ -1080,7 +1086,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
* (compression might make file larger)
*/
if ((zip->flags & ZIP_FLAG_FORCE_ZIP64)
|| (zip->entry_uncompressed_size + additional_size > ZIP_4GB_MAX)
|| (zip->entry_uncompressed_size > ZIP_4GB_MAX - additional_size)
|| (zip->entry_uncompressed_size > ZIP_4GB_MAX_UNCOMPRESSED
&& zip->entry_compression != COMPRESSION_STORE)) {
MIN_VERSION_NEEDED(45);