mirror of
				https://github.com/eledio-devices/thirdparty-miniz.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Streaming ZIP creation, automatic ZIP64 switching and UTF8 filenames
This commit is contained in:
		
							
								
								
									
										317
									
								
								miniz_zip.c
									
									
									
									
									
								
							
							
						
						
									
										317
									
								
								miniz_zip.c
									
									
									
									
									
								
							| @@ -135,6 +135,8 @@ enum | |||||||
|     MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20, |     MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20, | ||||||
|     MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001, |     MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001, | ||||||
|     MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50, |     MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50, | ||||||
|  | 	MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24, | ||||||
|  | 	MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16, | ||||||
|  |  | ||||||
|     // Central directory header record offsets |     // Central directory header record offsets | ||||||
|     MZ_ZIP_CDH_SIG_OFS = 0, |     MZ_ZIP_CDH_SIG_OFS = 0, | ||||||
| @@ -2523,9 +2525,9 @@ mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilena | |||||||
| } | } | ||||||
|  |  | ||||||
| // TODO: pArchive_name is a terrible name here! | // TODO: pArchive_name is a terrible name here! | ||||||
| mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags) | mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags, time_t* last_modified) | ||||||
| { | { | ||||||
|     return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0); |     return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0, 0, last_modified, NULL, 0, NULL, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| typedef struct | typedef struct | ||||||
| @@ -2631,7 +2633,8 @@ static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char | |||||||
|                                                 const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, |                                                 const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, | ||||||
|                                                 mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, |                                                 mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, | ||||||
|                                                 mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, |                                                 mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, | ||||||
|                                                 mz_uint64 local_header_ofs, mz_uint32 ext_attributes) |                                                 mz_uint64 local_header_ofs, mz_uint32 ext_attributes, | ||||||
|  | 											    const char* user_extra_data, mz_uint user_extra_data_len) | ||||||
| { | { | ||||||
|     mz_zip_internal_state *pState = pZip->m_pState; |     mz_zip_internal_state *pState = pZip->m_pState; | ||||||
|     mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; |     mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; | ||||||
| @@ -2645,15 +2648,16 @@ static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet |     // miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet | ||||||
|     if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) >= MZ_UINT32_MAX) |     if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + user_extra_data_len + comment_size) >= MZ_UINT32_MAX) | ||||||
|         return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); |         return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); | ||||||
|  |  | ||||||
|     if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes)) |     if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size + user_extra_data_len, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes)) | ||||||
|         return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); |         return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); | ||||||
|  |  | ||||||
|     if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || |     if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || | ||||||
|         (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) || |         (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) || | ||||||
|         (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) || |         (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) || | ||||||
|  | 		(!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) || | ||||||
|         (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) || |         (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) || | ||||||
|         (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1))) |         (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1))) | ||||||
|     { |     { | ||||||
| @@ -2707,11 +2711,13 @@ static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_fil | |||||||
|     return MZ_TRUE; |     return MZ_TRUE; | ||||||
| } | } | ||||||
|  |  | ||||||
| mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32) | mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, | ||||||
|  | 	mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, mz_uint16 bit_flags, time_t* last_modified, | ||||||
|  | 	const char* user_extra_data, mz_uint user_extra_data_len, const char* user_extra_data_central, mz_uint user_extra_data_central_len) | ||||||
| { | { | ||||||
|     mz_uint16 method = 0, dos_time = 0, dos_date = 0; |     mz_uint16 method = 0, dos_time = 0, dos_date = 0; | ||||||
|     mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; |     mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; | ||||||
|     mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, extra_data_file_ofs = 0, comp_size = 0; |     mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; | ||||||
|     size_t archive_name_size; |     size_t archive_name_size; | ||||||
|     mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; |     mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; | ||||||
|     tdefl_compressor *pComp = NULL; |     tdefl_compressor *pComp = NULL; | ||||||
| @@ -2739,9 +2745,15 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
|     else |     else | ||||||
|     { |     { | ||||||
| 		if (pZip->m_total_files == MZ_UINT16_MAX) | 		if (pZip->m_total_files == MZ_UINT16_MAX) | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); | 		{ | ||||||
|  | 			pState->m_zip64 = MZ_TRUE; | ||||||
|  | 			//return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); | ||||||
|  | 		} | ||||||
| 		if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) | 		if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | 		{ | ||||||
|  | 			pState->m_zip64 = MZ_TRUE; | ||||||
|  | 			//return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|  | 		} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) |     if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) | ||||||
| @@ -2750,6 +2762,12 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
|     if (!mz_zip_writer_validate_archive_name(pArchive_name)) |     if (!mz_zip_writer_validate_archive_name(pArchive_name)) | ||||||
|         return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); |         return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); | ||||||
|  |  | ||||||
|  | 	if (last_modified != NULL) | ||||||
|  | 	{ | ||||||
|  | 		mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
| #ifndef MINIZ_NO_TIME | #ifndef MINIZ_NO_TIME | ||||||
| 	{ | 	{ | ||||||
| 		MZ_TIME_T cur_time; | 		MZ_TIME_T cur_time; | ||||||
| @@ -2757,6 +2775,7 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
| 		mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date); | 		mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date); | ||||||
| 	} | 	} | ||||||
| #endif // #ifndef MINIZ_NO_TIME | #endif // #ifndef MINIZ_NO_TIME | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     archive_name_size = strlen(pArchive_name); |     archive_name_size = strlen(pArchive_name); | ||||||
|     if (archive_name_size > MZ_UINT16_MAX) |     if (archive_name_size > MZ_UINT16_MAX) | ||||||
| @@ -2772,7 +2791,10 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
|     { |     { | ||||||
|         // Bail early if the archive would obviously become too large |         // Bail early if the archive would obviously become too large | ||||||
| 		if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF) | 		if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF) | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | 		{ | ||||||
|  | 			pState->m_zip64 = MZ_TRUE; | ||||||
|  | 			//return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|  | 		} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) |     if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) | ||||||
| @@ -2795,7 +2817,7 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); |             return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) |     if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes)) | ||||||
|     { |     { | ||||||
|         pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); |         pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); | ||||||
|         return MZ_FALSE; |         return MZ_FALSE; | ||||||
| @@ -2806,10 +2828,32 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
|     { |     { | ||||||
|         MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); |         MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); | ||||||
|     } |     } | ||||||
|     cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); |     cur_archive_file_ofs += num_alignment_padding_bytes; | ||||||
|  |  | ||||||
|     MZ_CLEAR_OBJ(local_dir_header); |     MZ_CLEAR_OBJ(local_dir_header); | ||||||
|  |  | ||||||
|  | 	if (uncomp_size && level) | ||||||
|  | 	{ | ||||||
|  | 		method = MZ_DEFLATED; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	if (pState->m_zip64) | ||||||
|  | 	{ | ||||||
|  | 		if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) | ||||||
|  | 		{ | ||||||
|  | 			pExtra_data = extra_data; | ||||||
|  | 			extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,  | ||||||
|  | 				(uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size + user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); | ||||||
|  |  | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += sizeof(local_dir_header); | ||||||
|  |  | ||||||
| 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) | ||||||
| 		{ | 		{ | ||||||
| 			pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); | 			pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); | ||||||
| @@ -2817,11 +2861,40 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
| 		} | 		} | ||||||
| 		cur_archive_file_ofs += archive_name_size; | 		cur_archive_file_ofs += archive_name_size; | ||||||
|  |  | ||||||
|     extra_data_file_ofs = cur_archive_file_ofs; | 		if (pExtra_data != NULL) | ||||||
|     if (pState->m_zip64) |  | ||||||
| 		{ | 		{ | ||||||
|         // Reserve space for an extra data field for zip64 | 			if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size) | ||||||
|         cur_archive_file_ofs += MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE; | 				return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 			cur_archive_file_ofs += extra_size; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|  | 		if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); | ||||||
|  |  | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += sizeof(local_dir_header); | ||||||
|  |  | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) | ||||||
|  | 		{ | ||||||
|  | 			pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  | 		} | ||||||
|  | 		cur_archive_file_ofs += archive_name_size; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (user_extra_data_len > 0) | ||||||
|  | 	{ | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += user_extra_data_len; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) |     if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) | ||||||
| @@ -2866,47 +2939,50 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
|  |  | ||||||
|         comp_size = state.m_comp_size; |         comp_size = state.m_comp_size; | ||||||
|         cur_archive_file_ofs = state.m_cur_archive_file_ofs; |         cur_archive_file_ofs = state.m_cur_archive_file_ofs; | ||||||
|  |  | ||||||
|         method = MZ_DEFLATED; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); |     pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); | ||||||
|     pComp = NULL; |     pComp = NULL; | ||||||
|  |  | ||||||
|     if (pState->m_zip64) | 	if (uncomp_size) | ||||||
| 	{ | 	{ | ||||||
|         // Write the local header+zip64 extra data | 		MZ_ASSERT(bit_flags & (1 << 3)); | ||||||
|         mz_uint32 local_dir_entry_extra_data_size = mz_zip_writer_create_zip64_extra_data(extra_data, &uncomp_size, &comp_size, NULL); |  | ||||||
|         MZ_ASSERT(local_dir_entry_extra_data_size <= sizeof(extra_data)); |  | ||||||
|  |  | ||||||
|         if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, local_dir_entry_extra_data_size, MZ_UINT32_MAX, MZ_UINT32_MAX, uncomp_crc32, method, 0, dos_time, dos_date)) | 		mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); | 		mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; | ||||||
|  |  | ||||||
|         if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) | 		MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | 		MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); | ||||||
|  | 		if (pExtra_data==NULL) | ||||||
|         if (pZip->m_pWrite(pZip->m_pIO_opaque, extra_data_file_ofs, extra_data, local_dir_entry_extra_data_size) != local_dir_entry_extra_data_size) |  | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); |  | ||||||
|  |  | ||||||
|         // See if we need to create zip64 extra data |  | ||||||
|         if (MZ_MAX(local_dir_header_ofs, MZ_MAX(comp_size, uncomp_size)) >= MZ_UINT32_MAX) |  | ||||||
|         { |  | ||||||
|             pExtra_data = extra_data; |  | ||||||
|             extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, (comp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
| 		{ | 		{ | ||||||
| 			if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) | 			if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) | ||||||
| 				return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | 				return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|         if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) |  | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); |  | ||||||
|  |  | ||||||
|         if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) | 			MZ_WRITE_LE32(local_dir_footer + 8, comp_size); | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | 			MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			MZ_WRITE_LE64(local_dir_footer + 8, comp_size); | ||||||
|  | 			MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); | ||||||
|  | 			local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|     if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size) | ||||||
|  | 			return MZ_FALSE; | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += local_dir_footer_size; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (pExtra_data != NULL) | ||||||
|  | 	{ | ||||||
|  | 		extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, | ||||||
|  | 			(uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |     if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, | ||||||
|  | 		comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes, | ||||||
|  | 		user_extra_data_central, user_extra_data_central_len)) | ||||||
|         return MZ_FALSE; |         return MZ_FALSE; | ||||||
|  |  | ||||||
|     pZip->m_total_files++; |     pZip->m_total_files++; | ||||||
| @@ -2916,11 +2992,13 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name | |||||||
| } | } | ||||||
|  |  | ||||||
| #ifndef MINIZ_NO_STDIO | #ifndef MINIZ_NO_STDIO | ||||||
| mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) | mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, | ||||||
|  | 	const char* user_extra_data, mz_uint user_extra_data_len, const char* user_extra_data_central, mz_uint user_extra_data_central_len) | ||||||
| { | { | ||||||
|  | 	mz_uint16 gen_flags = 1 << 3 | 1 << 11; | ||||||
|     mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; |     mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; | ||||||
|     mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; |     mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; | ||||||
|     mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, extra_data_file_ofs = 0, uncomp_size = size_to_add, comp_size = 0; |     mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = size_to_add, comp_size = 0; | ||||||
|     size_t archive_name_size; |     size_t archive_name_size; | ||||||
|     mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; |     mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; | ||||||
|     mz_uint8 *pExtra_data = NULL; |     mz_uint8 *pExtra_data = NULL; | ||||||
| @@ -2941,7 +3019,8 @@ mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, | |||||||
|     if ((!pState->m_zip64) && (uncomp_size > MZ_UINT32_MAX)) |     if ((!pState->m_zip64) && (uncomp_size > MZ_UINT32_MAX)) | ||||||
|     { |     { | ||||||
|         // Source file is too large for non-zip64 |         // Source file is too large for non-zip64 | ||||||
|         return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); |         //return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|  | 		pState->m_zip64 = MZ_TRUE; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // We could support this, but why? |     // We could support this, but why? | ||||||
| @@ -2959,7 +3038,10 @@ mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, | |||||||
|     else |     else | ||||||
|     { |     { | ||||||
| 		if (pZip->m_total_files == MZ_UINT16_MAX) | 		if (pZip->m_total_files == MZ_UINT16_MAX) | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); | 		{ | ||||||
|  | 			pState->m_zip64 = MZ_TRUE; | ||||||
|  | 			//return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); | ||||||
|  | 		} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     archive_name_size = strlen(pArchive_name); |     archive_name_size = strlen(pArchive_name); | ||||||
| @@ -2975,8 +3057,11 @@ mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, | |||||||
|     if (!pState->m_zip64) |     if (!pState->m_zip64) | ||||||
|     { |     { | ||||||
|         // Bail early if the archive would obviously become too large |         // Bail early if the archive would obviously become too large | ||||||
|         if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF) | 		if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE+1024) > 0xFFFFFFFF) | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | 		{ | ||||||
|  | 			pState->m_zip64 = MZ_TRUE; | ||||||
|  | 			//return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|  | 		} | ||||||
|     } |     } | ||||||
|  |  | ||||||
| #ifndef MINIZ_NO_TIME | #ifndef MINIZ_NO_TIME | ||||||
| @@ -2989,30 +3074,80 @@ mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, | |||||||
|     if (uncomp_size <= 3) |     if (uncomp_size <= 3) | ||||||
|         level = 0; |         level = 0; | ||||||
|  |  | ||||||
|     if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) |     if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes)) | ||||||
|     { |     { | ||||||
|         return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); |         return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     local_dir_header_ofs += num_alignment_padding_bytes; | 	cur_archive_file_ofs += num_alignment_padding_bytes; | ||||||
|  | 	local_dir_header_ofs = cur_archive_file_ofs; | ||||||
|  |  | ||||||
|     if (pZip->m_file_offset_alignment) |     if (pZip->m_file_offset_alignment) | ||||||
|     { |     { | ||||||
|         MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); |         MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | 	if (uncomp_size && level) | ||||||
|  | 	{ | ||||||
|  | 		method = MZ_DEFLATED; | ||||||
| 	} | 	} | ||||||
|     cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); |  | ||||||
|  |  | ||||||
| 	MZ_CLEAR_OBJ(local_dir_header); | 	MZ_CLEAR_OBJ(local_dir_header); | ||||||
|  | 	if (pState->m_zip64) | ||||||
|  | 	{ | ||||||
|  | 		if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) | ||||||
|  | 		{ | ||||||
|  | 			pExtra_data = extra_data; | ||||||
|  | 			extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, | ||||||
|  | 				(uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size+ user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); | ||||||
|  |  | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += sizeof(local_dir_header); | ||||||
|  |  | ||||||
| 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) | ||||||
| 		{ | 		{ | ||||||
| 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cur_archive_file_ofs += archive_name_size; | 		cur_archive_file_ofs += archive_name_size; | ||||||
|  |  | ||||||
|     extra_data_file_ofs = cur_archive_file_ofs; | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size) | ||||||
|     if (pState->m_zip64) | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += extra_size;		 | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
| 	{ | 	{ | ||||||
|         // Reserve space for an extra data field for zip64 | 		if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) | ||||||
|         cur_archive_file_ofs += MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE; | 			return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|  | 		if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); | ||||||
|  |  | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += sizeof(local_dir_header); | ||||||
|  |  | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) | ||||||
|  | 		{ | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += archive_name_size; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (user_extra_data_len > 0) | ||||||
|  | 	{ | ||||||
|  | 		if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) | ||||||
|  | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); | ||||||
|  |  | ||||||
|  | 		cur_archive_file_ofs += user_extra_data_len; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     if (uncomp_size) |     if (uncomp_size) | ||||||
| @@ -3099,47 +3234,45 @@ mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, | |||||||
|  |  | ||||||
|             comp_size = state.m_comp_size; |             comp_size = state.m_comp_size; | ||||||
|             cur_archive_file_ofs = state.m_cur_archive_file_ofs; |             cur_archive_file_ofs = state.m_cur_archive_file_ofs; | ||||||
|  |  | ||||||
|             method = MZ_DEFLATED; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); |         pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (pState->m_zip64) | 	mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; | ||||||
|  | 	mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; | ||||||
|  |  | ||||||
|  | 	MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); | ||||||
|  | 	MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); | ||||||
|  | 	if (pExtra_data==NULL) | ||||||
| 	{ | 	{ | ||||||
|         // Write the local header+zip64 extra data | 		if (comp_size > MZ_UINT32_MAX) | ||||||
|         mz_uint32 local_dir_entry_extra_data_size = mz_zip_writer_create_zip64_extra_data(extra_data, &uncomp_size, &comp_size, NULL); | 			return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | ||||||
|         MZ_ASSERT(local_dir_entry_extra_data_size <= sizeof(extra_data)); |  | ||||||
|  |  | ||||||
|         if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, local_dir_entry_extra_data_size, MZ_UINT32_MAX, MZ_UINT32_MAX, uncomp_crc32, method, 0, dos_time, dos_date)) | 		MZ_WRITE_LE32(local_dir_footer + 8, comp_size); | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); | 		MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); | ||||||
|  |  | ||||||
|         if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) |  | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); |  | ||||||
|  |  | ||||||
|         if (pZip->m_pWrite(pZip->m_pIO_opaque, extra_data_file_ofs, extra_data, local_dir_entry_extra_data_size) != local_dir_entry_extra_data_size) |  | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); |  | ||||||
|  |  | ||||||
|         // See if we need to create zip64 extra data |  | ||||||
|         if (MZ_MAX(local_dir_header_ofs, MZ_MAX(comp_size, uncomp_size)) >= MZ_UINT32_MAX) |  | ||||||
|         { |  | ||||||
|             pExtra_data = extra_data; |  | ||||||
|             extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, (comp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); |  | ||||||
|         } |  | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
|         if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) | 		MZ_WRITE_LE64(local_dir_footer + 8, comp_size); | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); | 		MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); | ||||||
|         if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) | 		local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); |  | ||||||
|  |  | ||||||
|         if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) |  | ||||||
|             return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) | 	if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size) | ||||||
|  | 		return MZ_FALSE; | ||||||
|  |  | ||||||
|  | 	cur_archive_file_ofs += local_dir_footer_size; | ||||||
|  |  | ||||||
|  | 	if (pExtra_data != NULL) | ||||||
|  | 	{ | ||||||
|  | 		extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, | ||||||
|  | 			(uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |     if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, comment_size,  | ||||||
|  | 		uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes, | ||||||
|  | 		user_extra_data_central, user_extra_data_central_len)) | ||||||
|         return MZ_FALSE; |         return MZ_FALSE; | ||||||
|  |  | ||||||
|     pZip->m_total_files++; |     pZip->m_total_files++; | ||||||
| @@ -3148,20 +3281,22 @@ mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, | |||||||
|     return MZ_TRUE; |     return MZ_TRUE; | ||||||
| } | } | ||||||
|  |  | ||||||
| mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) | mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, MZ_TIME_T *pFile_time) | ||||||
| { | { | ||||||
|     MZ_FILE *pSrc_file = NULL; |     MZ_FILE *pSrc_file = NULL; | ||||||
|     mz_uint64 uncomp_size = 0; |     mz_uint64 uncomp_size = 0; | ||||||
|     MZ_TIME_T file_modified_time; |     MZ_TIME_T file_modified_time; | ||||||
|     MZ_TIME_T *pFile_modified_time = NULL; |  | ||||||
|  |  | ||||||
|     memset(&file_modified_time, 0, sizeof(file_modified_time)); |     memset(&file_modified_time, 0, sizeof(file_modified_time)); | ||||||
|  |  | ||||||
| #if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) | #if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) | ||||||
|     pFile_modified_time = &file_modified_time; | 	if (pFile_time == NULL) | ||||||
|  | 	{ | ||||||
|  | 		pFile_time = &file_modified_time; | ||||||
|  |  | ||||||
| 		if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time)) | 		if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time)) | ||||||
| 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED); | 			return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED); | ||||||
|  | 	} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); |     pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); | ||||||
| @@ -3172,7 +3307,7 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, | |||||||
|     uncomp_size = MZ_FTELL64(pSrc_file); |     uncomp_size = MZ_FTELL64(pSrc_file); | ||||||
|     MZ_FSEEK64(pSrc_file, 0, SEEK_SET); |     MZ_FSEEK64(pSrc_file, 0, SEEK_SET); | ||||||
|  |  | ||||||
|     mz_bool status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_modified_time, pComment, comment_size, level_and_flags); |     mz_bool status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, level_and_flags, NULL, 0, NULL, 0); | ||||||
|  |  | ||||||
|     MZ_FCLOSE(pSrc_file); |     MZ_FCLOSE(pSrc_file); | ||||||
|  |  | ||||||
| @@ -3799,7 +3934,7 @@ mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0); |     status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0, 0, 0, NULL, 0, NULL, 0); | ||||||
|     actual_err = zip_archive.m_last_error; |     actual_err = zip_archive.m_last_error; | ||||||
|  |  | ||||||
|     // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) |     // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								miniz_zip.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								miniz_zip.h
									
									
									
									
									
								
							| @@ -331,19 +331,23 @@ mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilena | |||||||
| // Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. | // Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. | ||||||
| // To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. | // To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. | ||||||
| // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. | // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. | ||||||
| mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags); | mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags, time_t* last_modified); | ||||||
|  |  | ||||||
| // Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. | // Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. | ||||||
| // uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. | // uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. | ||||||
| mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32); | mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,  | ||||||
|  | 	mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, mz_uint16 bit_flags, time_t* last_modified, const char* user_extra_data_local, mz_uint user_extra_data_local_len, | ||||||
|  | 	const char* user_extra_data_central, mz_uint user_extra_data_central_len); | ||||||
|  |  | ||||||
| #ifndef MINIZ_NO_STDIO | #ifndef MINIZ_NO_STDIO | ||||||
| // Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. | // Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. | ||||||
| // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. | // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. | ||||||
| mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); | mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, MZ_TIME_T *pFile_time); | ||||||
|  |  | ||||||
| // Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. | // Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. | ||||||
| mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); | mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, | ||||||
|  | 	const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char* user_extra_data_local, mz_uint user_extra_data_local_len, | ||||||
|  | 	const char* user_extra_data_central, mz_uint user_extra_data_central_len); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Adds a file to an archive by fully cloning the data from another archive. | // Adds a file to an archive by fully cloning the data from another archive. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user