in ios/CodePush/SSZipArchive/minizip/unzip.c [1260:1483]
extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len)
{
int err = UNZ_OK;
uInt read = 0;
unz64_s *s;
file_in_zip64_read_info_s *pfile_in_zip_read_info;
if (file == NULL)
return UNZ_PARAMERROR;
s = (unz64_s *)file;
pfile_in_zip_read_info = s->pfile_in_zip_read;
if (pfile_in_zip_read_info == NULL)
return UNZ_PARAMERROR;
if (pfile_in_zip_read_info->read_buffer == NULL)
return UNZ_END_OF_LIST_OF_FILE;
if (len == 0)
return 0;
pfile_in_zip_read_info->stream.next_out = (Bytef *)buf;
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
if (pfile_in_zip_read_info->raw) {
if (len > pfile_in_zip_read_info->rest_read_compressed + pfile_in_zip_read_info->stream.avail_in)
pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed +
pfile_in_zip_read_info->stream.avail_in;
} else {
// NOTE:
// This bit of code seems to try to set the amount of space in the output buffer based on the
// value stored in the headers stored in the .zip file. However, if those values are incorrect
// it may result in a loss of data when uncompresssing that file. The compressed data is still
// legit and will deflate without knowing the uncompressed code so this tidbit is unnecessary and
// may cause issues for some .zip files.
//
// It's removed in here to fix those issues.
//
// See: https://github.com/ZipArchive/ziparchive/issues/16
//
/*
FIXME: Upgrading to minizip 1.1 caused issues here, Uncommented the code that was commented before. 11/24/2015
*/
if (len > pfile_in_zip_read_info->rest_read_uncompressed)
pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
}
while (pfile_in_zip_read_info->stream.avail_out > 0) {
if (pfile_in_zip_read_info->stream.avail_in == 0) {
uInt bytes_to_read = UNZ_BUFSIZE;
uInt bytes_not_read = 0;
uInt bytes_read = 0;
uInt total_bytes_read = 0;
if (pfile_in_zip_read_info->stream.next_in != NULL)
bytes_not_read = (uInt)(pfile_in_zip_read_info->read_buffer + UNZ_BUFSIZE -
pfile_in_zip_read_info->stream.next_in);
bytes_to_read -= bytes_not_read;
if (bytes_not_read > 0)
memcpy(pfile_in_zip_read_info->read_buffer, pfile_in_zip_read_info->stream.next_in, bytes_not_read);
if (pfile_in_zip_read_info->rest_read_compressed < bytes_to_read)
bytes_to_read = (uInt)pfile_in_zip_read_info->rest_read_compressed;
while (total_bytes_read != bytes_to_read) {
if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream,
pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile,
ZLIB_FILEFUNC_SEEK_SET) != 0)
return UNZ_ERRNO;
bytes_read = (int)ZREAD64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream,
pfile_in_zip_read_info->read_buffer + bytes_not_read + total_bytes_read,
bytes_to_read - total_bytes_read);
total_bytes_read += bytes_read;
pfile_in_zip_read_info->pos_in_zipfile += bytes_read;
if (bytes_read == 0) {
if (ZERROR64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream))
return UNZ_ERRNO;
err = unzGoToNextDisk(file);
if (err != UNZ_OK)
return err;
pfile_in_zip_read_info->pos_in_zipfile = 0;
pfile_in_zip_read_info->filestream = s->filestream;
}
}
#ifndef NOUNCRYPT
if ((s->cur_file_info.flag & 1) != 0) {
#ifdef HAVE_AES
if (s->cur_file_info.compression_method == AES_METHOD) {
fcrypt_decrypt(pfile_in_zip_read_info->read_buffer, bytes_to_read, &s->pfile_in_zip_read->aes_ctx);
} else
#endif
{
uInt i;
for (i = 0; i < total_bytes_read; i++)
pfile_in_zip_read_info->read_buffer[i] =
zdecode(s->keys, s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]);
}
}
#endif
pfile_in_zip_read_info->rest_read_compressed -= total_bytes_read;
pfile_in_zip_read_info->stream.next_in = (Bytef *)pfile_in_zip_read_info->read_buffer;
pfile_in_zip_read_info->stream.avail_in = (uInt)bytes_not_read + total_bytes_read;
}
if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) {
uInt copy, i;
if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
(pfile_in_zip_read_info->rest_read_compressed == 0))
return (read == 0) ? UNZ_EOF : read;
if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in)
copy = pfile_in_zip_read_info->stream.avail_out;
else
copy = pfile_in_zip_read_info->stream.avail_in;
for (i = 0; i < copy; i++)
*(pfile_in_zip_read_info->stream.next_out + i) =
*(pfile_in_zip_read_info->stream.next_in + i);
pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + copy;
pfile_in_zip_read_info->rest_read_uncompressed -= copy;
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
pfile_in_zip_read_info->stream.next_out, copy);
pfile_in_zip_read_info->stream.avail_in -= copy;
pfile_in_zip_read_info->stream.avail_out -= copy;
pfile_in_zip_read_info->stream.next_out += copy;
pfile_in_zip_read_info->stream.next_in += copy;
pfile_in_zip_read_info->stream.total_out += copy;
read += copy;
} else if (pfile_in_zip_read_info->compression_method == Z_BZIP2ED) {
#ifdef HAVE_BZIP2
uLong total_out_before, total_out_after;
const Bytef *buf_before;
uLong out_bytes;
pfile_in_zip_read_info->bstream.next_in = (char *)pfile_in_zip_read_info->stream.next_in;
pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
pfile_in_zip_read_info->bstream.next_out = (char *)pfile_in_zip_read_info->stream.next_out;
pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
total_out_before = pfile_in_zip_read_info->bstream.total_out_lo32;
buf_before = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
err = BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
total_out_after = pfile_in_zip_read_info->bstream.total_out_lo32;
out_bytes = total_out_after - total_out_before;
pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + out_bytes;
pfile_in_zip_read_info->rest_read_uncompressed -= out_bytes;
pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, buf_before, (uInt)(out_bytes));
read += (uInt)(total_out_after - total_out_before);
pfile_in_zip_read_info->stream.next_in = (Bytef *)pfile_in_zip_read_info->bstream.next_in;
pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
pfile_in_zip_read_info->stream.next_out = (Bytef *)pfile_in_zip_read_info->bstream.next_out;
pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
if (err == BZ_STREAM_END)
return (read == 0) ? UNZ_EOF : read;
if (err != BZ_OK)
break;
#endif
} else {
ZPOS64_T total_out_before, total_out_after;
const Bytef *buf_before;
ZPOS64_T out_bytes;
int flush = Z_SYNC_FLUSH;
total_out_before = pfile_in_zip_read_info->stream.total_out;
buf_before = pfile_in_zip_read_info->stream.next_out;
/*
if ((pfile_in_zip_read_info->rest_read_uncompressed ==
pfile_in_zip_read_info->stream.avail_out) &&
(pfile_in_zip_read_info->rest_read_compressed == 0))
flush = Z_FINISH;
*/
err = inflate(&pfile_in_zip_read_info->stream, flush);
if ((err >= 0) && (pfile_in_zip_read_info->stream.msg != NULL))
err = Z_DATA_ERROR;
total_out_after = pfile_in_zip_read_info->stream.total_out;
out_bytes = total_out_after - total_out_before;
pfile_in_zip_read_info->total_out_64 += out_bytes;
pfile_in_zip_read_info->rest_read_uncompressed -= out_bytes;
pfile_in_zip_read_info->crc32 =
crc32(pfile_in_zip_read_info->crc32, buf_before, (uInt)(out_bytes));
read += (uInt)(total_out_after - total_out_before);
if (err == Z_STREAM_END)
return (read == 0) ? UNZ_EOF : read;
if (err != Z_OK)
break;
}
}
if (err == Z_OK)
return read;
return err;
}