|
|
Comments and Discussions
|
|
 |

|
There has been a lot of fixes and enhancements posted over the years. Is there an updated version that includes all of these fixes?
|
|
|
|

|
Yes! Version 1.4 would be very welcome!
Thomas Haase
|
|
|
|

|
Bug
The current version of the library when building with _UNICODE defined and using
ZipAdd(zipFile, L"HelloWorld.txt", buffer, sizeof(buffer), ZIP_MEMORY) results in a bug that only the 1st character 'H' of the filename "HelloWorld.txt" gets stored in the zip archive because the cast to (char*)dstzn produces "H\0" as the filename rather than "HelloWorld.txt\0". Reason being the wchar_t is 2 bytes and since 'H' 0x48 is stored as 2 bytes with the 1st byte being NUL 0x00 and the 2nd byte being 'H' 0x48 and in little endian it is stored in RAM as "H\0" 0x48 0x00 hence the cast to (char*) produces a null terminated string "H\0".
The buggy code is in XZip.cpp ZipAdd(...)
if (flags == ZIP_FILENAME)
{
char szDest[MAX_PATH*2];
memset(szDest, 0, sizeof(szDest));
#ifdef _UNICODE
int nActualChars = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) dstzn, -1, szDest, MAX_PATH*2-2, NULL, NULL); if (nActualChars == 0)
return ZR_ARGS;
#else
strcpy(szDest, dstzn);
#endif
lasterrorZ = zip->Add(szDest, src, len, flags);
}
else
{
lasterrorZ = zip->Add((char *)dstzn, src, len, flags);
}
Solution
To fix the bug the code should be simplified to this in XZip.cpp ZipAdd(...)
1. Check for invalid dstzn parameter
if (hz == 0)
{
lasterrorZ = ZR_ARGS;
return ZR_ARGS;
}
if (dstzn == NULL)
{
lasterrorZ = ZR_ARGS;
return ZR_ARGS;
}
TZipHandleData *han = (TZipHandleData*)hz;
2. Remove the if/else to always convert the filename regardless of the value of the flags parameter
TZip *zip = han->zip;
char szDest[MAX_PATH*2];
memset(szDest, 0, sizeof(szDest));
#ifdef _UNICODE
int nActualChars = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) dstzn, -1, szDest, MAX_PATH*2-2, NULL, NULL); if (nActualChars == 0)
return ZR_ARGS;
#else
strcpy(szDest, dstzn);
#endif
lasterrorZ = zip->Add(szDest, src, len, flags);
return lasterrorZ;
modified 19 Oct '11 - 16:35.
|
|
|
|

|
Hi there: Tried to use CreateZip with ZIP_FOLDER, but always have an error returned. I was trying to pack several folders with files underneath into a zip file under an assigned directory. Can anyone shed a light on how to do that? Thanks and regards, Ke
|
|
|
|

|
The problem might be a unicode issue. The ZipAdd function is only handling unicode properly for files and not folders. Solution:
ZRESULT ZipAdd(HZIP hz, const TCHAR *dstzn, void *src, unsigned int len, DWORD flags)
{
...
FROM:
if ( flags == ZIP_FILENAME )
{
TO:
if ( dstzn )
{
...
}
modified on Tuesday, August 23, 2011 8:03 PM
|
|
|
|

|
I really appreciate Hans and all whom worked on this code, because it works!
I recently noticed that opening an existing zip file reports "UNZ_BADZIPFILE" when the file size is larger than 2GB. To resolve this I made a lot of changes to my copy of the code, but they can be summarized as follows for anyone who is interested (basically the issue is the variables used are too small):
- change all "unsigned long" variables to "unsigned __int64" (see unz_global_info, unz_file_info).
- change the definition of "uLong" from "unsigned long" to "unsigned __int64" (I just got rid of "uLong" and replaced it).
- change several "unsigned int" variables to "unsigned __int64" (specifically LUFILE struct's members).
- replace SetFilePointer() with SetFilePointerEx(), so that you can use the unsigned __int64 values.
An example replacement of SetFilePointer() is this in the "lufseek()" function:
if (whence==SEEK_SET)
{
LARGE_INTEGER lnValue;
lnValue.QuadPart = stream->initial_offset + offset;
::SetFilePointerEx(stream->h, lnValue, NULL, FILE_BEGIN);
}
The files affected by this change were XUnzip.cpp and XUnzip.h (update struct's ZIPENTRY and ZIPENTRYW).
The limited testing I have done shows that it works, i.e. I can now successfully retrieve a listing of entries from a zip file that is larger than 2GB.
Hope this helps,
- Peter.
Owner Fourth Ray Software
fourthray.com
|
|
|
|
|

|
i have problem when unzip large file.
BOOL res = ReadFile(stream->h,ptr,toread,&red,NULL);
=> red return = 0;
it don't have in your solution
i don't know how to slove it,
help me...
|
|
|
|

|
FindZipItem will fail if the first char of const TCHAR *name is a forward slash.
In unzLocateFile in xunzip.cpp i added 2 lines of code to make unzipping files easier.
while ( *(szFileName++) == 0x2F ) {} szFileName--;
Adding above will now allow calling FindZipItem with or with out a leading forward slash.
So for example all the following works now
FindZipItem( hj, "icon.png", 0, &idx, &ze );
FindZipItem( hj, "/icon.png", 0, &idx, &ze );
FindZipItem( hj, "/res/image2d/icon.png", 0, &idx, &ze );
FindZipItem( hj, "META-INF/MANIFEST.MF", 0, &idx, &ze );
FindZipItem( hj, "/META-INF/MANIFEST.MF", 0, &idx, &ze );
And i know people read these pages lol
Come on post some comments or even better some improvements
Someone smart needs to update this class to allow updating existing zips, that would be cool !
|
|
|
|

|
Thanks.
The problem is not the desire to update the class, but the fact that the original code is such a horrible spaghetti mess that almost any change will break something else.
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
XZip and XUnzip provide non-MFC functions to create a zip, add files to it, and extract files from it - all in two .cpp files
| Type | Article |
| Licence | CPOL |
| First Posted | 13 May 2003 |
| Views | 407,073 |
| Downloads | 10,390 |
| Bookmarked | 239 times |
|
|