We allocate space early on to support the advertised number of
files. A malicious archive can set a nonsensical value here to exhaust
memory. This adds a check comparing the number of files to the number
of streams and the size of the total header.
Note that the just-added test does not actually fail without this.
The existing code recovers if the allocation fails, which it typically
will. The new check tightens the limit so that we reject nonsensical
file counts and avoid problems from large memory allocations.
return (-1);
if (UMAX_ENTRY < zip->numFiles)
return (-1);
+ /* Empty-file entries (those beyond the known stream count) require a
+ * kEmptyStream bitmap of ceil(numFiles/8) bytes; reject if that cannot
+ * fit in the remaining header bytes. Non-empty files need no header
+ * space here because they map directly to already-parsed streams. */
+ if (zip->numFiles > (uint64_t)zip->si.ss.unpack_streams &&
+ zip->numFiles - (uint64_t)zip->si.ss.unpack_streams >
+ 8 * zip->header_bytes_remaining)
+ return (-1);
zip->entries = calloc((size_t)zip->numFiles, sizeof(*zip->entries));
if (zip->entries == NULL)