Natalia Pujol - 2010-04-17

Hi! I wrote this because AdvZip don't support Zip files writed using Java ZipOutStream class.

ZipOutStream class add an "non-standard" signature at end of every file entry, in th data descriptor. Just after data and before the CRC32.

To solve this I've patched two functions to do a workaround about this.
The changes are:

File: zip.cpp

in void zip::skip_local(const unsigned char* buf, FILE* f)

Original:

// data descriptor
if ((le_uint16_read(buf+ZIP_LO_general_purpose_bit_flag) & ZIP_GEN_FLAGS_DEFLATE_ZERO) != 0) {
if (fseek(f, ZIP_DO_FIXED, SEEK_CUR) != 0) {
throw error_invalid() << "Failed seek";
}
}
}

Patched:

// data descriptor
if ((le_uint16_read(buf+ZIP_LO_general_purpose_bit_flag) & ZIP_GEN_FLAGS_DEFLATE_ZERO) != 0) {
/* *****************************************************************
   **     Workaround to solve ZipOutputStream incompatibility     **
   ***************************************************************** */
unsigned char data_desc;
if (fread(data_desc, 4, 1, f) != 1) {
throw error() << "Failed read";
}
if (le_uint32_read(data_desc) != 0x08074B50) {
fseek(f, -4, SEEK_CUR);
}
/* *****************************************************************
   **     End Workaround                                          **
   ***************************************************************** */
if (fseek(f, ZIP_DO_FIXED, SEEK_CUR) != 0) {
throw error_invalid() << "Failed seek";
}
}
}

in void zip_entry::load_local(const unsigned char* buf, FILE* f, unsigned size)

Original:

if (size < ZIP_DO_FIXED) {
throw error_invalid() << "Overflow of data descriptor";
}
size -= ZIP_DO_FIXED;

if (fread(data_desc, ZIP_DO_FIXED, 1, f) != 1) {
throw error() << "Failed read";
}

check_descriptor(data_desc);
}
}

Patched:

if (size < ZIP_DO_FIXED) {
throw error_invalid() << "Overflow of data descriptor";
}
size -= ZIP_DO_FIXED;

/* *****************************************************************
   **     Workaround to solve ZipOutputStream incompatibility     **
   ***************************************************************** */
if (fread(data_desc, 4, 1, f) != 1) {
throw error() << "Failed read";
}
if (le_uint32_read(data_desc) != 0x08074B50) {
fseek(f, -4, SEEK_CUR);
}
/* *****************************************************************
   **     End Workaround                                          **
   ***************************************************************** */
if (fread(data_desc, ZIP_DO_FIXED, 1, f) != 1) {
throw error() << "Failed read";
}

check_descriptor(data_desc);
}
}

I hope this help somebody…