gmio_core: fix zip64 corrupted output
This commit is contained in:
parent
8999472912
commit
abb7bafc4a
@ -38,15 +38,8 @@
|
||||
* Constants
|
||||
* ---------- */
|
||||
|
||||
enum {
|
||||
GMIO_ZIP_SIZE_LOCAL_FILE_HEADER = 4 + 5*2 + 3*4 + 2*2,
|
||||
GMIO_ZIP_SIZE_CENTRAL_DIRECTORY_HEADER = 4 + 6*2 + 3*4 + 5*2 +2*4,
|
||||
GMIO_ZIP_SIZE_DATA_DESCRIPTOR = 4 + 4 + 4 + 4,
|
||||
GMIO_ZIP64_SIZE_DATA_DESCRIPTOR = 4 + 4 + 2*8,
|
||||
GMIO_ZIP64_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD = 4 + 8 + 2*2 + 2*4 + 4*8,
|
||||
GMIO_ZIP64_SIZE_END_OF_CENTRAL_DIRECTORY_LOCATOR = 4 + 4 + 8 + 4,
|
||||
GMIO_ZIP_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD = 4 + 4*2 + 2*4 + 2
|
||||
};
|
||||
static const uint16_t zip64_extrablock_tag = 0x0001;
|
||||
static const uint16_t zip64_extrablock_size = 3*8 + 4;
|
||||
|
||||
/* ----------
|
||||
* Internal functions
|
||||
@ -238,7 +231,7 @@ size_t gmio_zip_read_central_directory_header(
|
||||
gmio_adv_decode_uint16_le(&buff); /* disk_nb_start */
|
||||
info->internal_file_attrs = gmio_adv_decode_uint16_le(&buff);
|
||||
info->external_file_attrs = gmio_adv_decode_uint32_le(&buff);
|
||||
info->relative_offset_local_header = gmio_adv_decode_uint32_le(&buff);
|
||||
info->local_header_offset = gmio_adv_decode_uint32_le(&buff);
|
||||
|
||||
info->filename = NULL;
|
||||
info->extrafield = NULL;
|
||||
@ -247,6 +240,36 @@ size_t gmio_zip_read_central_directory_header(
|
||||
return gmio_zip_io_returnerr(read_len, GMIO_ERROR_OK, ptr_error);
|
||||
}
|
||||
|
||||
size_t gmio_zip64_read_extrafield(
|
||||
struct gmio_stream *stream,
|
||||
struct gmio_zip64_extrafield *info,
|
||||
int *ptr_error)
|
||||
{
|
||||
#ifdef GMIO_HAVE_INT64_TYPE
|
||||
uint8_t bytes[GMIO_ZIP64_SIZE_EXTRAFIELD];
|
||||
const uint8_t* buff = bytes;
|
||||
size_t read_len = 0;
|
||||
if (!gmio_zip_readcheckbytes(stream, bytes, sizeof(bytes), &read_len, ptr_error))
|
||||
return read_len;
|
||||
if (gmio_adv_decode_uint16_le(&buff) != zip64_extrablock_tag) {
|
||||
return gmio_zip_io_returnerr(
|
||||
read_len, GMIO_ZIP_UTILS_ERROR_BAD_EXTRAFIELD_TAG, ptr_error);
|
||||
}
|
||||
if (gmio_adv_decode_uint16_le(&buff) != zip64_extrablock_size) {
|
||||
return gmio_zip_io_returnerr(
|
||||
read_len, GMIO_ZIP_UTILS_ERROR_BAD_EXTRAFIELD_SIZE, ptr_error);
|
||||
}
|
||||
info->uncompressed_size = gmio_adv_decode_uint64_le(&buff);
|
||||
info->compressed_size = gmio_adv_decode_uint64_le(&buff);
|
||||
info->local_header_offset = gmio_adv_decode_uint64_le(&buff);
|
||||
gmio_adv_decode_uint32_le(&buff); /* Disk start number */
|
||||
return gmio_zip_io_returnerr(read_len, GMIO_ERROR_OK, ptr_error);
|
||||
#else
|
||||
return gmio_zip_io_returnerr(
|
||||
0, GMIO_ERROR_ZIP_INT64_TYPE_REQUIRED, ptr_error);
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t gmio_zip64_read_end_of_central_directory_record(
|
||||
struct gmio_stream *stream,
|
||||
struct gmio_zip64_end_of_central_directory_record *info,
|
||||
@ -269,7 +292,7 @@ size_t gmio_zip64_read_end_of_central_directory_record(
|
||||
gmio_adv_decode_uint64_le(&buff); /* total_entry_count_in_central_dir_on_disk */
|
||||
info->entry_count = gmio_adv_decode_uint64_le(&buff);
|
||||
info->central_dir_size = gmio_adv_decode_uint64_le(&buff);
|
||||
info->start_offset = gmio_adv_decode_uint64_le(&buff);
|
||||
info->central_dir_offset = gmio_adv_decode_uint64_le(&buff);
|
||||
return gmio_zip_io_returnerr(read_len, GMIO_ERROR_OK, ptr_error);
|
||||
#else
|
||||
return gmio_zip_io_returnerr(
|
||||
@ -293,7 +316,7 @@ size_t gmio_zip64_read_end_of_central_directory_locator(
|
||||
/* Number of the disk with the start of the zip64 end of central directory */
|
||||
gmio_adv_decode_uint32_le(&buff);
|
||||
/* Relative offset of the zip64 end of central directory record */
|
||||
info->relative_offset = gmio_adv_decode_uint64_le(&buff);
|
||||
info->zip64_end_of_central_dir_offset = gmio_adv_decode_uint64_le(&buff);
|
||||
/* Total number of disks */
|
||||
gmio_adv_decode_uint32_le(&buff);
|
||||
return gmio_zip_io_returnerr(read_len, GMIO_ERROR_OK, ptr_error);
|
||||
@ -320,7 +343,7 @@ size_t gmio_zip_read_end_of_central_directory_record(
|
||||
gmio_adv_decode_uint16_le(&buff); /* total_entry_count_in_central_dir_on_disk */
|
||||
info->entry_count = gmio_adv_decode_uint16_le(&buff);
|
||||
info->central_dir_size = gmio_adv_decode_uint32_le(&buff);
|
||||
info->start_offset = gmio_adv_decode_uint32_le(&buff);
|
||||
info->central_dir_offset = gmio_adv_decode_uint32_le(&buff);
|
||||
info->filecomment_len = gmio_adv_decode_uint16_le(&buff);
|
||||
info->filecomment = NULL;
|
||||
return gmio_zip_io_returnerr(read_len, GMIO_ERROR_OK, ptr_error);
|
||||
@ -437,9 +460,9 @@ size_t gmio_zip_write_central_directory_header(
|
||||
gmio_adv_encode_uint16_le(0, &buff); /* Disk number start */
|
||||
gmio_adv_encode_uint16_le(info->internal_file_attrs, &buff);
|
||||
gmio_adv_encode_uint32_le(info->external_file_attrs, &buff);
|
||||
const uint32_t relative_offset_local_header =
|
||||
info->use_zip64 ? UINT32_MAX : info->relative_offset_local_header;
|
||||
gmio_adv_encode_uint32_le(relative_offset_local_header, &buff);
|
||||
const uint32_t local_header_offset =
|
||||
info->use_zip64 ? UINT32_MAX : info->local_header_offset;
|
||||
gmio_adv_encode_uint32_le(local_header_offset, &buff);
|
||||
|
||||
/* Write to stream */
|
||||
const size_t expected_written_len =
|
||||
@ -469,13 +492,11 @@ size_t gmio_zip64_write_extrafield(
|
||||
0, GMIO_ERROR_INVALID_MEMBLOCK_SIZE, ptr_error);
|
||||
}
|
||||
#ifdef GMIO_HAVE_INT64_TYPE
|
||||
static const uint16_t extrablock_tag = 0x0001;
|
||||
static const uint16_t extrablock_size = 3*8 + 4;
|
||||
gmio_adv_encode_uint16_le(extrablock_tag, &buff);
|
||||
gmio_adv_encode_uint16_le(extrablock_size, &buff);
|
||||
gmio_adv_encode_uint16_le(zip64_extrablock_tag, &buff);
|
||||
gmio_adv_encode_uint16_le(zip64_extrablock_size, &buff);
|
||||
gmio_adv_encode_uint64_le(info->uncompressed_size, &buff);
|
||||
gmio_adv_encode_uint64_le(info->compressed_size, &buff);
|
||||
gmio_adv_encode_uint64_le(info->relative_offset_local_header, &buff);
|
||||
gmio_adv_encode_uint64_le(info->local_header_offset, &buff);
|
||||
gmio_adv_encode_uint32_le(0, &buff); /* Disk start number */
|
||||
return gmio_zip_io_returnerr(
|
||||
GMIO_ZIP64_SIZE_EXTRAFIELD, GMIO_ERROR_OK, ptr_error);
|
||||
@ -505,7 +526,7 @@ size_t gmio_zip64_write_end_of_central_directory_record(
|
||||
gmio_adv_encode_uint64_le(disk_entry_count, &buff);
|
||||
gmio_adv_encode_uint64_le(info->entry_count, &buff);
|
||||
gmio_adv_encode_uint64_le(info->central_dir_size, &buff);
|
||||
gmio_adv_encode_uint64_le(info->start_offset, &buff);
|
||||
gmio_adv_encode_uint64_le(info->central_dir_offset, &buff);
|
||||
/* Note: don't write any PKWARE reserved "zip64 extensible data sector"
|
||||
/* Write to stream */
|
||||
const size_t expected_written_len = sizeof(bytes);
|
||||
@ -531,7 +552,7 @@ size_t gmio_zip64_write_end_of_central_directory_locator(
|
||||
const uint32_t disk_count = 1;
|
||||
gmio_adv_encode_uint32_le(0x07064b50, &buff);
|
||||
gmio_adv_encode_uint32_le(disk_nb, &buff);
|
||||
gmio_adv_encode_uint64_le(info->relative_offset, &buff);
|
||||
gmio_adv_encode_uint64_le(info->zip64_end_of_central_dir_offset, &buff);
|
||||
gmio_adv_encode_uint32_le(disk_count, &buff);
|
||||
/* Write to stream */
|
||||
const size_t expected_written_len = sizeof(bytes);
|
||||
@ -573,9 +594,9 @@ size_t gmio_zip_write_end_of_central_directory_record(
|
||||
info->use_zip64 ? UINT32_MAX : info->central_dir_size;
|
||||
gmio_adv_encode_uint32_le(central_dir_size, &buff);
|
||||
|
||||
const uint32_t start_offset =
|
||||
info->use_zip64 ? UINT32_MAX : info->start_offset;
|
||||
gmio_adv_encode_uint32_le(start_offset, &buff);
|
||||
const uint32_t central_dir_offset =
|
||||
info->use_zip64 ? UINT32_MAX : info->central_dir_offset;
|
||||
gmio_adv_encode_uint32_le(central_dir_offset, &buff);
|
||||
|
||||
gmio_adv_encode_uint16_le(info->filecomment_len, &buff);
|
||||
|
||||
@ -606,17 +627,19 @@ bool gmio_zip_write_single_file(
|
||||
file_entry->feature_version
|
||||
>= GMIO_ZIP_FEATURE_VERSION_FILE_ZIP64_FORMAT_EXTENSIONS;
|
||||
uint8_t extrafield[GMIO_ZIP64_SIZE_EXTRAFIELD];
|
||||
size_t zip_write_pos = 0;
|
||||
uintmax_t zip_write_pos = 0;
|
||||
|
||||
/* Write local file header */
|
||||
struct gmio_zip_local_file_header lfh = {0};
|
||||
lfh.version_needed_to_extract = file_entry->feature_version;
|
||||
lfh.general_purpose_flags = GMIO_ZIP_GENERAL_PURPOSE_FLAG_USE_DATA_DESCRIPTOR;
|
||||
lfh.compress_method = file_entry->compress_method;
|
||||
lfh.filename = file_entry->filename;
|
||||
lfh.filename_len = file_entry->filename_len;
|
||||
if (use_zip64_format_extensions) {
|
||||
lfh.compressed_size = UINT32_MAX;
|
||||
lfh.uncompressed_size = UINT32_MAX;
|
||||
const struct gmio_zip64_extrafield zip64extra = {0};
|
||||
zip_write_pos +=
|
||||
gmio_zip64_write_extrafield(
|
||||
extrafield, sizeof(extrafield), &zip64extra, ptr_error);
|
||||
if (gmio_error(*ptr_error))
|
||||
@ -653,7 +676,7 @@ bool gmio_zip_write_single_file(
|
||||
return false;
|
||||
|
||||
/* Write central directory header */
|
||||
const uintmax_t pos_start_central_dir = zip_write_pos;
|
||||
const uintmax_t pos_central_dir = zip_write_pos;
|
||||
struct gmio_zip_central_directory_header cdh = {0};
|
||||
cdh.use_zip64 = needs_zip64;
|
||||
cdh.version_needed_to_extract = version_needed;
|
||||
@ -668,8 +691,6 @@ bool gmio_zip_write_single_file(
|
||||
struct gmio_zip64_extrafield zip64extra = {0};
|
||||
zip64extra.compressed_size = dd.compressed_size;
|
||||
zip64extra.uncompressed_size = dd.uncompressed_size;
|
||||
zip64extra.relative_offset_local_header = 0;
|
||||
zip_write_pos +=
|
||||
gmio_zip64_write_extrafield(
|
||||
extrafield, sizeof(extrafield), &zip64extra, ptr_error);
|
||||
if (gmio_error(*ptr_error))
|
||||
@ -677,21 +698,21 @@ bool gmio_zip_write_single_file(
|
||||
cdh.extrafield = extrafield;
|
||||
cdh.extrafield_len = sizeof(extrafield);
|
||||
}
|
||||
const uintmax_t central_dir_startpos = zip_write_pos;
|
||||
const uintmax_t central_dir_pos = zip_write_pos;
|
||||
const size_t central_dir_size =
|
||||
gmio_zip_write_central_directory_header(stream, &cdh, ptr_error);
|
||||
zip_write_pos += central_dir_size;
|
||||
if (gmio_error(*ptr_error))
|
||||
return false;
|
||||
const uintmax_t pos_end_central_dir = zip_write_pos;
|
||||
|
||||
if (needs_zip64) {
|
||||
/* Write Zip64 end of central directory record */
|
||||
const uintmax_t pos_zip64_end_of_central_dir = zip_write_pos;
|
||||
struct gmio_zip64_end_of_central_directory_record eocdr64 = {0};
|
||||
eocdr64.version_needed_to_extract = version_needed;
|
||||
eocdr64.entry_count = 1;
|
||||
eocdr64.central_dir_size = pos_end_central_dir - pos_start_central_dir;
|
||||
eocdr64.start_offset = pos_start_central_dir;
|
||||
eocdr64.central_dir_size = central_dir_size;
|
||||
eocdr64.central_dir_offset = pos_central_dir;
|
||||
zip_write_pos +=
|
||||
gmio_zip64_write_end_of_central_directory_record(
|
||||
stream, &eocdr64, ptr_error);
|
||||
@ -700,7 +721,7 @@ bool gmio_zip_write_single_file(
|
||||
|
||||
/* Write Zip64 end of central directory locator */
|
||||
struct gmio_zip64_end_of_central_directory_locator eocdl64 = {0};
|
||||
eocdl64.relative_offset = pos_end_central_dir;
|
||||
eocdl64.zip64_end_of_central_dir_offset = pos_zip64_end_of_central_dir;
|
||||
zip_write_pos +=
|
||||
gmio_zip64_write_end_of_central_directory_locator(
|
||||
stream, &eocdl64, ptr_error);
|
||||
@ -713,7 +734,7 @@ bool gmio_zip_write_single_file(
|
||||
eocdr.use_zip64 = needs_zip64;
|
||||
eocdr.entry_count = 1;
|
||||
eocdr.central_dir_size = (uint32_t)central_dir_size;
|
||||
eocdr.start_offset = (uint32_t)central_dir_startpos;
|
||||
eocdr.central_dir_offset = (uint32_t)central_dir_pos;
|
||||
zip_write_pos +=
|
||||
gmio_zip_write_end_of_central_directory_record(
|
||||
stream, &eocdr, ptr_error);
|
||||
|
@ -192,26 +192,35 @@ struct gmio_zip_central_directory_header {
|
||||
uint16_t filecomment_len;
|
||||
uint16_t internal_file_attrs;
|
||||
uint32_t external_file_attrs;
|
||||
uint32_t relative_offset_local_header;
|
||||
uint32_t local_header_offset;
|
||||
const char* filename;
|
||||
const uint8_t* extrafield;
|
||||
const char* filecomment;
|
||||
};
|
||||
|
||||
enum { GMIO_ZIP64_SIZE_EXTRAFIELD = 2*2 + 3*8 + 4 };
|
||||
enum {
|
||||
GMIO_ZIP_SIZE_LOCAL_FILE_HEADER = 4 + 5*2 + 3*4 + 2*2,
|
||||
GMIO_ZIP_SIZE_CENTRAL_DIRECTORY_HEADER = 4 + 6*2 + 3*4 + 5*2 +2*4,
|
||||
GMIO_ZIP_SIZE_DATA_DESCRIPTOR = 4 + 4 + 4 + 4,
|
||||
GMIO_ZIP64_SIZE_EXTRAFIELD = 2*2 + 3*8 + 4,
|
||||
GMIO_ZIP64_SIZE_DATA_DESCRIPTOR = 4 + 4 + 2*8,
|
||||
GMIO_ZIP64_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD = 4 + 8 + 2*2 + 2*4 + 4*8,
|
||||
GMIO_ZIP64_SIZE_END_OF_CENTRAL_DIRECTORY_LOCATOR = 4 + 4 + 8 + 4,
|
||||
GMIO_ZIP_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD = 4 + 4*2 + 2*4 + 2
|
||||
};
|
||||
|
||||
/*! Zip64 extended info (extra field) */
|
||||
struct gmio_zip64_extrafield {
|
||||
uintmax_t compressed_size;
|
||||
uintmax_t uncompressed_size;
|
||||
uintmax_t relative_offset_local_header;
|
||||
uintmax_t local_header_offset;
|
||||
};
|
||||
|
||||
struct gmio_zip_end_of_central_directory_record {
|
||||
bool use_zip64;
|
||||
uint16_t entry_count;
|
||||
uint32_t central_dir_size;
|
||||
uint32_t start_offset;
|
||||
uint32_t central_dir_offset;
|
||||
uint16_t filecomment_len;
|
||||
const char* filecomment;
|
||||
};
|
||||
@ -221,18 +230,24 @@ struct gmio_zip64_end_of_central_directory_record {
|
||||
enum gmio_zip_feature_version version_needed_to_extract;
|
||||
uintmax_t entry_count; /* should be 64b */
|
||||
uintmax_t central_dir_size; /* should be 64b */
|
||||
uintmax_t start_offset; /* should be 64b */
|
||||
uintmax_t central_dir_offset; /* should be 64b */
|
||||
};
|
||||
|
||||
struct gmio_zip64_end_of_central_directory_locator {
|
||||
uintmax_t relative_offset; /* should be 64b */
|
||||
uintmax_t zip64_end_of_central_dir_offset; /* should be 64b */
|
||||
};
|
||||
|
||||
enum { GMIO_ZIP_UTILS_ERROR_TAG = 0x00100000 };
|
||||
enum gmio_zip_utils_error {
|
||||
GMIO_ZIP_UTILS_ERROR_BAD_MAGIC = GMIO_ZIP_UTILS_ERROR_TAG + 1
|
||||
GMIO_ZIP_UTILS_ERROR_BAD_MAGIC = GMIO_ZIP_UTILS_ERROR_TAG + 1,
|
||||
GMIO_ZIP_UTILS_ERROR_BAD_EXTRAFIELD_TAG,
|
||||
GMIO_ZIP_UTILS_ERROR_BAD_EXTRAFIELD_SIZE
|
||||
};
|
||||
|
||||
/*
|
||||
* ZIP read functions
|
||||
*/
|
||||
|
||||
size_t gmio_zip_read_local_file_header(
|
||||
struct gmio_stream* stream,
|
||||
struct gmio_zip_local_file_header* info,
|
||||
@ -253,6 +268,11 @@ size_t gmio_zip_read_central_directory_header(
|
||||
struct gmio_zip_central_directory_header* info,
|
||||
int* ptr_error);
|
||||
|
||||
size_t gmio_zip64_read_extrafield(
|
||||
struct gmio_stream* stream,
|
||||
struct gmio_zip64_extrafield* info,
|
||||
int* ptr_error);
|
||||
|
||||
size_t gmio_zip64_read_end_of_central_directory_record(
|
||||
struct gmio_stream* stream,
|
||||
struct gmio_zip64_end_of_central_directory_record* info,
|
||||
@ -268,6 +288,10 @@ size_t gmio_zip_read_end_of_central_directory_record(
|
||||
struct gmio_zip_end_of_central_directory_record* info,
|
||||
int* ptr_error);
|
||||
|
||||
/*
|
||||
* ZIP write functions
|
||||
*/
|
||||
|
||||
size_t gmio_zip_write_local_file_header(
|
||||
struct gmio_stream* stream,
|
||||
const struct gmio_zip_local_file_header* info,
|
||||
|
@ -56,6 +56,7 @@ const char* all_tests()
|
||||
UTEST_RUN(test_internal__stringstream);
|
||||
UTEST_RUN(test_internal__string_ascii_utils);
|
||||
UTEST_RUN(test_internal__benchmark_gmio_fast_atof);
|
||||
UTEST_RUN(test_internal__zip_utils);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -256,7 +256,6 @@ static int __tamf__write_amf(
|
||||
return gmio_amf_write(&stream, doc, opts);
|
||||
}
|
||||
|
||||
|
||||
static const char* test_amf_write_doc_1_plaintext()
|
||||
{
|
||||
static const size_t wbuffsize = 8192;
|
||||
@ -282,27 +281,6 @@ static const char* test_amf_write_doc_1_plaintext()
|
||||
static const char zip_entry_filename[] = "test.amf";
|
||||
static const uint16_t zip_entry_filename_len = sizeof(zip_entry_filename) - 1;
|
||||
|
||||
static const char* __tamf__check_zip_local_file_header(
|
||||
const struct gmio_zip_local_file_header* zip_lfh)
|
||||
{
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_lfh->compress_method,
|
||||
GMIO_ZIP_COMPRESS_METHOD_DEFLATE);
|
||||
UTEST_ASSERT(
|
||||
(zip_lfh->general_purpose_flags &
|
||||
GMIO_ZIP_GENERAL_PURPOSE_FLAG_USE_DATA_DESCRIPTOR)
|
||||
!= 0);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_lfh->filename_len,
|
||||
zip_entry_filename_len);
|
||||
UTEST_ASSERT(strncmp(
|
||||
zip_lfh->filename,
|
||||
zip_entry_filename,
|
||||
zip_entry_filename_len)
|
||||
== 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* test_amf_write_doc_1_zip()
|
||||
{
|
||||
static const size_t wbuffsize = 8192;
|
||||
@ -319,10 +297,10 @@ static const char* test_amf_write_doc_1_zip()
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
}
|
||||
|
||||
const size_t source_len = wbuff.pos;
|
||||
const uint32_t crc32_amf_data = gmio_zlib_crc32(wbuff.ptr, source_len);
|
||||
uint8_t* source = calloc(source_len, 1);
|
||||
memcpy(source, wbuff.ptr, source_len);
|
||||
const size_t amf_data_len = wbuff.pos;
|
||||
const uint32_t crc32_amf_data = gmio_zlib_crc32(wbuff.ptr, amf_data_len);
|
||||
uint8_t* amf_data = calloc(amf_data_len, 1);
|
||||
memcpy(amf_data, wbuff.ptr, amf_data_len);
|
||||
|
||||
{ /* Write compressed(ZIP) */
|
||||
wbuff.pos = 0;
|
||||
@ -347,79 +325,45 @@ static const char* test_amf_write_doc_1_zip()
|
||||
wbuff.pos = 0;
|
||||
struct gmio_stream stream = gmio_stream_buffer(&wbuff);
|
||||
int error = GMIO_ERROR_OK;
|
||||
/* -- Read ZIP local file header */
|
||||
/* -- Read ZIP end of central directory record */
|
||||
wbuff.pos =
|
||||
zip_archive_len - GMIO_ZIP_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD;
|
||||
struct gmio_zip_end_of_central_directory_record zip_eocdr = {0};
|
||||
gmio_zip_read_end_of_central_directory_record(&stream, &zip_eocdr, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
/* -- Read ZIP central directory */
|
||||
wbuff.pos = zip_eocdr.central_dir_offset;
|
||||
struct gmio_zip_central_directory_header zip_cdh = {0};
|
||||
gmio_zip_read_central_directory_header(&stream, &zip_cdh, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(amf_data_len, zip_cdh.uncompressed_size);
|
||||
const uint32_t amf_zdata_len = zip_cdh.compressed_size;
|
||||
/* -- Read(skip) ZIP local file header */
|
||||
wbuff.pos = 0;
|
||||
struct gmio_zip_local_file_header zip_lfh = {0};
|
||||
const size_t lfh_read_len =
|
||||
gmio_zip_read_local_file_header(&stream, &zip_lfh, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
zip_lfh.filename = (const char*)wbuff.ptr + wbuff.pos;
|
||||
const char* check_str = __tamf__check_zip_local_file_header(&zip_lfh);
|
||||
if (check_str != NULL)
|
||||
return check_str;
|
||||
/* -- Read ZIP end of central directory record */
|
||||
static const size_t end_of_central_dir_record_len = 22;
|
||||
wbuff.pos = zip_archive_len - end_of_central_dir_record_len;;
|
||||
struct gmio_zip_end_of_central_directory_record zip_eocdr = {0};
|
||||
gmio_zip_read_end_of_central_directory_record(
|
||||
&stream, &zip_eocdr, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(zip_eocdr.entry_count, 1);
|
||||
/* -- Read ZIP central directory */
|
||||
wbuff.pos = zip_eocdr.start_offset;
|
||||
struct gmio_zip_central_directory_header zip_cdh = {0};
|
||||
gmio_zip_read_central_directory_header(&stream, &zip_cdh, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_cdh.compress_method,
|
||||
GMIO_ZIP_COMPRESS_METHOD_DEFLATE);
|
||||
UTEST_ASSERT(
|
||||
(zip_cdh.general_purpose_flags &
|
||||
GMIO_ZIP_GENERAL_PURPOSE_FLAG_USE_DATA_DESCRIPTOR)
|
||||
!= 0);
|
||||
UTEST_COMPARE_UINT(crc32_amf_data, zip_cdh.crc32);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_cdh.filename_len, zip_entry_filename_len);
|
||||
UTEST_ASSERT(strncmp(
|
||||
(const char*)wbuff.ptr + wbuff.pos,
|
||||
zip_entry_filename,
|
||||
zip_entry_filename_len)
|
||||
== 0);
|
||||
/* -- Read compressed AMF data */
|
||||
const size_t pos_start_amf_data =
|
||||
lfh_read_len + zip_lfh.filename_len + zip_lfh.extrafield_len;
|
||||
wbuff.pos = pos_start_amf_data;
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
/* -- Read and check compressed AMF data */
|
||||
wbuff.pos = lfh_read_len + zip_lfh.filename_len + zip_lfh.extrafield_len;
|
||||
{
|
||||
uint8_t* dest = calloc(zip_cdh.uncompressed_size, 1);
|
||||
size_t dest_len = zip_cdh.uncompressed_size;
|
||||
const int error =
|
||||
gmio_zlib_uncompress_buffer(
|
||||
dest,
|
||||
&dest_len,
|
||||
(const uint8_t*)wbuff.ptr + wbuff.pos,
|
||||
zip_cdh.compressed_size);
|
||||
uint8_t* dest = calloc(amf_data_len, 1);
|
||||
size_t dest_len = amf_data_len;
|
||||
const uint8_t* amf_zdata = (const uint8_t*)wbuff.ptr + wbuff.pos;
|
||||
const int error = gmio_zlib_uncompress_buffer(
|
||||
dest, &dest_len, amf_zdata, amf_zdata_len);
|
||||
printf("\n-- Info: z_len=%i src_len=%i\n",
|
||||
zip_cdh.compressed_size, source_len);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(source_len, dest_len);
|
||||
UTEST_COMPARE_UINT(dest_len, zip_cdh.uncompressed_size);
|
||||
UTEST_COMPARE_INT(memcmp(dest, source, source_len), 0);
|
||||
amf_zdata_len, amf_data_len);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(dest_len, amf_data_len);
|
||||
UTEST_COMPARE_INT(memcmp(dest, amf_data, amf_data_len), 0);
|
||||
const uint32_t crc32_uncomp = gmio_zlib_crc32(dest, dest_len);
|
||||
UTEST_COMPARE_UINT(crc32_amf_data, crc32_uncomp);
|
||||
free(dest);
|
||||
}
|
||||
/* -- Read ZIP data descriptor */
|
||||
wbuff.pos = pos_start_amf_data + zip_cdh.compressed_size;
|
||||
struct gmio_zip_data_descriptor zip_dd = {0};
|
||||
gmio_zip_read_data_descriptor(&stream, &zip_dd, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(zip_dd.crc32, crc32_amf_data);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_dd.compressed_size, zip_cdh.compressed_size);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_dd.uncompressed_size, zip_cdh.uncompressed_size);
|
||||
}
|
||||
|
||||
free(source);
|
||||
free(amf_data);
|
||||
free(wbuff.ptr);
|
||||
return NULL;
|
||||
}
|
||||
@ -440,13 +384,8 @@ static const char* test_amf_write_doc_1_zip64()
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
}
|
||||
|
||||
const size_t source_len = wbuff.pos;
|
||||
const uint32_t crc32_amf_data = gmio_zlib_crc32(wbuff.ptr, source_len);
|
||||
uint8_t* source = calloc(source_len, 1);
|
||||
memcpy(source, wbuff.ptr, source_len);
|
||||
const uintmax_t amf_data_len = wbuff.pos;
|
||||
|
||||
static const char zip_entry_filename[] = "test.amf";
|
||||
static const uint16_t zip_entry_filename_len = sizeof(zip_entry_filename) - 1;
|
||||
{ /* Write compressed(Zip64) */
|
||||
wbuff.pos = 0;
|
||||
struct gmio_amf_write_options options = {0};
|
||||
@ -471,83 +410,32 @@ static const char* test_amf_write_doc_1_zip64()
|
||||
wbuff.pos = 0;
|
||||
struct gmio_stream stream = gmio_stream_buffer(&wbuff);
|
||||
int error = GMIO_ERROR_OK;
|
||||
/* -- Read ZIP local file header */
|
||||
struct gmio_zip_local_file_header zip_lfh = {0};
|
||||
const size_t lfh_read_len =
|
||||
gmio_zip_read_local_file_header(&stream, &zip_lfh, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
zip_lfh.filename = (const char*)wbuff.ptr + wbuff.pos;
|
||||
const char* check_str = __tamf__check_zip_local_file_header(&zip_lfh);
|
||||
if (check_str != NULL)
|
||||
return check_str;
|
||||
/* -- Read ZIP end of central directory record */
|
||||
static const size_t end_of_central_dir_record_len = 22;
|
||||
wbuff.pos = zip_archive_len - end_of_central_dir_record_len;;
|
||||
struct gmio_zip_end_of_central_directory_record zip_eocdr = {0};
|
||||
gmio_zip_read_end_of_central_directory_record(
|
||||
&stream, &zip_eocdr, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(zip_eocdr.entry_count, 0xFFFF);
|
||||
UTEST_COMPARE_UINT(zip_eocdr.central_dir_size, 0xFFFFFFFF);
|
||||
UTEST_COMPARE_UINT(zip_eocdr.start_offset, 0xFFFFFFFF);
|
||||
#if 0
|
||||
/* -- Read Zip64 end of central directory record */
|
||||
wbuff.pos =
|
||||
zip_archive_len
|
||||
- GMIO_ZIP_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD
|
||||
- GMIO_ZIP64_SIZE_END_OF_CENTRAL_DIRECTORY_LOCATOR
|
||||
- GMIO_ZIP64_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD;
|
||||
struct gmio_zip64_end_of_central_directory_record zip64_eocdr = {0};
|
||||
gmio_zip64_read_end_of_central_directory_record(
|
||||
&stream, &zip64_eocdr, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
/* -- Read ZIP central directory */
|
||||
wbuff.pos = zip_eocdr.start_offset_central_dir_from_disk_start_nb;
|
||||
wbuff.pos = zip64_eocdr.central_dir_offset;
|
||||
struct gmio_zip_central_directory_header zip_cdh = {0};
|
||||
gmio_zip_read_central_directory_header(&stream, &zip_cdh, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_cdh.compress_method,
|
||||
GMIO_ZIP_COMPRESS_METHOD_DEFLATE);
|
||||
UTEST_ASSERT(
|
||||
(zip_cdh.general_purpose_flags &
|
||||
GMIO_ZIP_GENERAL_PURPOSE_FLAG_USE_DATA_DESCRIPTOR)
|
||||
!= 0);
|
||||
UTEST_COMPARE_UINT(crc32_amf_data, zip_cdh.crc32);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_cdh.filename_len, zip_entry_filename_len);
|
||||
UTEST_ASSERT(strncmp(
|
||||
(const char*)wbuff.ptr + wbuff.pos,
|
||||
zip_entry_filename,
|
||||
zip_entry_filename_len)
|
||||
== 0);
|
||||
/* -- Read compressed AMF data */
|
||||
const size_t pos_start_amf_data =
|
||||
lfh_read_len + zip_lfh.filename_len + zip_lfh.extrafield_len;
|
||||
wbuff.pos = pos_start_amf_data;
|
||||
{
|
||||
uint8_t* dest = calloc(zip_cdh.uncompressed_size, 1);
|
||||
size_t dest_len = zip_cdh.uncompressed_size;
|
||||
const int error =
|
||||
gmio_zlib_uncompress_buffer(
|
||||
dest,
|
||||
&dest_len,
|
||||
(const uint8_t*)wbuff.ptr + wbuff.pos,
|
||||
zip_cdh.compressed_size);
|
||||
printf("\n-- Info: z_len=%i src_len=%i\n",
|
||||
zip_cdh.compressed_size, source_len);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(source_len, dest_len);
|
||||
UTEST_COMPARE_UINT(dest_len, zip_cdh.uncompressed_size);
|
||||
UTEST_COMPARE_INT(memcmp(dest, source, source_len), 0);
|
||||
const uint32_t crc32_uncomp = gmio_zlib_crc32(dest, dest_len);
|
||||
UTEST_COMPARE_UINT(crc32_amf_data, crc32_uncomp);
|
||||
free(dest);
|
||||
}
|
||||
/* -- Read ZIP data descriptor */
|
||||
wbuff.pos = pos_start_amf_data + zip_cdh.compressed_size;
|
||||
struct gmio_zip_data_descriptor zip_dd = {0};
|
||||
gmio_zip64_read_data_descriptor(&stream, &zip_dd, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(zip_dd.crc32, crc32_amf_data);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_dd.compressed_size, zip_cdh.compressed_size);
|
||||
UTEST_COMPARE_UINT(
|
||||
zip_dd.uncompressed_size, zip_cdh.uncompressed_size);
|
||||
#endif
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
/* -- Read ZIP central directory Zip64 extrafield*/
|
||||
wbuff.pos =
|
||||
zip64_eocdr.central_dir_offset
|
||||
+ GMIO_ZIP_SIZE_CENTRAL_DIRECTORY_HEADER
|
||||
+ zip_cdh.filename_len;
|
||||
struct gmio_zip64_extrafield zip64_extra = {0};
|
||||
gmio_zip64_read_extrafield(&stream, &zip64_extra, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(amf_data_len, zip64_extra.uncompressed_size);
|
||||
}
|
||||
|
||||
free(source);
|
||||
free(wbuff.ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "../src/gmio_core/internal/convert.h"
|
||||
#include "../src/gmio_core/internal/error_check.h"
|
||||
#include "../src/gmio_core/internal/fast_atof.h"
|
||||
#include "../src/gmio_core/internal/helper_stream.h"
|
||||
#include "../src/gmio_core/internal/locale_utils.h"
|
||||
#include "../src/gmio_core/internal/numeric_utils.h"
|
||||
#include "../src/gmio_core/internal/ostringstream.h"
|
||||
@ -44,6 +45,8 @@
|
||||
#include "../src/gmio_core/internal/stringstream.h"
|
||||
#include "../src/gmio_core/internal/stringstream_fast_atof.h"
|
||||
#include "../src/gmio_core/internal/string_ascii_utils.h"
|
||||
#include "../src/gmio_core/internal/zip_utils.h"
|
||||
#include "../src/gmio_core/internal/zlib_utils.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
@ -531,3 +534,284 @@ static const char* test_internal__error_check()
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __tc__write_file(const char* filepath, uint8_t* bytes, size_t len)
|
||||
{
|
||||
FILE* file = fopen(filepath, "wb");
|
||||
fwrite(bytes, 1, len, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
struct __tc__func_write_file_data_cookie {
|
||||
struct gmio_stream* stream;
|
||||
const uint8_t* data;
|
||||
const uint8_t* zdata;
|
||||
uint32_t data_crc32;
|
||||
size_t data_len;
|
||||
size_t zdata_len;
|
||||
};
|
||||
|
||||
static int __tc__write_zip_file_data(
|
||||
void* cookie, struct gmio_zip_data_descriptor* dd)
|
||||
{
|
||||
struct __tc__func_write_file_data_cookie* fcookie =
|
||||
(struct __tc__func_write_file_data_cookie*)cookie;
|
||||
gmio_stream_write_bytes(fcookie->stream, fcookie->zdata, fcookie->zdata_len);
|
||||
dd->crc32 = fcookie->data_crc32;
|
||||
dd->uncompressed_size = fcookie->data_len;
|
||||
dd->compressed_size = fcookie->zdata_len;
|
||||
return GMIO_ERROR_OK;
|
||||
}
|
||||
|
||||
static const char* __tc__zip_compare_entry(
|
||||
const struct gmio_zip_file_entry* lhs,
|
||||
const struct gmio_zip_file_entry* rhs)
|
||||
{
|
||||
UTEST_COMPARE_UINT(lhs->compress_method, rhs->compress_method);
|
||||
UTEST_COMPARE_UINT(lhs->feature_version, rhs->feature_version);
|
||||
UTEST_COMPARE_UINT(lhs->filename_len, rhs->filename_len);
|
||||
UTEST_ASSERT(strncmp(lhs->filename, rhs->filename, lhs->filename_len) == 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* test_internal__zip_utils()
|
||||
{
|
||||
static const unsigned bytes_size = 1024;
|
||||
uint8_t* bytes = calloc(bytes_size, 1);
|
||||
struct gmio_rw_buffer wbuff = gmio_rw_buffer(bytes, bytes_size, 0);
|
||||
struct gmio_stream stream = gmio_stream_buffer(&wbuff);
|
||||
int error;
|
||||
|
||||
/* Write empty ZIP file */
|
||||
{
|
||||
struct gmio_zip_end_of_central_directory_record eocdr = {0};
|
||||
gmio_zip_write_end_of_central_directory_record(&stream, &eocdr, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
#if 1
|
||||
__tc__write_file("test_output_empty.zip", wbuff.ptr, wbuff.pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Write empty Zip64 file */
|
||||
wbuff.pos = 0;
|
||||
{
|
||||
struct gmio_zip64_end_of_central_directory_record eocdr64 = {0};
|
||||
eocdr64.version_needed_to_extract =
|
||||
GMIO_ZIP_FEATURE_VERSION_FILE_ZIP64_FORMAT_EXTENSIONS;
|
||||
gmio_zip64_write_end_of_central_directory_record(
|
||||
&stream, &eocdr64, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
|
||||
struct gmio_zip64_end_of_central_directory_locator eocdl64 = {0};
|
||||
gmio_zip64_write_end_of_central_directory_locator(
|
||||
&stream, &eocdl64, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
|
||||
struct gmio_zip_end_of_central_directory_record eocdr = {0};
|
||||
gmio_zip_write_end_of_central_directory_record(&stream, &eocdr, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
#if 1
|
||||
__tc__write_file("test_output_empty_64.zip", wbuff.ptr, wbuff.pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Common constants */
|
||||
static const char zip_entry_filedata[] =
|
||||
"On ne fait bien que ce qu'on fait soi-même";
|
||||
struct __tc__func_write_file_data_cookie fcookie = {0};
|
||||
fcookie.stream = &stream;
|
||||
fcookie.data = (const uint8_t*)zip_entry_filedata;
|
||||
fcookie.zdata = fcookie.data; /* No compression */
|
||||
fcookie.data_len = GMIO_ARRAY_SIZE(zip_entry_filedata) - 1;
|
||||
fcookie.zdata_len = fcookie.data_len; /* No compression */
|
||||
fcookie.data_crc32 = gmio_zlib_crc32(fcookie.data, fcookie.data_len);
|
||||
static const char zip_entry_filename[] = "file.txt";
|
||||
static const uint16_t zip_entry_filename_len =
|
||||
GMIO_ARRAY_SIZE(zip_entry_filename) - 1;
|
||||
|
||||
/* Common variables */
|
||||
struct gmio_zip_file_entry entry = {0};
|
||||
entry.compress_method = GMIO_ZIP_COMPRESS_METHOD_NO_COMPRESSION;
|
||||
entry.feature_version = GMIO_ZIP_FEATURE_VERSION_DEFAULT;
|
||||
entry.filename = zip_entry_filename;
|
||||
entry.filename_len = zip_entry_filename_len;
|
||||
entry.cookie_func_write_file_data = &fcookie;
|
||||
entry.func_write_file_data = __tc__write_zip_file_data;
|
||||
|
||||
/*
|
||||
* Write one-entry ZIP file
|
||||
*/
|
||||
{
|
||||
wbuff.pos = 0;
|
||||
entry.feature_version = GMIO_ZIP_FEATURE_VERSION_DEFAULT;
|
||||
UTEST_ASSERT(gmio_zip_write_single_file(&stream, &entry, &error));
|
||||
UTEST_COMPARE_UINT(error, GMIO_ERROR_OK);
|
||||
#if 1
|
||||
__tc__write_file("test_output_one_file.zip", wbuff.ptr, wbuff.pos);
|
||||
#endif
|
||||
|
||||
const uintmax_t zip_archive_len = wbuff.pos;
|
||||
wbuff.pos = 0;
|
||||
/* -- Read ZIP local file header */
|
||||
struct gmio_zip_local_file_header zip_lfh = {0};
|
||||
const size_t lfh_read_len =
|
||||
gmio_zip_read_local_file_header(&stream, &zip_lfh, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
struct gmio_zip_file_entry lfh_entry = {0};
|
||||
lfh_entry.compress_method = zip_lfh.compress_method;
|
||||
lfh_entry.feature_version = zip_lfh.version_needed_to_extract;
|
||||
lfh_entry.filename = (const char*)wbuff.ptr + wbuff.pos;
|
||||
lfh_entry.filename_len = zip_lfh.filename_len;
|
||||
const char* check_str = __tc__zip_compare_entry(&entry, &lfh_entry);
|
||||
if (check_str != NULL) return check_str;
|
||||
/* -- Read ZIP end of central directory record */
|
||||
wbuff.pos =
|
||||
zip_archive_len - GMIO_ZIP_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD;
|
||||
struct gmio_zip_end_of_central_directory_record zip_eocdr = {0};
|
||||
gmio_zip_read_end_of_central_directory_record(
|
||||
&stream, &zip_eocdr, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(zip_eocdr.entry_count, 1);
|
||||
/* -- Read ZIP central directory */
|
||||
wbuff.pos = zip_eocdr.central_dir_offset;
|
||||
struct gmio_zip_central_directory_header zip_cdh = {0};
|
||||
gmio_zip_read_central_directory_header(&stream, &zip_cdh, &error);
|
||||
struct gmio_zip_file_entry cdh_entry = {0};
|
||||
cdh_entry.compress_method = zip_cdh.compress_method;
|
||||
cdh_entry.feature_version = zip_cdh.version_needed_to_extract;
|
||||
cdh_entry.filename = (const char*)wbuff.ptr + wbuff.pos;
|
||||
cdh_entry.filename_len = zip_lfh.filename_len;
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_ASSERT((zip_cdh.general_purpose_flags &
|
||||
GMIO_ZIP_GENERAL_PURPOSE_FLAG_USE_DATA_DESCRIPTOR)
|
||||
!= 0);
|
||||
UTEST_COMPARE_UINT(fcookie.data_crc32, zip_cdh.crc32);
|
||||
UTEST_COMPARE_UINT(fcookie.data_len, zip_cdh.uncompressed_size);
|
||||
UTEST_COMPARE_UINT(fcookie.zdata_len, zip_cdh.compressed_size);
|
||||
UTEST_COMPARE_UINT(zip_cdh.local_header_offset, 0);
|
||||
check_str = __tc__zip_compare_entry(&entry, &cdh_entry);
|
||||
if (check_str != NULL) return check_str;
|
||||
/* -- Read file data */
|
||||
const size_t pos_file_data =
|
||||
lfh_read_len + zip_lfh.filename_len + zip_lfh.extrafield_len;
|
||||
UTEST_ASSERT(strncmp((const char*)wbuff.ptr + pos_file_data,
|
||||
(const char*)fcookie.zdata,
|
||||
fcookie.zdata_len)
|
||||
== 0);
|
||||
/* -- Read ZIP data descriptor */
|
||||
wbuff.pos = pos_file_data + zip_cdh.compressed_size;
|
||||
struct gmio_zip_data_descriptor zip_dd = {0};
|
||||
gmio_zip_read_data_descriptor(&stream, &zip_dd, &error);
|
||||
UTEST_COMPARE_INT(error, GMIO_ERROR_OK);
|
||||
UTEST_COMPARE_UINT(zip_dd.crc32, zip_cdh.crc32);
|
||||
UTEST_COMPARE_UINT(zip_dd.compressed_size, zip_cdh.compressed_size);
|
||||
UTEST_COMPARE_UINT(zip_dd.uncompressed_size, zip_cdh.uncompressed_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one-entry Zip64 file
|
||||
*/
|
||||
{
|
||||
wbuff.pos = 0;
|
||||
entry.feature_version =
|
||||
GMIO_ZIP_FEATURE_VERSION_FILE_ZIP64_FORMAT_EXTENSIONS;
|
||||
UTEST_ASSERT(gmio_zip_write_single_file(&stream, &entry, &error));
|
||||
UTEST_COMPARE_UINT(error, GMIO_ERROR_OK);
|
||||
#if 1
|
||||
__tc__write_file("test_output_one_file_64.zip", wbuff.ptr, wbuff.pos);
|
||||
#endif
|
||||
|
||||
const uintmax_t zip_archive_len = wbuff.pos;
|
||||
/* -- Read ZIP end of central directory record */
|
||||
wbuff.pos =
|
||||
zip_archive_len - GMIO_ZIP_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD;
|
||||
struct gmio_zip_end_of_central_directory_record zip_eocdr = {0};
|
||||
gmio_zip_read_end_of_central_directory_record(
|
||||
&stream, &zip_eocdr, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(UINT16_MAX, zip_eocdr.entry_count);
|
||||
UTEST_COMPARE_UINT(UINT32_MAX, zip_eocdr.central_dir_size);
|
||||
UTEST_COMPARE_UINT(UINT32_MAX, zip_eocdr.central_dir_offset);
|
||||
/* -- Read Zip64 end of central directory locator */
|
||||
wbuff.pos =
|
||||
zip_archive_len
|
||||
- GMIO_ZIP_SIZE_END_OF_CENTRAL_DIRECTORY_RECORD
|
||||
- GMIO_ZIP64_SIZE_END_OF_CENTRAL_DIRECTORY_LOCATOR;
|
||||
struct gmio_zip64_end_of_central_directory_locator zip64_eocdl = {0};
|
||||
gmio_zip64_read_end_of_central_directory_locator(
|
||||
&stream, &zip64_eocdl, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
/* -- Read Zip64 end of central directory record */
|
||||
wbuff.pos = zip64_eocdl.zip64_end_of_central_dir_offset;
|
||||
struct gmio_zip64_end_of_central_directory_record zip64_eocdr = {0};
|
||||
gmio_zip64_read_end_of_central_directory_record(
|
||||
&stream, &zip64_eocdr, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(
|
||||
GMIO_ZIP_FEATURE_VERSION_FILE_ZIP64_FORMAT_EXTENSIONS,
|
||||
zip64_eocdr.version_needed_to_extract);
|
||||
UTEST_COMPARE_UINT(1, zip64_eocdr.entry_count);
|
||||
/* -- Read ZIP central directory header */
|
||||
wbuff.pos = zip64_eocdr.central_dir_offset;
|
||||
struct gmio_zip_central_directory_header zip_cdh = {0};
|
||||
size_t zip_cdh_len =
|
||||
gmio_zip_read_central_directory_header(&stream, &zip_cdh, &error);
|
||||
zip_cdh_len +=
|
||||
zip_cdh.filename_len
|
||||
+ zip_cdh.extrafield_len
|
||||
+ zip_cdh.filecomment_len;
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(zip64_eocdr.central_dir_size, zip_cdh_len);
|
||||
UTEST_ASSERT((zip_cdh.general_purpose_flags &
|
||||
GMIO_ZIP_GENERAL_PURPOSE_FLAG_USE_DATA_DESCRIPTOR)
|
||||
!= 0);
|
||||
UTEST_COMPARE_UINT(fcookie.data_crc32, zip_cdh.crc32);
|
||||
UTEST_COMPARE_UINT(UINT32_MAX, zip_cdh.uncompressed_size);
|
||||
UTEST_COMPARE_UINT(UINT32_MAX, zip_cdh.compressed_size);
|
||||
UTEST_COMPARE_UINT(UINT32_MAX, zip_cdh.local_header_offset);
|
||||
struct gmio_zip_file_entry cdh_entry = {0};
|
||||
cdh_entry.compress_method = zip_cdh.compress_method;
|
||||
cdh_entry.feature_version = zip_cdh.version_needed_to_extract;
|
||||
cdh_entry.filename = (const char*)wbuff.ptr + wbuff.pos;
|
||||
cdh_entry.filename_len = zip_cdh.filename_len;
|
||||
const char* check_str = __tc__zip_compare_entry(&entry, &cdh_entry);
|
||||
if (check_str != NULL) return check_str;
|
||||
/* Read Zip64 extra field */
|
||||
wbuff.pos =
|
||||
zip64_eocdr.central_dir_offset
|
||||
+ GMIO_ZIP_SIZE_CENTRAL_DIRECTORY_HEADER
|
||||
+ zip_cdh.filename_len;
|
||||
struct gmio_zip64_extrafield zip64_extra = {0};
|
||||
gmio_zip64_read_extrafield(&stream, &zip64_extra, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(fcookie.data_len, zip64_extra.uncompressed_size);
|
||||
UTEST_COMPARE_UINT(fcookie.zdata_len, zip64_extra.compressed_size);
|
||||
UTEST_COMPARE_UINT(0, zip64_extra.local_header_offset);
|
||||
/* Read ZIP local file header */
|
||||
wbuff.pos = 0;
|
||||
struct gmio_zip_local_file_header zip_lfh = {0};
|
||||
gmio_zip_read_local_file_header(&stream, &zip_lfh, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_INT(0, zip_lfh.crc32);
|
||||
UTEST_COMPARE_INT(0, zip_lfh.compressed_size);
|
||||
UTEST_COMPARE_INT(0, zip_lfh.uncompressed_size);
|
||||
/* Read ZIP local file header extrafield */
|
||||
wbuff.pos = GMIO_ZIP_SIZE_LOCAL_FILE_HEADER + zip_lfh.filename_len;
|
||||
gmio_zip64_read_extrafield(&stream, &zip64_extra, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(0, zip64_extra.uncompressed_size);
|
||||
UTEST_COMPARE_UINT(0, zip64_extra.compressed_size);
|
||||
UTEST_COMPARE_UINT(0, zip64_extra.local_header_offset);
|
||||
/* Read Zip64 data descriptor */
|
||||
wbuff.pos += fcookie.zdata_len;
|
||||
struct gmio_zip_data_descriptor zip_dd = {0};
|
||||
gmio_zip64_read_data_descriptor(&stream, &zip_dd, &error);
|
||||
UTEST_COMPARE_INT(GMIO_ERROR_OK, error);
|
||||
UTEST_COMPARE_UINT(fcookie.data_crc32, zip_dd.crc32);
|
||||
UTEST_COMPARE_UINT(fcookie.data_len, zip_dd.uncompressed_size);
|
||||
UTEST_COMPARE_UINT(fcookie.zdata_len, zip_dd.compressed_size);
|
||||
}
|
||||
|
||||
free(bytes);
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user