The issue is that unztell64() does not return the correct value if
the position in the current file (in the ZIP archive) is beyond 4
GB. The cause is that unzReadCurrentFile() does not account for
pfile_in_zip_read_info->stream.total_out at line 1854 of unzip.c
wrapping around (it is a 32-bit variable). So, on line 1860
uTotalOutAfter can be *less* than uTotalOutBefore, propagating the
wraparound to uOutThis, which in turn is added to
pfile_in_zip_read_info->total_out_64. That has the effect of
subtracting 4 GB.
err = Z_DATA_ERROR;
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+ /* Detect overflow, because z_stream.total_out is uLong (32 bits) */
+ if (uTotalOutAfter<uTotalOutBefore)
+ uTotalOutAfter += 1LL << 32; /* Add maximum value of uLong + 1 */
uOutThis = uTotalOutAfter-uTotalOutBefore;
pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;