in contrib/libz/contrib/minizip/zip.c [1514:1748]
extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
{
zip64_internal* zi;
ZPOS64_T compressed_size;
uLong invalidValue = 0xffffffff;
unsigned datasize = 0;
int err=ZIP_OK;
if (file == NULL)
return ZIP_PARAMERROR;
zi = (zip64_internal*)file;
if (zi->in_opened_file_inzip == 0)
return ZIP_PARAMERROR;
zi->ci.stream.avail_in = 0;
if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
{
while (err==ZIP_OK)
{
uLong uTotalOutBefore;
if (zi->ci.stream.avail_out == 0)
{
if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
err = ZIP_ERRNO;
zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
zi->ci.stream.next_out = zi->ci.buffered_data;
}
uTotalOutBefore = zi->ci.stream.total_out;
err=deflate(&zi->ci.stream, Z_FINISH);
zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
}
}
else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
{
#ifdef HAVE_BZIP2
err = BZ_FINISH_OK;
while (err==BZ_FINISH_OK)
{
uLong uTotalOutBefore;
if (zi->ci.bstream.avail_out == 0)
{
if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
err = ZIP_ERRNO;
zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
}
uTotalOutBefore = zi->ci.bstream.total_out_lo32;
err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
if(err == BZ_STREAM_END)
err = Z_STREAM_END;
zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
}
if(err == BZ_FINISH_OK)
err = ZIP_OK;
#endif
}
if (err==Z_STREAM_END)
err=ZIP_OK; /* this is normal */
if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
{
if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
err = ZIP_ERRNO;
}
if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
{
int tmp_err = deflateEnd(&zi->ci.stream);
if (err == ZIP_OK)
err = tmp_err;
zi->ci.stream_initialised = 0;
}
#ifdef HAVE_BZIP2
else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
{
int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
if (err==ZIP_OK)
err = tmperr;
zi->ci.stream_initialised = 0;
}
#endif
if (!zi->ci.raw)
{
crc32 = (uLong)zi->ci.crc32;
uncompressed_size = zi->ci.totalUncompressedData;
}
compressed_size = zi->ci.totalCompressedData;
# ifndef NOCRYPT
compressed_size += zi->ci.crypt_header_size;
# endif
// update Current Item crc and sizes,
if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
{
/*version Made by*/
zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
/*version needed*/
zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
}
zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
if(compressed_size >= 0xffffffff)
zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
else
zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
/// set internal file attributes field
if (zi->ci.stream.data_type == Z_ASCII)
zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
if(uncompressed_size >= 0xffffffff)
zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
else
zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
// Add ZIP64 extra info field for uncompressed size
if(uncompressed_size >= 0xffffffff)
datasize += 8;
// Add ZIP64 extra info field for compressed size
if(compressed_size >= 0xffffffff)
datasize += 8;
// Add ZIP64 extra info field for relative offset to local file header of current file
if(zi->ci.pos_local_header >= 0xffffffff)
datasize += 8;
if(datasize > 0)
{
char* p = NULL;
if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
{
// we can not write more data to the buffer that we have room for.
return ZIP_BADZIPFILE;
}
p = zi->ci.central_header + zi->ci.size_centralheader;
// Add Extra Information Header for 'ZIP64 information'
zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
p += 2;
zip64local_putValue_inmemory(p, datasize, 2); // DataSize
p += 2;
if(uncompressed_size >= 0xffffffff)
{
zip64local_putValue_inmemory(p, uncompressed_size, 8);
p += 8;
}
if(compressed_size >= 0xffffffff)
{
zip64local_putValue_inmemory(p, compressed_size, 8);
p += 8;
}
if(zi->ci.pos_local_header >= 0xffffffff)
{
zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
p += 8;
}
// Update how much extra free space we got in the memory buffer
// and increase the centralheader size so the new ZIP64 fields are included
// ( 4 below is the size of HeaderID and DataSize field )
zi->ci.size_centralExtraFree -= datasize + 4;
zi->ci.size_centralheader += datasize + 4;
// Update the extra info size field
zi->ci.size_centralExtra += datasize + 4;
zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
}
if (err==ZIP_OK)
err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
free(zi->ci.central_header);
if (err==ZIP_OK)
{
// Update the LocalFileHeader with the new values.
ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
err = ZIP_ERRNO;
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
{
if(zi->ci.pos_zip64extrainfo > 0)
{
// Update the size in the ZIP64 extended field.
if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
err = ZIP_ERRNO;
if (err==ZIP_OK) /* compressed size, unknown */
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
if (err==ZIP_OK) /* uncompressed size, unknown */
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
}
else
err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
}
else
{
if (err==ZIP_OK) /* compressed size, unknown */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
if (err==ZIP_OK) /* uncompressed size, unknown */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
}
if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
err = ZIP_ERRNO;
}
zi->number_entry ++;
zi->in_opened_file_inzip = 0;
return err;
}