From 71a38563ae44daea05ec919c21cb3e622d08720f Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 14 Aug 2016 22:52:13 +0200 Subject: Windows: various fixes for XZip library bugs --- src/Common/XUnzip.cpp | 48 ++++++++++++++++++++++++++++++++---------- src/Common/XZip.cpp | 58 ++++++++++++++++++++++++++++----------------------- 2 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/Common/XUnzip.cpp b/src/Common/XUnzip.cpp index 5d522870..913f4408 100644 --- a/src/Common/XUnzip.cpp +++ b/src/Common/XUnzip.cpp @@ -90,8 +90,9 @@ // /////////////////////////////////////////////////////////////////////////////// - +#ifndef _WIN64 #define _USE_32BIT_TIME_T //+++1.2 +#endif #define STRICT @@ -3673,14 +3674,30 @@ int unzReadCurrentFile (unzFile file, voidp buf, unsigned len) pfile_in_zip_read_info->crc32 = ucrc32(pfile_in_zip_read_info->crc32,bufBefore,(uInt)(uOutThis)); pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - if (err==Z_STREAM_END) return (iRead==0) ? UNZ_EOF : iRead; //+++1.3 + if (err==Z_STREAM_END) + { + if( pfile_in_zip_read_info->rest_read_uncompressed > 0 ) + { + return iRead; // More to go + } + return Z_OK; // No point returning UNZ_EOF as it is also zero + } + //if (err==Z_STREAM_END) return (iRead==0) ? UNZ_EOF : iRead; //+++1.3 //if (err==Z_STREAM_END) return (iRead==len) ? UNZ_EOF : iRead; //+++1.2 if (err != Z_OK) break; } } - if (err==Z_OK) return iRead; + // if (err==Z_OK) return iRead; + if( err == Z_OK ) + { + if( pfile_in_zip_read_info->rest_read_uncompressed > 0 ) + { + return iRead; // More to go + } + return Z_OK; // Done + } return iRead; } @@ -3839,10 +3856,17 @@ int unzReadCurrentFile (unzFile file, void *buf, unsigned len); int unzCloseCurrentFile (unzFile file); -FILETIME timet2filetime(time_t timer) +FILETIME timet2filetime(__time32_t timer) { - struct tm *tm = gmtime(&timer); + struct tm *tm = _gmtime32(&timer); SYSTEMTIME st; + + if (tm == NULL) + { + _time32(&timer); + tm = _gmtime32(&timer); + } + st.wYear = (WORD)(tm->tm_year+1900); st.wMonth = (WORD)(tm->tm_mon+1); st.wDay = (WORD)(tm->tm_mday); @@ -3953,8 +3977,9 @@ ZRESULT TUnzip::Get(int index,ZIPENTRY *ze) // WORD dostime = (WORD)(ufi.dosDate&0xFFFF); WORD dosdate = (WORD)((ufi.dosDate>>16)&0xFFFF); - FILETIME ft; - DosDateTimeToFileTime(dosdate,dostime,&ft); + FILETIME lt, ft; + DosDateTimeToFileTime(dosdate,dostime,<); + LocalFileTimeToFileTime(<,&ft); ze->atime=ft; ze->ctime=ft; ze->mtime=ft; // the zip will always have at least that dostime. But if it also has // an extra header, then we'll instead get the info from that. @@ -3969,15 +3994,15 @@ ZRESULT TUnzip::Get(int index,ZIPENTRY *ze) bool hasctime = (flags&4)!=0; epos+=5; if (hasmtime) - { time_t mtime = *(time_t*)(extra+epos); epos+=4; + { __time32_t mtime = *(__time32_t*)(extra+epos); epos+=4; ze->mtime = timet2filetime(mtime); } if (hasatime) - { time_t atime = *(time_t*)(extra+epos); epos+=4; + { __time32_t atime = *(__time32_t*)(extra+epos); epos+=4; ze->atime = timet2filetime(atime); } if (hasctime) - { time_t ctime = *(time_t*)(extra+epos); + { __time32_t ctime = *(__time32_t*)(extra+epos); ze->ctime = timet2filetime(ctime); } break; @@ -4164,7 +4189,8 @@ ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags) SetFileTime(h,&ze.ctime,&ze.atime,&ze.mtime); if (flags!=ZIP_HANDLE) CloseHandle(h); - unzCloseCurrentFile(uf); + if (unzCloseCurrentFile(uf) == UNZ_CRCERROR) + return ZR_CORRUPT; if (haderr) return ZR_WRITE; return ZR_OK; diff --git a/src/Common/XZip.cpp b/src/Common/XZip.cpp index 1d98d34e..9ce6de5d 100644 --- a/src/Common/XZip.cpp +++ b/src/Common/XZip.cpp @@ -90,7 +90,9 @@ // /////////////////////////////////////////////////////////////////////////////// +#ifndef _WIN64 #define _USE_32BIT_TIME_T //+++1.2 +#endif #define STRICT @@ -668,7 +670,7 @@ public: typedef struct iztimes { - time_t atime,mtime,ctime; + __time32_t atime,mtime,ctime; } iztimes; // access, modify, create times typedef struct zlist { @@ -2250,7 +2252,7 @@ bool HasZipSuffix(const char *fn) } -time_t filetime2timet(const FILETIME ft) +__time32_t filetime2timet(const FILETIME ft) { SYSTEMTIME st; FileTimeToSystemTime(&ft,&st); if (st.wYear<1970) {st.wYear=1970; st.wMonth=1; st.wDay=1;} if (st.wYear>=2038) {st.wYear=2037; st.wMonth=12; st.wDay=31;} @@ -2262,7 +2264,7 @@ time_t filetime2timet(const FILETIME ft) tm.tm_mon = st.wMonth-1; tm.tm_year = st.wYear-1900; tm.tm_isdst = 0; - time_t t = mktime(&tm); + __time32_t t = _mktime32(&tm); return t; } @@ -3050,6 +3052,13 @@ ZRESULT ZipAdd(HZIP hz, const TCHAR *dstzn, void *src, unsigned int len, DWORD f lasterrorZ = ZR_ARGS; return ZR_ARGS; } + + if (dstzn == NULL) + { + lasterrorZ = ZR_ARGS; + return ZR_ARGS; + } + TZipHandleData *han = (TZipHandleData*)hz; if (han->flag != 2) { @@ -3059,33 +3068,26 @@ ZRESULT ZipAdd(HZIP hz, const TCHAR *dstzn, void *src, unsigned int len, DWORD f TZip *zip = han->zip; - if (flags == ZIP_FILENAME) - { - char szDest[MAX_PATH*2]; - memset(szDest, 0, sizeof(szDest)); + char szDest[MAX_PATH*2]; + memset(szDest, 0, sizeof(szDest)); #ifdef _UNICODE - // need to convert Unicode dest to ANSI - int nActualChars = WideCharToMultiByte(CP_ACP, // code page - 0, // performance and mapping flags - (LPCWSTR) dstzn, // wide-character string - -1, // number of chars in string - szDest, // buffer for new string - MAX_PATH*2-2, // size of buffer - NULL, // default for unmappable chars - NULL); // set when default char used - if (nActualChars == 0) - return ZR_ARGS; + // need to convert Unicode dest to ANSI + int nActualChars = WideCharToMultiByte(CP_ACP, // code page + 0, // performance and mapping flags + (LPCWSTR) dstzn, // wide-character string + -1, // number of chars in string + szDest, // buffer for new string + MAX_PATH*2, // size of buffer + NULL, // default for unmappable chars + NULL); // set when default char used + if (nActualChars == 0) + return ZR_ARGS; #else - strcpy(szDest, dstzn); + strcpy(szDest, dstzn); #endif - lasterrorZ = zip->Add(szDest, src, len, flags); - } - else - { - lasterrorZ = zip->Add((char *)dstzn, src, len, flags); - } + lasterrorZ = zip->Add(szDest, src, len, flags); return lasterrorZ; } @@ -3182,8 +3184,12 @@ BOOL AddFolderContent(HZIP hZip, TCHAR* AbsolutePath, TCHAR* DirToAdd) _tcscpy(RelativePathNewFileFound, DirToAdd); _tcscat(RelativePathNewFileFound, _T("\\")); _tcscat(RelativePathNewFileFound, FindFileData.cFileName); + + TCHAR AbsoluteSourceFile[MAX_PATH] = { 0 }; + _tcscpy(AbsoluteSourceFile, AbsolutePath); + _tcscat(AbsoluteSourceFile, RelativePathNewFileFound); - if (ZipAdd(hZip, RelativePathNewFileFound, RelativePathNewFileFound, 0, ZIP_FILENAME) != ZR_OK) + if (ZipAdd(hZip, RelativePathNewFileFound, AbsoluteSourceFile, 0, ZIP_FILENAME) != ZR_OK) { return FALSE; } -- cgit v1.2.3