Fix issues with extraction of file permissions, especially in standalone. b=231083, 235781 r+sr=dveditz a=asa

This commit is contained in:
dbaron%dbaron.org 2004-08-17 00:12:04 +00:00
parent dc2f73bf76
commit b31f4063fe
4 changed files with 42 additions and 30 deletions

View File

@ -232,7 +232,7 @@ nsJAR::Open()
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(mZipFile, &rv);
if (NS_FAILED(rv)) return rv;
rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0664, &mFd);
rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0000, &mFd);
if (NS_FAILED(rv)) return rv;
PRInt32 err = mZip.OpenArchiveWithFileDesc(mFd);
@ -274,12 +274,19 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(outFile, &rv);
if (NS_FAILED(rv)) return rv;
nsZipItem *item = 0;
PRInt32 err = mZip.GetItem(zipEntry, &item);
if (err != ZIP_OK)
return ziperr2nsresult(err);
// Remove existing file so we set permissions correctly.
localFile->Remove(PR_FALSE);
PRFileDesc* fd;
rv = localFile->OpenNSPRFileDesc(PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 0664, &fd);
rv = localFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE, item->mode, &fd);
if (NS_FAILED(rv)) return NS_ERROR_FILE_ACCESS_DENIED;
nsZipItem *item = 0;
PRInt32 err = mZip.ExtractFileToFileDesc(zipEntry, fd, &item, mFd);
err = mZip.ExtractItemToFileDesc(item, fd, mFd);
PR_Close(fd);
if (err != ZIP_OK)
@ -287,15 +294,14 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
else
{
#if defined(XP_UNIX)
nsCAutoString path;
rv = outFile->GetNativePath(path);
if (NS_SUCCEEDED(rv))
if (item->flags & ZIFLAG_SYMLINK)
{
if (item->flags & ZIFLAG_SYMLINK)
nsCAutoString path;
rv = outFile->GetNativePath(path);
if (NS_SUCCEEDED(rv))
{
err = mZip.ResolveSymlink(path.get(),item);
}
chmod(path.get(), item->mode);
}
#endif
@ -446,7 +452,7 @@ nsJAR::OpenFile()
if (NS_FAILED(rv)) return nsnull;
PRFileDesc* fd;
rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0664, &fd);
rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0000, &fd);
if (NS_FAILED(rv)) return nsnull;
return fd;

View File

@ -105,6 +105,7 @@ char * strdup(const char *src)
#endif /* STANDALONE */
#ifdef XP_UNIX
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <unistd.h>
@ -478,7 +479,7 @@ PRInt32 nsZipArchive::OpenArchive(const char * aArchiveName)
return ZIP_ERR_PARAM;
//-- open the physical file
mFd = PR_Open(aArchiveName, PR_RDONLY, 0);
mFd = PR_Open(aArchiveName, PR_RDONLY, 0000);
if (mFd == 0)
return ZIP_ERR_DISK;
@ -656,12 +657,26 @@ PRUint32 nsZipReadState::Available()
PRInt32 nsZipArchive::ExtractFile(const char* zipEntry, const char* aOutname,
PRFileDesc* aFd)
{
PRFileDesc* fOut = PR_Open(aOutname, ZFILE_CREATE, 0644);
//-- Find item in archive
nsZipItem* item = GetFileItem(zipEntry);
if (!item)
return ZIP_ERR_FNF;
// delete any existing file so that we overwrite the file permissions
PR_Delete(aOutname);
PRFileDesc* fOut = PR_Open(aOutname, ZFILE_CREATE, item->mode);
if (fOut == 0)
return ZIP_ERR_DISK;
nsZipItem *item = 0;
PRInt32 status = ExtractFileToFileDesc(zipEntry, fOut, &item, aFd);
#if defined(XP_UNIX) && defined(STANDALONE)
// When STANDALONE is defined, PR_Open ignores its 3d argument.
mode_t msk = umask(0);
umask(msk);
chmod(aOutname, item->mode & ~msk);
#endif
PRInt32 status = ExtractItemToFileDesc(item, fOut, aFd);
PR_Close(fOut);
if (status != ZIP_OK)
@ -673,30 +688,23 @@ PRInt32 nsZipArchive::ExtractFile(const char* zipEntry, const char* aOutname,
{
if (ZIFLAG_SYMLINK & item->flags)
{
status = ResolveSymlink(aOutname,item);
status = ResolveSymlink(aOutname, item);
}
//-- set extracted file permissions
chmod(aOutname, item->mode);
}
#endif
return status;
}
PRInt32
nsZipArchive::ExtractFileToFileDesc(const char * zipEntry, PRFileDesc* outFD,
nsZipItem **outItem, PRFileDesc* aFd)
nsZipArchive::ExtractItemToFileDesc(nsZipItem* item, PRFileDesc* outFD,
PRFileDesc* aFd)
{
//-- sanity check arguments
if (zipEntry == 0 || outFD == 0 || outItem == 0)
if (item == 0 || outFD == 0)
return ZIP_ERR_PARAM;
PRInt32 status;
//-- Find item in archive
nsZipItem* item = GetFileItem(zipEntry);
if (!item)
return ZIP_ERR_FNF;
//-- extract the file using the appropriate method
switch(item->compression)
{
@ -713,7 +721,6 @@ nsZipArchive::ExtractFileToFileDesc(const char * zipEntry, PRFileDesc* outFD,
return ZIP_ERR_UNSUPPORTED;
}
*outItem = item;
return status;
}
@ -833,7 +840,7 @@ PRInt32 nsZipArchive::ResolveSymlink(const char *path, nsZipItem *item)
if (item->flags & ZIFLAG_SYMLINK)
{
char buf[PATH_MAX+1];
PRFileDesc * fIn = PR_Open(path, PR_RDONLY, 0644);
PRFileDesc * fIn = PR_Open(path, PR_RDONLY, 0000);
if (fIn)
{
PRInt32 length = PATH_MAX;

View File

@ -248,8 +248,7 @@ public:
PRInt32 ExtractFile(const char * zipEntry, const char * aOutname,
PRFileDesc* aFd);
PRInt32 ExtractFileToFileDesc(const char * zipEntry, PRFileDesc* outFD,
nsZipItem **outItem,
PRInt32 ExtractItemToFileDesc(nsZipItem* item, PRFileDesc* outFD,
PRFileDesc* aFd);
/**

View File

@ -57,7 +57,7 @@
#define PL_strcpy strcpy
#define PL_strlen strlen
#define PR_Open(a,b,c) fopen((a),(b))
#define PR_Open(a,b,c) fopen((a),(b)) // XXX Ignores mode
#define PR_Read(f,d,n) fread((d),1,(n),(f))
#define PR_Write(f,s,n) fwrite((s),1,(n),(f))
#define PR_Close fclose