зеркало из https://github.com/mozilla/pjs.git
Fix bug 109157, nsZipArchive::BuildFileList footprint reduction
R=dp, SR=dveditz,alecf
This commit is contained in:
Родитель
ab98515b2d
Коммит
1de419dbb5
|
@ -1044,7 +1044,7 @@ nsJARItem::GetName(char * *aName)
|
|||
if ( !mZipItem->name )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
namedup = PL_strndup( mZipItem->name, mZipItem->namelen );
|
||||
namedup = PL_strdup( mZipItem->name );
|
||||
if ( !namedup )
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
|
|
@ -277,7 +277,9 @@ PR_PUBLIC_API(PRInt32) ZIP_FindNext( void* hFind, char * outbuf, PRUint16 bufsiz
|
|||
status = find->GetArchive()->FindNext( find, &item );
|
||||
if ( status == ZIP_OK )
|
||||
{
|
||||
if ( bufsize > item->namelen )
|
||||
PRUint16 namelen = (PRUint16)PL_strlen(item->name);
|
||||
|
||||
if ( bufsize > namelen )
|
||||
{
|
||||
PL_strcpy( outbuf, item->name );
|
||||
}
|
||||
|
@ -571,7 +573,7 @@ PRInt32 nsZipArchive::ExtractFile(const char* zipEntry, const char* aOutname)
|
|||
#if defined(XP_UNIX)
|
||||
else
|
||||
{
|
||||
if (item->isSymlink)
|
||||
if (ZIFLAG_SYMLINK & item-flags)
|
||||
{
|
||||
status = ResolveSymlink(aOutname,item);
|
||||
}
|
||||
|
@ -731,7 +733,7 @@ PRInt32 nsZipArchive::FindFree( nsZipFind* aFind )
|
|||
PRInt32 nsZipArchive::ResolveSymlink(const char *path, nsZipItem *item)
|
||||
{
|
||||
PRInt32 status = ZIP_OK;
|
||||
if (item->isSymlink)
|
||||
if (item->flags & ZIFLAG_SYMLINK)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
PRFileDesc * fIn = PR_Open(path, PR_RDONLY, 0644);
|
||||
|
@ -891,15 +893,23 @@ PRInt32 nsZipArchive::BuildFileList()
|
|||
break;
|
||||
}
|
||||
|
||||
item->namelen = namelen;
|
||||
item->headerloc = xtolong( central->localhdr_offset );
|
||||
item->compression = xtoint( central->method );
|
||||
item->offset = xtolong( central->localhdr_offset );
|
||||
item->compression = (PRUint8)xtoint( central->method );
|
||||
#if defined(DEBUG)
|
||||
/*
|
||||
* Make sure our space optimization is non lossy.
|
||||
*/
|
||||
PR_ASSERT(xtoint(central->method) == (PRUint16)item->compression);
|
||||
#endif
|
||||
item->size = xtolong( central->size );
|
||||
item->realsize = xtolong( central->orglen );
|
||||
item->crc32 = xtolong( central->crc32 );
|
||||
PRUint32 external_attributes = xtolong( central->external_attributes );
|
||||
item->mode = ExtractMode( external_attributes );
|
||||
item->isSymlink = IsSymlink( external_attributes );
|
||||
if ( IsSymlink( external_attributes ) )
|
||||
{
|
||||
item->flags |= ZIFLAG_SYMLINK;
|
||||
}
|
||||
item->time = xtoint( central->time );
|
||||
item->date = xtoint( central->date );
|
||||
|
||||
|
@ -1021,26 +1031,30 @@ PRInt32 nsZipArchive::SeekToItem(const nsZipItem* aItem)
|
|||
PR_ASSERT (aItem);
|
||||
|
||||
//-- the first time an item is used we need to calculate its offset
|
||||
if ( aItem->offset == 0 )
|
||||
if ( !(aItem->flags & ZIFLAG_DATAOFFSET) )
|
||||
{
|
||||
//-- read local header to extract local extralen
|
||||
//-- aItem->offset contains the header offset, not the data offset.
|
||||
//-- read local header to get variable length values and calculate
|
||||
//-- the real data offset
|
||||
//--
|
||||
//-- NOTE: extralen is different in central header and local header
|
||||
//-- for archives created using the Unix "zip" utility. To set
|
||||
//-- the offset accurately we need the local extralen.
|
||||
if ( !ZIP_Seek( mFd, aItem->headerloc, PR_SEEK_SET ) )
|
||||
//-- the offset accurately we need the _local_ extralen.
|
||||
if ( !ZIP_Seek( mFd, aItem->offset, PR_SEEK_SET ) )
|
||||
return ZIP_ERR_CORRUPT;
|
||||
|
||||
|
||||
ZipLocal Local;
|
||||
if ( PR_Read(mFd, (char*)&Local, sizeof(ZipLocal)) != (READTYPE)sizeof(ZipLocal)
|
||||
|| xtolong( Local.signature ) != LOCALSIG )
|
||||
{
|
||||
{
|
||||
//-- read error or local header not found
|
||||
return ZIP_ERR_CORRUPT;
|
||||
}
|
||||
|
||||
((nsZipItem*)aItem)->offset = aItem->headerloc + sizeof(Local) +
|
||||
xtoint( Local.filename_len ) +
|
||||
xtoint( Local.extrafield_len );
|
||||
((nsZipItem*)aItem)->offset += sizeof(Local) +
|
||||
xtoint( Local.filename_len ) +
|
||||
xtoint( Local.extrafield_len );
|
||||
((nsZipItem*)aItem)->flags |= ZIFLAG_DATAOFFSET;
|
||||
}
|
||||
|
||||
//-- move to start of file in archive
|
||||
|
@ -1497,7 +1511,7 @@ nsZipArchive::~nsZipArchive()
|
|||
|
||||
MOZ_DECL_CTOR_COUNTER(nsZipItem)
|
||||
|
||||
nsZipItem::nsZipItem() : name(0), offset(0), next(0)
|
||||
nsZipItem::nsZipItem() : name(0), offset(0), next(0), flags(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsZipItem);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
#define ZIP_Seek(fd,p,m) (PR_Seek((fd),(p),(m))==(p))
|
||||
#endif
|
||||
|
||||
#define ZIFLAG_SYMLINK 0x01 /* zip item is a symlink */
|
||||
#define ZIFLAG_DATAOFFSET 0x02 /* zip item offset points to file data */
|
||||
|
||||
class nsZipFind;
|
||||
class nsZipRead;
|
||||
class nsZipItemMetadata;
|
||||
|
@ -54,21 +57,27 @@ class nsZipItemMetadata;
|
|||
class nsZipItem
|
||||
{
|
||||
public:
|
||||
char* name;
|
||||
PRUint32 namelen;
|
||||
char* name; /* '\0' terminated */
|
||||
|
||||
PRUint32 offset;
|
||||
PRUint32 headerloc;
|
||||
PRUint16 compression;
|
||||
PRUint32 size;
|
||||
PRUint32 realsize;
|
||||
PRUint32 crc32;
|
||||
|
||||
nsZipItem* next;
|
||||
|
||||
/*
|
||||
* Keep small items together, to avoid overhead.
|
||||
*/
|
||||
PRUint16 mode;
|
||||
PRUint16 time;
|
||||
PRUint16 date;
|
||||
PRBool isSymlink;
|
||||
|
||||
nsZipItem* next;
|
||||
/*
|
||||
* Keep small items together, to avoid overhead.
|
||||
*/
|
||||
PRUint8 compression;
|
||||
PRUint8 flags;
|
||||
|
||||
/**
|
||||
* GetModTime
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define PL_strcmp strcmp
|
||||
#define PL_strdup strdup
|
||||
#define PL_strcpy strcpy
|
||||
#define PL_strlen strlen
|
||||
|
||||
#define PR_Open(a,b,c) fopen((a),(b))
|
||||
#define PR_Read(f,d,n) fread((d),1,(n),(f))
|
||||
|
@ -76,6 +77,7 @@ typedef short PRInt16;
|
|||
typedef unsigned short PRUint16;
|
||||
typedef char PRBool;
|
||||
typedef unsigned char PRUint8;
|
||||
typedef PRUint8 PRPackedBool;
|
||||
|
||||
#define PR_TRUE 1
|
||||
#define PR_FALSE 0
|
||||
|
|
Загрузка…
Ссылка в новой задаче