MCPcopy Create free account
hub / github.com/Squirrel/Squirrel.Windows / Unzip

Method Unzip

src/Setup/unzip.cpp:3964–4036  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3962
3963
3964ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags)
3965{ if (flags!=ZIP_MEMORY && flags!=ZIP_FILENAME && flags!=ZIP_HANDLE) return ZR_ARGS;
3966 if (flags==ZIP_MEMORY)
3967 { if (index!=currentfile)
3968 { if (currentfile!=-1) unzCloseCurrentFile(uf); currentfile=-1;
3969 if (index>=(int)uf->gi.number_entry) return ZR_ARGS;
3970 if (index<(int)uf->num_file) unzGoToFirstFile(uf);
3971 while ((int)uf->num_file<index) unzGoToNextFile(uf);
3972 unzOpenCurrentFile(uf,password); currentfile=index;
3973 }
3974 bool reached_eof;
3975 int res = unzReadCurrentFile(uf,dst,len,&reached_eof);
3976 if (res<=0) {unzCloseCurrentFile(uf); currentfile=-1;}
3977 if (reached_eof) return ZR_OK;
3978 if (res>0) return ZR_MORE;
3979 if (res==UNZ_PASSWORD) return ZR_PASSWORD;
3980 return ZR_FLATE;
3981 }
3982 // otherwise we're writing to a handle or a file
3983 if (currentfile!=-1) unzCloseCurrentFile(uf); currentfile=-1;
3984 if (index>=(int)uf->gi.number_entry) return ZR_ARGS;
3985 if (index<(int)uf->num_file) unzGoToFirstFile(uf);
3986 while ((int)uf->num_file<index) unzGoToNextFile(uf);
3987 ZIPENTRY ze; Get(index,&ze);
3988 // zipentry=directory is handled specially
3989 if ((ze.attr&FILE_ATTRIBUTE_DIRECTORY)!=0)
3990 { if (flags==ZIP_HANDLE) return ZR_OK; // don't do anything
3991 const TCHAR *dir = (const TCHAR*)dst;
3992 bool isabsolute = (dir[0]=='/' || dir[0]=='\\' || (dir[0]!=0 && dir[1]==':'));
3993 if (isabsolute) EnsureDirectory(0,dir); else EnsureDirectory(rootdir,dir);
3994 return ZR_OK;
3995 }
3996 // otherwise, we write the zipentry to a file/handle
3997 HANDLE h;
3998 if (flags==ZIP_HANDLE) h=dst;
3999 else
4000 { const TCHAR *ufn = (const TCHAR*)dst;
4001 // We'll qualify all relative names to our root dir, and leave absolute names as they are
4002 // ufn="zipfile.txt" dir="" name="zipfile.txt" fn="c:\\currentdir\\zipfile.txt"
4003 // ufn="dir1/dir2/subfile.txt" dir="dir1/dir2/" name="subfile.txt" fn="c:\\currentdir\\dir1/dir2/subfiles.txt"
4004 // ufn="\z\file.txt" dir="\z\" name="file.txt" fn="\z\file.txt"
4005 // This might be a security risk, in the case where we just use the zipentry's name as "ufn", where
4006 // a malicious zip could unzip itself into c:\windows. Our solution is that GetZipItem (which
4007 // is how the user retrieve's the file's name within the zip) never returns absolute paths.
4008 const TCHAR *name=ufn; const TCHAR *c=name; while (*c!=0) {if (*c=='/' || *c=='\\') name=c+1; c++;}
4009 TCHAR dir[MAX_PATH]; _tcscpy_s(dir, MAX_PATH, ufn); if (name==ufn) *dir=0; else dir[name-ufn]=0;
4010 TCHAR fn[MAX_PATH];
4011 bool isabsolute = (dir[0]=='/' || dir[0]=='\\' || (dir[0]!=0 && dir[1]==':'));
4012 if (isabsolute) {wsprintf(fn,_T("%s%s"),dir,name); EnsureDirectory(0,dir);}
4013 else {wsprintf(fn,_T("%s%s%s"),rootdir,dir,name); EnsureDirectory(rootdir,dir);}
4014 //
4015 h = CreateFile(fn,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,ze.attr,NULL);
4016 }
4017 if (h==INVALID_HANDLE_VALUE) return ZR_NOFILE;
4018 unzOpenCurrentFile(uf,password);
4019 if (unzbuf==0) unzbuf=new char[16384]; DWORD haderr=0;
4020 //
4021

Callers 1

UnzipItemInternalFunction · 0.80

Calls 6

unzCloseCurrentFileFunction · 0.85
unzGoToFirstFileFunction · 0.85
unzGoToNextFileFunction · 0.85
unzOpenCurrentFileFunction · 0.85
unzReadCurrentFileFunction · 0.85
EnsureDirectoryFunction · 0.85

Tested by

no test coverage detected