mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 525741 - two JAR tests fail if modification date of their files is on day daylight saving time starts or ends and after time change. r=dtownsend,tglek
This commit is contained in:
parent
a090ac8577
commit
a107124c97
@ -259,14 +259,9 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
|
|||||||
}
|
}
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
PRTime prtime = GetModTime(item->Date(), item->Time());
|
|
||||||
// nsIFile needs milliseconds, while prtime is in microseconds.
|
// nsIFile needs milliseconds, while prtime is in microseconds.
|
||||||
PRTime conversion = LL_ZERO;
|
|
||||||
PRTime newTime = LL_ZERO;
|
|
||||||
LL_I2L(conversion, PR_USEC_PER_MSEC);
|
|
||||||
LL_DIV(newTime, prtime, conversion);
|
|
||||||
// non-fatal if this fails, ignore errors
|
// non-fatal if this fails, ignore errors
|
||||||
outFile->SetLastModifiedTime(newTime);
|
outFile->SetLastModifiedTime(item->LastModTime() / PR_USEC_PER_MSEC);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -933,8 +928,7 @@ nsJARItem::nsJARItem(nsZipItem* aZipItem)
|
|||||||
: mSize(aZipItem->Size()),
|
: mSize(aZipItem->Size()),
|
||||||
mRealsize(aZipItem->RealSize()),
|
mRealsize(aZipItem->RealSize()),
|
||||||
mCrc32(aZipItem->CRC32()),
|
mCrc32(aZipItem->CRC32()),
|
||||||
mDate(aZipItem->Date()),
|
mLastModTime(aZipItem->LastModTime()),
|
||||||
mTime(aZipItem->Time()),
|
|
||||||
mCompression(aZipItem->Compression()),
|
mCompression(aZipItem->Compression()),
|
||||||
mIsDirectory(aZipItem->IsDirectory()),
|
mIsDirectory(aZipItem->IsDirectory()),
|
||||||
mIsSynthetic(aZipItem->isSynthetic)
|
mIsSynthetic(aZipItem->isSynthetic)
|
||||||
@ -1021,7 +1015,7 @@ nsJARItem::GetLastModifiedTime(PRTime* aLastModTime)
|
|||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aLastModTime);
|
NS_ENSURE_ARG_POINTER(aLastModTime);
|
||||||
|
|
||||||
*aLastModTime = GetModTime(mDate, mTime);
|
*aLastModTime = mLastModTime;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1267,27 +1261,4 @@ nsZipReaderCache::Observe(nsISupports *aSubject,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRTime GetModTime(PRUint16 aDate, PRUint16 aTime)
|
|
||||||
{
|
|
||||||
PRExplodedTime time;
|
|
||||||
|
|
||||||
time.tm_usec = 0;
|
|
||||||
|
|
||||||
time.tm_hour = (aTime >> 11) & 0x1F;
|
|
||||||
time.tm_min = (aTime >> 5) & 0x3F;
|
|
||||||
time.tm_sec = (aTime & 0x1F) * 2;
|
|
||||||
|
|
||||||
time.tm_year = (aDate >> 9) + 1980;
|
|
||||||
time.tm_month = ((aDate >> 5) & 0x0F)-1;
|
|
||||||
time.tm_mday = aDate & 0x1F;
|
|
||||||
|
|
||||||
time.tm_params.tp_gmt_offset = 0;
|
|
||||||
time.tm_params.tp_dst_offset = 0;
|
|
||||||
|
|
||||||
PR_NormalizeTime(&time, PR_GMTParameters);
|
|
||||||
time.tm_params = PR_LocalTimeParameters(&time);
|
|
||||||
|
|
||||||
return PR_ImplodeTime(&time);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -85,8 +85,6 @@ typedef enum
|
|||||||
JAR_NOT_SIGNED = 7
|
JAR_NOT_SIGNED = 7
|
||||||
} JARManifestStatusType;
|
} JARManifestStatusType;
|
||||||
|
|
||||||
PRTime GetModTime(PRUint16 aDate, PRUint16 aTime);
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
* Class nsJAR declaration.
|
* Class nsJAR declaration.
|
||||||
* nsJAR serves as an XPCOM wrapper for nsZipArchive with the addition of
|
* nsJAR serves as an XPCOM wrapper for nsZipArchive with the addition of
|
||||||
@ -184,8 +182,7 @@ private:
|
|||||||
PRUint32 mSize; /* size in original file */
|
PRUint32 mSize; /* size in original file */
|
||||||
PRUint32 mRealsize; /* inflated size */
|
PRUint32 mRealsize; /* inflated size */
|
||||||
PRUint32 mCrc32;
|
PRUint32 mCrc32;
|
||||||
PRUint16 mDate;
|
PRTime mLastModTime;
|
||||||
PRUint16 mTime;
|
|
||||||
PRUint16 mCompression;
|
PRUint16 mCompression;
|
||||||
PRPackedBool mIsDirectory;
|
PRPackedBool mIsDirectory;
|
||||||
PRPackedBool mIsSynthetic;
|
PRPackedBool mIsSynthetic;
|
||||||
|
@ -346,7 +346,7 @@ nsJARInputStream::ReadDirectory(char* aBuffer, PRUint32 aCount, PRUint32 *aBytes
|
|||||||
|
|
||||||
// Last Modified Time
|
// Last Modified Time
|
||||||
PRExplodedTime tm;
|
PRExplodedTime tm;
|
||||||
PR_ExplodeTime(GetModTime(ze->Date(), ze->Time()), PR_GMTParameters, &tm);
|
PR_ExplodeTime(ze->LastModTime(), PR_GMTParameters, &tm);
|
||||||
char itemLastModTime[65];
|
char itemLastModTime[65];
|
||||||
PR_FormatTimeUSEnglish(itemLastModTime,
|
PR_FormatTimeUSEnglish(itemLastModTime,
|
||||||
sizeof(itemLastModTime),
|
sizeof(itemLastModTime),
|
||||||
|
@ -104,8 +104,8 @@ static const PRUint32 kMaxNameLength = PATH_MAX; /* Maximum name length */
|
|||||||
static const PRUint16 kSyntheticTime = 0;
|
static const PRUint16 kSyntheticTime = 0;
|
||||||
static const PRUint16 kSyntheticDate = (1 + (1 << 5) + (0 << 9));
|
static const PRUint16 kSyntheticDate = (1 + (1 << 5) + (0 << 9));
|
||||||
|
|
||||||
static PRUint16 xtoint(const unsigned char *ii);
|
static PRUint16 xtoint(const PRUint8 *ii);
|
||||||
static PRUint32 xtolong(const unsigned char *ll);
|
static PRUint32 xtolong(const PRUint8 *ll);
|
||||||
static PRUint32 HashName(const char* aName, PRUint16 nameLen);
|
static PRUint32 HashName(const char* aName, PRUint16 nameLen);
|
||||||
#if defined(XP_UNIX) || defined(XP_BEOS)
|
#if defined(XP_UNIX) || defined(XP_BEOS)
|
||||||
static nsresult ResolveSymlink(const char *path);
|
static nsresult ResolveSymlink(const char *path);
|
||||||
@ -848,7 +848,7 @@ static PRUint32 HashName(const char* aName, PRUint16 len)
|
|||||||
* Converts a two byte ugly endianed integer
|
* Converts a two byte ugly endianed integer
|
||||||
* to our platform's integer.
|
* to our platform's integer.
|
||||||
*/
|
*/
|
||||||
static PRUint16 xtoint (const unsigned char *ii)
|
static PRUint16 xtoint (const PRUint8 *ii)
|
||||||
{
|
{
|
||||||
return (PRUint16) ((ii [0]) | (ii [1] << 8));
|
return (PRUint16) ((ii [0]) | (ii [1] << 8));
|
||||||
}
|
}
|
||||||
@ -859,7 +859,7 @@ static PRUint16 xtoint (const unsigned char *ii)
|
|||||||
* Converts a four byte ugly endianed integer
|
* Converts a four byte ugly endianed integer
|
||||||
* to our platform's integer.
|
* to our platform's integer.
|
||||||
*/
|
*/
|
||||||
static PRUint32 xtolong (const unsigned char *ll)
|
static PRUint32 xtolong (const PRUint8 *ll)
|
||||||
{
|
{
|
||||||
return (PRUint32)( (ll [0] << 0) |
|
return (PRUint32)( (ll [0] << 0) |
|
||||||
(ll [1] << 8) |
|
(ll [1] << 8) |
|
||||||
@ -867,56 +867,129 @@ static PRUint32 xtolong (const unsigned char *ll)
|
|||||||
(ll [3] << 24) );
|
(ll [3] << 24) );
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint32 const nsZipItem::LocalOffset()
|
/*
|
||||||
|
* GetModTime
|
||||||
|
*
|
||||||
|
* returns last modification time in microseconds
|
||||||
|
*/
|
||||||
|
static PRTime GetModTime(PRUint16 aDate, PRUint16 aTime)
|
||||||
|
{
|
||||||
|
// Note that on DST shift we can't handle correctly the hour that is valid
|
||||||
|
// in both DST zones
|
||||||
|
PRExplodedTime time;
|
||||||
|
|
||||||
|
time.tm_usec = 0;
|
||||||
|
|
||||||
|
time.tm_hour = (aTime >> 11) & 0x1F;
|
||||||
|
time.tm_min = (aTime >> 5) & 0x3F;
|
||||||
|
time.tm_sec = (aTime & 0x1F) * 2;
|
||||||
|
|
||||||
|
time.tm_year = (aDate >> 9) + 1980;
|
||||||
|
time.tm_month = ((aDate >> 5) & 0x0F) - 1;
|
||||||
|
time.tm_mday = aDate & 0x1F;
|
||||||
|
|
||||||
|
time.tm_params.tp_gmt_offset = 0;
|
||||||
|
time.tm_params.tp_dst_offset = 0;
|
||||||
|
|
||||||
|
PR_NormalizeTime(&time, PR_GMTParameters);
|
||||||
|
time.tm_params.tp_gmt_offset = PR_LocalTimeParameters(&time).tp_gmt_offset;
|
||||||
|
PR_NormalizeTime(&time, PR_GMTParameters);
|
||||||
|
time.tm_params.tp_dst_offset = PR_LocalTimeParameters(&time).tp_dst_offset;
|
||||||
|
|
||||||
|
return PR_ImplodeTime(&time);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32 nsZipItem::LocalOffset()
|
||||||
{
|
{
|
||||||
return xtolong(central->localhdr_offset);
|
return xtolong(central->localhdr_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint32 const nsZipItem::Size()
|
PRUint32 nsZipItem::Size()
|
||||||
{
|
{
|
||||||
return isSynthetic ? 0 : xtolong(central->size);
|
return isSynthetic ? 0 : xtolong(central->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint32 const nsZipItem::RealSize()
|
PRUint32 nsZipItem::RealSize()
|
||||||
{
|
{
|
||||||
return isSynthetic ? 0 : xtolong(central->orglen);
|
return isSynthetic ? 0 : xtolong(central->orglen);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint32 const nsZipItem::CRC32()
|
PRUint32 nsZipItem::CRC32()
|
||||||
{
|
{
|
||||||
return isSynthetic ? 0 : xtolong(central->crc32);
|
return isSynthetic ? 0 : xtolong(central->crc32);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint16 const nsZipItem::Date()
|
PRUint16 nsZipItem::Date()
|
||||||
{
|
{
|
||||||
return isSynthetic ? kSyntheticDate : xtoint(central->date);
|
return isSynthetic ? kSyntheticDate : xtoint(central->date);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint16 const nsZipItem::Time()
|
PRUint16 nsZipItem::Time()
|
||||||
{
|
{
|
||||||
return isSynthetic ? kSyntheticTime : xtoint(central->time);
|
return isSynthetic ? kSyntheticTime : xtoint(central->time);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint16 const nsZipItem::Compression()
|
PRUint16 nsZipItem::Compression()
|
||||||
{
|
{
|
||||||
return isSynthetic ? STORED : xtoint(central->method);
|
return isSynthetic ? STORED : xtoint(central->method);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool const nsZipItem::IsDirectory()
|
bool nsZipItem::IsDirectory()
|
||||||
{
|
{
|
||||||
return isSynthetic || ((nameLength > 0) && ('/' == Name()[nameLength - 1]));
|
return isSynthetic || ((nameLength > 0) && ('/' == Name()[nameLength - 1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint16 const nsZipItem::Mode()
|
PRUint16 nsZipItem::Mode()
|
||||||
{
|
{
|
||||||
if (isSynthetic) return 0755;
|
if (isSynthetic) return 0755;
|
||||||
return ((PRUint16)(central->external_attributes[2]) | 0x100);
|
return ((PRUint16)(central->external_attributes[2]) | 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PRUint8 * nsZipItem::GetExtraField(PRUint16 aTag, PRUint16 *aBlockSize)
|
||||||
|
{
|
||||||
|
if (isSynthetic) return NULL;
|
||||||
|
|
||||||
|
const unsigned char *buf = ((const unsigned char*)central) + ZIPCENTRAL_SIZE +
|
||||||
|
nameLength;
|
||||||
|
PRUint32 buflen = (PRUint32)xtoint(central->extrafield_len);
|
||||||
|
PRUint32 pos = 0;
|
||||||
|
PRUint16 tag, blocksize;
|
||||||
|
|
||||||
|
while (buf && (pos + 4) <= buflen) {
|
||||||
|
tag = xtoint(buf + pos);
|
||||||
|
blocksize = xtoint(buf + pos + 2);
|
||||||
|
|
||||||
|
if (aTag == tag && (pos + 4 + blocksize) <= buflen) {
|
||||||
|
*aBlockSize = blocksize;
|
||||||
|
return buf + pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += blocksize + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRTime nsZipItem::LastModTime()
|
||||||
|
{
|
||||||
|
if (isSynthetic) return GetModTime(kSyntheticDate, kSyntheticTime);
|
||||||
|
|
||||||
|
// Try to read timestamp from extra field
|
||||||
|
PRUint16 blocksize;
|
||||||
|
const PRUint8 *tsField = GetExtraField(EXTENDED_TIMESTAMP_FIELD, &blocksize);
|
||||||
|
if (tsField && blocksize >= 5 && tsField[4] & EXTENDED_TIMESTAMP_MODTIME) {
|
||||||
|
return (PRTime)(xtolong(tsField + 5)) * PR_USEC_PER_SEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetModTime(Date(), Time());
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(XP_UNIX) || defined(XP_BEOS)
|
#if defined(XP_UNIX) || defined(XP_BEOS)
|
||||||
bool const nsZipItem::IsSymlink()
|
bool nsZipItem::IsSymlink()
|
||||||
{
|
{
|
||||||
if (isSynthetic) return false;
|
if (isSynthetic) return false;
|
||||||
return (xtoint(central->external_attributes+2) & S_IFMT) == S_IFLNK;
|
return (xtoint(central->external_attributes+2) & S_IFMT) == S_IFLNK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -83,18 +83,20 @@ class nsZipItem
|
|||||||
public:
|
public:
|
||||||
const char* Name() { return ((const char*)central) + ZIPCENTRAL_SIZE; }
|
const char* Name() { return ((const char*)central) + ZIPCENTRAL_SIZE; }
|
||||||
|
|
||||||
PRUint32 const LocalOffset();
|
PRUint32 LocalOffset();
|
||||||
PRUint32 const Size();
|
PRUint32 Size();
|
||||||
PRUint32 const RealSize();
|
PRUint32 RealSize();
|
||||||
PRUint32 const CRC32();
|
PRUint32 CRC32();
|
||||||
PRUint16 const Date();
|
PRUint16 Date();
|
||||||
PRUint16 const Time();
|
PRUint16 Time();
|
||||||
PRUint16 const Compression();
|
PRUint16 Compression();
|
||||||
bool const IsDirectory();
|
bool IsDirectory();
|
||||||
PRUint16 const Mode();
|
PRUint16 Mode();
|
||||||
|
const PRUint8* GetExtraField(PRUint16 aTag, PRUint16 *aBlockSize);
|
||||||
|
PRTime LastModTime();
|
||||||
|
|
||||||
#if defined(XP_UNIX) || defined(XP_BEOS)
|
#if defined(XP_UNIX) || defined(XP_BEOS)
|
||||||
bool const IsSymlink();
|
bool IsSymlink();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsZipItem* next;
|
nsZipItem* next;
|
||||||
|
@ -7,8 +7,8 @@ const path = "data/test_bug379841.zip";
|
|||||||
const MAX_TIME_DIFF = 2000000;
|
const MAX_TIME_DIFF = 2000000;
|
||||||
|
|
||||||
var ENTRY_NAME = "test";
|
var ENTRY_NAME = "test";
|
||||||
// Actual time of file was 07 May 2007 14:35:49
|
// Actual time of file was 07 May 2007 13:35:49 UTC
|
||||||
var ENTRY_TIME = new Date(2007, 4, 7, 14, 35, 49, 0);
|
var ENTRY_TIME = new Date(Date.UTC(2007, 4, 7, 13, 35, 49, 0));
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
var file = do_get_file(path);
|
var file = do_get_file(path);
|
||||||
|
@ -122,6 +122,10 @@ typedef struct ZipEnd_
|
|||||||
#define CENTRALSIG 0x02014B50l
|
#define CENTRALSIG 0x02014B50l
|
||||||
#define ENDSIG 0x06054B50l
|
#define ENDSIG 0x06054B50l
|
||||||
|
|
||||||
|
/* extra fields */
|
||||||
|
#define EXTENDED_TIMESTAMP_FIELD 0x5455
|
||||||
|
#define EXTENDED_TIMESTAMP_MODTIME 0x01
|
||||||
|
|
||||||
/* compression methods */
|
/* compression methods */
|
||||||
#define STORED 0
|
#define STORED 0
|
||||||
#define SHRUNK 1
|
#define SHRUNK 1
|
||||||
|
@ -50,47 +50,43 @@
|
|||||||
* The off argument, where present, is incremented according to the number of
|
* The off argument, where present, is incremented according to the number of
|
||||||
* bytes consumed from the buffer.
|
* bytes consumed from the buffer.
|
||||||
*/
|
*/
|
||||||
inline NS_HIDDEN_(void) WRITE8(char* buf, PRUint32* off, PRUint8 val)
|
inline NS_HIDDEN_(void) WRITE8(PRUint8* buf, PRUint32* off, PRUint8 val)
|
||||||
{
|
{
|
||||||
buf[(*off)++] = val & 0xff;
|
buf[(*off)++] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NS_HIDDEN_(void) WRITE16(char* buf, PRUint32* off, PRUint16 val)
|
inline NS_HIDDEN_(void) WRITE16(PRUint8* buf, PRUint32* off, PRUint16 val)
|
||||||
{
|
{
|
||||||
buf[(*off)++] = val & 0xff;
|
WRITE8(buf, off, val & 0xff);
|
||||||
buf[(*off)++] = (val >> 8) & 0xff;
|
WRITE8(buf, off, (val >> 8) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NS_HIDDEN_(void) WRITE32(char* buf, PRUint32* off, PRUint32 val)
|
inline NS_HIDDEN_(void) WRITE32(PRUint8* buf, PRUint32* off, PRUint32 val)
|
||||||
{
|
{
|
||||||
buf[(*off)++] = val & 0xff;
|
WRITE16(buf, off, val & 0xffff);
|
||||||
buf[(*off)++] = (val >> 8) & 0xff;
|
WRITE16(buf, off, (val >> 16) & 0xffff);
|
||||||
buf[(*off)++] = (val >> 16) & 0xff;
|
|
||||||
buf[(*off)++] = (val >> 24) & 0xff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NS_HIDDEN_(PRUint8) READ8(char* buf, PRUint32* off)
|
inline NS_HIDDEN_(PRUint8) READ8(const PRUint8* buf, PRUint32* off)
|
||||||
{
|
{
|
||||||
return (PRUint8)buf[(*off)++];
|
return buf[(*off)++];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NS_HIDDEN_(PRUint16) READ16(char* buf, PRUint32* off)
|
inline NS_HIDDEN_(PRUint16) READ16(const PRUint8* buf, PRUint32* off)
|
||||||
{
|
{
|
||||||
PRUint16 val = (PRUint16)buf[(*off)++] & 0xff;
|
PRUint16 val = READ8(buf, off);
|
||||||
val |= ((PRUint16)buf[(*off)++] & 0xff) << 8;
|
val |= READ8(buf, off) << 8;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NS_HIDDEN_(PRUint32) READ32(char* buf, PRUint32* off)
|
inline NS_HIDDEN_(PRUint32) READ32(const PRUint8* buf, PRUint32* off)
|
||||||
{
|
{
|
||||||
PRUint32 val = (PRUint32)buf[(*off)++] & 0xff;
|
PRUint32 val = READ16(buf, off);
|
||||||
val |= ((PRUint32)buf[(*off)++] & 0xff) << 8;
|
val |= READ16(buf, off) << 16;
|
||||||
val |= ((PRUint32)buf[(*off)++] & 0xff) << 16;
|
|
||||||
val |= ((PRUint32)buf[(*off)++] & 0xff) << 24;
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NS_HIDDEN_(PRUint32) PEEK32(unsigned char *buf)
|
inline NS_HIDDEN_(PRUint32) PEEK32(const PRUint8* buf)
|
||||||
{
|
{
|
||||||
return (PRUint32)( (buf [0] ) |
|
return (PRUint32)( (buf [0] ) |
|
||||||
(buf [1] << 8) |
|
(buf [1] << 8) |
|
||||||
|
@ -47,6 +47,9 @@
|
|||||||
|
|
||||||
#define FLAGS_IS_UTF8 0x800
|
#define FLAGS_IS_UTF8 0x800
|
||||||
|
|
||||||
|
#define ZIP_EXTENDED_TIMESTAMP_FIELD 0x5455
|
||||||
|
#define ZIP_EXTENDED_TIMESTAMP_MODTIME 0x01
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nsZipHeader represents an entry from a zip file.
|
* nsZipHeader represents an entry from a zip file.
|
||||||
*/
|
*/
|
||||||
@ -105,11 +108,28 @@ NS_IMETHODIMP nsZipHeader::GetLastModifiedTime(PRTime *aLastModifiedTime)
|
|||||||
{
|
{
|
||||||
NS_ASSERTION(mInited, "Not initalised");
|
NS_ASSERTION(mInited, "Not initalised");
|
||||||
|
|
||||||
|
// Try to read timestamp from extra field
|
||||||
|
PRUint16 blocksize;
|
||||||
|
const PRUint8 *tsField = GetExtraField(ZIP_EXTENDED_TIMESTAMP_FIELD, PR_FALSE, &blocksize);
|
||||||
|
if (tsField && blocksize >= 5) {
|
||||||
|
PRUint32 pos = 4;
|
||||||
|
PRUint8 flags;
|
||||||
|
flags = READ8(tsField, &pos);
|
||||||
|
if (flags & ZIP_EXTENDED_TIMESTAMP_MODTIME) {
|
||||||
|
*aLastModifiedTime = (PRTime)(READ32(tsField, &pos))
|
||||||
|
* PR_USEC_PER_SEC;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use DOS date/time fields
|
||||||
|
// Note that on DST shift we can't handle correctly the hour that is valid
|
||||||
|
// in both DST zones
|
||||||
PRExplodedTime time;
|
PRExplodedTime time;
|
||||||
|
|
||||||
time.tm_usec = 0;
|
time.tm_usec = 0;
|
||||||
|
|
||||||
time.tm_hour = mTime >> 11;
|
time.tm_hour = (mTime >> 11) & 0x1F;
|
||||||
time.tm_min = (mTime >> 5) & 0x3F;
|
time.tm_min = (mTime >> 5) & 0x3F;
|
||||||
time.tm_sec = (mTime & 0x1F) * 2;
|
time.tm_sec = (mTime & 0x1F) * 2;
|
||||||
|
|
||||||
@ -121,7 +141,9 @@ NS_IMETHODIMP nsZipHeader::GetLastModifiedTime(PRTime *aLastModifiedTime)
|
|||||||
time.tm_params.tp_dst_offset = 0;
|
time.tm_params.tp_dst_offset = 0;
|
||||||
|
|
||||||
PR_NormalizeTime(&time, PR_GMTParameters);
|
PR_NormalizeTime(&time, PR_GMTParameters);
|
||||||
time.tm_params = PR_LocalTimeParameters(&time);
|
time.tm_params.tp_gmt_offset = PR_LocalTimeParameters(&time).tp_gmt_offset;
|
||||||
|
PR_NormalizeTime(&time, PR_GMTParameters);
|
||||||
|
time.tm_params.tp_dst_offset = PR_LocalTimeParameters(&time).tp_dst_offset;
|
||||||
|
|
||||||
*aLastModifiedTime = PR_ImplodeTime(&time);
|
*aLastModifiedTime = PR_ImplodeTime(&time);
|
||||||
|
|
||||||
@ -149,6 +171,27 @@ void nsZipHeader::Init(const nsACString & aPath, PRTime aDate, PRUint32 aAttr,
|
|||||||
mDate = time.tm_mday + ((time.tm_month + 1) << 5) +
|
mDate = time.tm_mday + ((time.tm_month + 1) << 5) +
|
||||||
((time.tm_year - 1980) << 9);
|
((time.tm_year - 1980) << 9);
|
||||||
|
|
||||||
|
// Store modification timestamp as extra field
|
||||||
|
// First fill CDS extra field
|
||||||
|
mFieldLength = 9;
|
||||||
|
mExtraField = new PRUint8[mFieldLength];
|
||||||
|
if (!mExtraField) {
|
||||||
|
mFieldLength = 0;
|
||||||
|
} else {
|
||||||
|
PRUint32 pos = 0;
|
||||||
|
WRITE16(mExtraField.get(), &pos, ZIP_EXTENDED_TIMESTAMP_FIELD);
|
||||||
|
WRITE16(mExtraField.get(), &pos, 5);
|
||||||
|
WRITE8(mExtraField.get(), &pos, ZIP_EXTENDED_TIMESTAMP_MODTIME);
|
||||||
|
WRITE32(mExtraField.get(), &pos, aDate / PR_USEC_PER_SEC);
|
||||||
|
|
||||||
|
// Fill local extra field
|
||||||
|
mLocalExtraField = new PRUint8[mFieldLength];
|
||||||
|
if (mLocalExtraField) {
|
||||||
|
mLocalFieldLength = mFieldLength;
|
||||||
|
memcpy(mLocalExtraField.get(), mExtraField.get(), mLocalFieldLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mEAttr = aAttr;
|
mEAttr = aAttr;
|
||||||
mOffset = aOffset;
|
mOffset = aOffset;
|
||||||
mName = aPath;
|
mName = aPath;
|
||||||
@ -160,14 +203,14 @@ void nsZipHeader::Init(const nsACString & aPath, PRTime aDate, PRUint32 aAttr,
|
|||||||
|
|
||||||
PRUint32 nsZipHeader::GetFileHeaderLength()
|
PRUint32 nsZipHeader::GetFileHeaderLength()
|
||||||
{
|
{
|
||||||
return ZIP_FILE_HEADER_SIZE + mName.Length();
|
return ZIP_FILE_HEADER_SIZE + mName.Length() + mLocalFieldLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsZipHeader::WriteFileHeader(nsIOutputStream *aStream)
|
nsresult nsZipHeader::WriteFileHeader(nsIOutputStream *aStream)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mInited, "Not initalised");
|
NS_ASSERTION(mInited, "Not initalised");
|
||||||
|
|
||||||
char buf[ZIP_FILE_HEADER_SIZE];
|
PRUint8 buf[ZIP_FILE_HEADER_SIZE];
|
||||||
PRUint32 pos = 0;
|
PRUint32 pos = 0;
|
||||||
WRITE32(buf, &pos, ZIP_FILE_HEADER_SIGNATURE);
|
WRITE32(buf, &pos, ZIP_FILE_HEADER_SIGNATURE);
|
||||||
WRITE16(buf, &pos, mVersionNeeded);
|
WRITE16(buf, &pos, mVersionNeeded);
|
||||||
@ -179,12 +222,21 @@ nsresult nsZipHeader::WriteFileHeader(nsIOutputStream *aStream)
|
|||||||
WRITE32(buf, &pos, mCSize);
|
WRITE32(buf, &pos, mCSize);
|
||||||
WRITE32(buf, &pos, mUSize);
|
WRITE32(buf, &pos, mUSize);
|
||||||
WRITE16(buf, &pos, mName.Length());
|
WRITE16(buf, &pos, mName.Length());
|
||||||
WRITE16(buf, &pos, 0);
|
WRITE16(buf, &pos, mLocalFieldLength);
|
||||||
|
|
||||||
nsresult rv = ZW_WriteData(aStream, buf, pos);
|
nsresult rv = ZW_WriteData(aStream, (const char *)buf, pos);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return ZW_WriteData(aStream, mName.get(), mName.Length());
|
rv = ZW_WriteData(aStream, mName.get(), mName.Length());
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (mLocalFieldLength)
|
||||||
|
{
|
||||||
|
rv = ZW_WriteData(aStream, (const char *)mLocalExtraField.get(), mLocalFieldLength);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint32 nsZipHeader::GetCDSHeaderLength()
|
PRUint32 nsZipHeader::GetCDSHeaderLength()
|
||||||
@ -197,7 +249,7 @@ nsresult nsZipHeader::WriteCDSHeader(nsIOutputStream *aStream)
|
|||||||
{
|
{
|
||||||
NS_ASSERTION(mInited, "Not initalised");
|
NS_ASSERTION(mInited, "Not initalised");
|
||||||
|
|
||||||
char buf[ZIP_CDS_HEADER_SIZE];
|
PRUint8 buf[ZIP_CDS_HEADER_SIZE];
|
||||||
PRUint32 pos = 0;
|
PRUint32 pos = 0;
|
||||||
WRITE32(buf, &pos, ZIP_CDS_HEADER_SIGNATURE);
|
WRITE32(buf, &pos, ZIP_CDS_HEADER_SIGNATURE);
|
||||||
WRITE16(buf, &pos, mVersionMade);
|
WRITE16(buf, &pos, mVersionMade);
|
||||||
@ -217,13 +269,13 @@ nsresult nsZipHeader::WriteCDSHeader(nsIOutputStream *aStream)
|
|||||||
WRITE32(buf, &pos, mEAttr);
|
WRITE32(buf, &pos, mEAttr);
|
||||||
WRITE32(buf, &pos, mOffset);
|
WRITE32(buf, &pos, mOffset);
|
||||||
|
|
||||||
nsresult rv = ZW_WriteData(aStream, buf, pos);
|
nsresult rv = ZW_WriteData(aStream, (const char *)buf, pos);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = ZW_WriteData(aStream, mName.get(), mName.Length());
|
rv = ZW_WriteData(aStream, mName.get(), mName.Length());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (mExtraField) {
|
if (mExtraField) {
|
||||||
rv = ZW_WriteData(aStream, mExtraField, mFieldLength);
|
rv = ZW_WriteData(aStream, (const char *)mExtraField.get(), mFieldLength);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
return ZW_WriteData(aStream, mComment.get(), mComment.Length());
|
return ZW_WriteData(aStream, mComment.get(), mComment.Length());
|
||||||
@ -233,9 +285,9 @@ nsresult nsZipHeader::ReadCDSHeader(nsIInputStream *stream)
|
|||||||
{
|
{
|
||||||
NS_ASSERTION(!mInited, "Already initalised");
|
NS_ASSERTION(!mInited, "Already initalised");
|
||||||
|
|
||||||
char buf[ZIP_CDS_HEADER_SIZE];
|
PRUint8 buf[ZIP_CDS_HEADER_SIZE];
|
||||||
|
|
||||||
nsresult rv = ZW_ReadData(stream, buf, ZIP_CDS_HEADER_SIZE);
|
nsresult rv = ZW_ReadData(stream, (char *)buf, ZIP_CDS_HEADER_SIZE);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
PRUint32 pos = 0;
|
PRUint32 pos = 0;
|
||||||
@ -271,9 +323,9 @@ nsresult nsZipHeader::ReadCDSHeader(nsIInputStream *stream)
|
|||||||
mName = NS_LITERAL_CSTRING("");
|
mName = NS_LITERAL_CSTRING("");
|
||||||
|
|
||||||
if (mFieldLength > 0) {
|
if (mFieldLength > 0) {
|
||||||
mExtraField = new char[mFieldLength];
|
mExtraField = new PRUint8[mFieldLength];
|
||||||
NS_ENSURE_TRUE(mExtraField, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(mExtraField, NS_ERROR_OUT_OF_MEMORY);
|
||||||
rv = ZW_ReadData(stream, mExtraField.get(), mFieldLength);
|
rv = ZW_ReadData(stream, (char *)mExtraField.get(), mFieldLength);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,3 +342,25 @@ nsresult nsZipHeader::ReadCDSHeader(nsIInputStream *stream)
|
|||||||
mInited = PR_TRUE;
|
mInited = PR_TRUE;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PRUint8 * nsZipHeader::GetExtraField(PRUint16 aTag, PRBool aLocal, PRUint16 *aBlockSize)
|
||||||
|
{
|
||||||
|
const PRUint8 *buf = aLocal ? mLocalExtraField : mExtraField;
|
||||||
|
PRUint32 buflen = aLocal ? mLocalFieldLength : mFieldLength;
|
||||||
|
PRUint32 pos = 0;
|
||||||
|
PRUint16 tag, blocksize;
|
||||||
|
|
||||||
|
while (buf && (pos + 4) <= buflen) {
|
||||||
|
tag = READ16(buf, &pos);
|
||||||
|
blocksize = READ16(buf, &pos);
|
||||||
|
|
||||||
|
if (aTag == tag && (pos + blocksize) <= buflen) {
|
||||||
|
*aBlockSize = blocksize;
|
||||||
|
return buf + pos - 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -68,6 +68,7 @@ public:
|
|||||||
mEAttr(0),
|
mEAttr(0),
|
||||||
mOffset(0),
|
mOffset(0),
|
||||||
mFieldLength(0),
|
mFieldLength(0),
|
||||||
|
mLocalFieldLength(0),
|
||||||
mVersionMade(0x0300 + 23), // Generated on Unix by v2.3 (matches infozip)
|
mVersionMade(0x0300 + 23), // Generated on Unix by v2.3 (matches infozip)
|
||||||
mVersionNeeded(20), // Requires v2.0 to extract
|
mVersionNeeded(20), // Requires v2.0 to extract
|
||||||
mFlags(0),
|
mFlags(0),
|
||||||
@ -77,13 +78,15 @@ public:
|
|||||||
mDisk(0),
|
mDisk(0),
|
||||||
mIAttr(0),
|
mIAttr(0),
|
||||||
mInited(PR_FALSE),
|
mInited(PR_FALSE),
|
||||||
mExtraField(NULL)
|
mExtraField(NULL),
|
||||||
|
mLocalExtraField(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~nsZipHeader()
|
~nsZipHeader()
|
||||||
{
|
{
|
||||||
mExtraField = NULL;
|
mExtraField = NULL;
|
||||||
|
mLocalExtraField = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRUint32 mCRC;
|
PRUint32 mCRC;
|
||||||
@ -92,6 +95,7 @@ public:
|
|||||||
PRUint32 mEAttr;
|
PRUint32 mEAttr;
|
||||||
PRUint32 mOffset;
|
PRUint32 mOffset;
|
||||||
PRUint32 mFieldLength;
|
PRUint32 mFieldLength;
|
||||||
|
PRUint32 mLocalFieldLength;
|
||||||
PRUint16 mVersionMade;
|
PRUint16 mVersionMade;
|
||||||
PRUint16 mVersionNeeded;
|
PRUint16 mVersionNeeded;
|
||||||
PRUint16 mFlags;
|
PRUint16 mFlags;
|
||||||
@ -103,7 +107,8 @@ public:
|
|||||||
PRPackedBool mInited;
|
PRPackedBool mInited;
|
||||||
nsCString mName;
|
nsCString mName;
|
||||||
nsCString mComment;
|
nsCString mComment;
|
||||||
nsAutoArrayPtr<char> mExtraField;
|
nsAutoArrayPtr<PRUint8> mExtraField;
|
||||||
|
nsAutoArrayPtr<PRUint8> mLocalExtraField;
|
||||||
|
|
||||||
void Init(const nsACString & aPath, PRTime aDate, PRUint32 aAttr,
|
void Init(const nsACString & aPath, PRTime aDate, PRUint32 aAttr,
|
||||||
PRUint32 aOffset);
|
PRUint32 aOffset);
|
||||||
@ -112,6 +117,7 @@ public:
|
|||||||
PRUint32 GetCDSHeaderLength();
|
PRUint32 GetCDSHeaderLength();
|
||||||
nsresult WriteCDSHeader(nsIOutputStream *aStream);
|
nsresult WriteCDSHeader(nsIOutputStream *aStream);
|
||||||
nsresult ReadCDSHeader(nsIInputStream *aStream);
|
nsresult ReadCDSHeader(nsIInputStream *aStream);
|
||||||
|
const PRUint8 * GetExtraField(PRUint16 aTag, PRBool aLocal, PRUint16 *aBlockSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -147,7 +147,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
|
|||||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), aFile);
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), aFile);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
char buf[1024];
|
PRUint8 buf[1024];
|
||||||
PRInt64 seek = size - 1024;
|
PRInt64 seek = size - 1024;
|
||||||
PRUint32 length = 1024;
|
PRUint32 length = 1024;
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
|
|||||||
inputStream->Close();
|
inputStream->Close();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
rv = ZW_ReadData(inputStream, buf, length);
|
rv = ZW_ReadData(inputStream, (char *)buf, length);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
inputStream->Close();
|
inputStream->Close();
|
||||||
return rv;
|
return rv;
|
||||||
@ -177,7 +177,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
|
|||||||
// We know it's at least this far from the end
|
// We know it's at least this far from the end
|
||||||
for (PRUint32 pos = length - ZIP_EOCDR_HEADER_SIZE;
|
for (PRUint32 pos = length - ZIP_EOCDR_HEADER_SIZE;
|
||||||
(PRInt32)pos >= 0; pos--) {
|
(PRInt32)pos >= 0; pos--) {
|
||||||
PRUint32 sig = PEEK32((unsigned char *)buf + pos);
|
PRUint32 sig = PEEK32(buf + pos);
|
||||||
if (sig == ZIP_EOCDR_HEADER_SIGNATURE) {
|
if (sig == ZIP_EOCDR_HEADER_SIGNATURE) {
|
||||||
// Skip down to entry count
|
// Skip down to entry count
|
||||||
pos += 10;
|
pos += 10;
|
||||||
@ -190,7 +190,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
|
|||||||
if (commentlen == 0)
|
if (commentlen == 0)
|
||||||
mComment.Truncate();
|
mComment.Truncate();
|
||||||
else if (pos + commentlen <= length)
|
else if (pos + commentlen <= length)
|
||||||
mComment.Assign(buf + pos, commentlen);
|
mComment.Assign((const char *)buf + pos, commentlen);
|
||||||
else {
|
else {
|
||||||
if ((seek + pos + commentlen) > size) {
|
if ((seek + pos + commentlen) > size) {
|
||||||
inputStream->Close();
|
inputStream->Close();
|
||||||
@ -682,7 +682,7 @@ NS_IMETHODIMP nsZipWriter::Close()
|
|||||||
size += mHeaders[i]->GetCDSHeaderLength();
|
size += mHeaders[i]->GetCDSHeaderLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[ZIP_EOCDR_HEADER_SIZE];
|
PRUint8 buf[ZIP_EOCDR_HEADER_SIZE];
|
||||||
PRUint32 pos = 0;
|
PRUint32 pos = 0;
|
||||||
WRITE32(buf, &pos, ZIP_EOCDR_HEADER_SIGNATURE);
|
WRITE32(buf, &pos, ZIP_EOCDR_HEADER_SIGNATURE);
|
||||||
WRITE16(buf, &pos, 0);
|
WRITE16(buf, &pos, 0);
|
||||||
@ -693,7 +693,7 @@ NS_IMETHODIMP nsZipWriter::Close()
|
|||||||
WRITE32(buf, &pos, mCDSOffset);
|
WRITE32(buf, &pos, mCDSOffset);
|
||||||
WRITE16(buf, &pos, mComment.Length());
|
WRITE16(buf, &pos, mComment.Length());
|
||||||
|
|
||||||
nsresult rv = ZW_WriteData(mStream, buf, pos);
|
nsresult rv = ZW_WriteData(mStream, (const char *)buf, pos);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
Cleanup();
|
Cleanup();
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -55,12 +55,10 @@ const ZIP_FILE_HEADER_SIZE = 30;
|
|||||||
const ZIP_CDS_HEADER_SIZE = 46;
|
const ZIP_CDS_HEADER_SIZE = 46;
|
||||||
const ZIP_METHOD_STORE = 0
|
const ZIP_METHOD_STORE = 0
|
||||||
const ZIP_METHOD_DEFLATE = 8
|
const ZIP_METHOD_DEFLATE = 8
|
||||||
|
const ZIP_EXTENDED_TIMESTAMP_SIZE = 9;
|
||||||
|
|
||||||
const PR_USEC_PER_MSEC = 1000;
|
const PR_USEC_PER_MSEC = 1000;
|
||||||
|
|
||||||
// ZIP times are stored at a 2 second resolution.
|
|
||||||
const TIME_RESOLUTION = 2000;
|
|
||||||
|
|
||||||
const DATA_DIR = "data/";
|
const DATA_DIR = "data/";
|
||||||
|
|
||||||
var ZipWriter = Components.Constructor("@mozilla.org/zipwriter;1",
|
var ZipWriter = Components.Constructor("@mozilla.org/zipwriter;1",
|
||||||
|
@ -77,11 +77,8 @@ var observer = {
|
|||||||
do_check_eq(entry.realSize, TESTS[i].size);
|
do_check_eq(entry.realSize, TESTS[i].size);
|
||||||
do_check_eq(entry.size, TESTS[i].size);
|
do_check_eq(entry.size, TESTS[i].size);
|
||||||
do_check_eq(entry.CRC32, TESTS[i].crc);
|
do_check_eq(entry.CRC32, TESTS[i].crc);
|
||||||
|
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC,
|
||||||
var diff = Math.abs((entry.lastModifiedTime/PR_USEC_PER_MSEC) -
|
|
||||||
source.lastModifiedTime);
|
source.lastModifiedTime);
|
||||||
if (diff > TIME_RESOLUTION)
|
|
||||||
do_throw(diff);
|
|
||||||
|
|
||||||
zipR.test(TESTS[i].name);
|
zipR.test(TESTS[i].name);
|
||||||
}
|
}
|
||||||
@ -100,6 +97,7 @@ function run_test()
|
|||||||
zipW.addEntryFile(TESTS[i].name, Ci.nsIZipWriter.COMPRESSION_NONE, source,
|
zipW.addEntryFile(TESTS[i].name, Ci.nsIZipWriter.COMPRESSION_NONE, source,
|
||||||
true);
|
true);
|
||||||
size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
|
size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
|
||||||
|
(ZIP_EXTENDED_TIMESTAMP_SIZE * 2) +
|
||||||
(TESTS[i].name.length*2) + TESTS[i].size;
|
(TESTS[i].name.length*2) + TESTS[i].size;
|
||||||
}
|
}
|
||||||
do_test_pending();
|
do_test_pending();
|
||||||
|
@ -55,9 +55,7 @@ function testpass(source)
|
|||||||
// Should be stored
|
// Should be stored
|
||||||
do_check_eq(entry.compression, ZIP_METHOD_DEFLATE);
|
do_check_eq(entry.compression, ZIP_METHOD_DEFLATE);
|
||||||
|
|
||||||
var diff = Math.abs((entry.lastModifiedTime / PR_USEC_PER_MSEC) - time);
|
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, time);
|
||||||
if (diff > TIME_RESOLUTION)
|
|
||||||
do_throw(diff);
|
|
||||||
|
|
||||||
// File size should match our data size.
|
// File size should match our data size.
|
||||||
do_check_eq(entry.realSize, DATA.length);
|
do_check_eq(entry.realSize, DATA.length);
|
||||||
|
@ -57,6 +57,8 @@ function run_test()
|
|||||||
|
|
||||||
// Adding the directory would have added a fixed amount to the file size.
|
// Adding the directory would have added a fixed amount to the file size.
|
||||||
// Any difference suggests the CDS was written out incorrectly.
|
// Any difference suggests the CDS was written out incorrectly.
|
||||||
var extra = ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE + (DIRNAME.length * 2);
|
var extra = ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
|
||||||
|
(DIRNAME.length * 2) + (ZIP_EXTENDED_TIMESTAMP_SIZE * 2);
|
||||||
|
|
||||||
do_check_eq(source.fileSize + extra, tmpFile.fileSize);
|
do_check_eq(source.fileSize + extra, tmpFile.fileSize);
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,7 @@ function run_test()
|
|||||||
do_check_eq(entry.compression, ZIP_METHOD_DEFLATE);
|
do_check_eq(entry.compression, ZIP_METHOD_DEFLATE);
|
||||||
do_check_eq(entry.CRC32, CRC);
|
do_check_eq(entry.CRC32, CRC);
|
||||||
do_check_eq(entry.realSize, DATA.length);
|
do_check_eq(entry.realSize, DATA.length);
|
||||||
var diff = Math.abs((entry.lastModifiedTime/PR_USEC_PER_MSEC) - time);
|
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, time);
|
||||||
if (diff > TIME_RESOLUTION)
|
|
||||||
do_throw(diff);
|
|
||||||
|
|
||||||
zipW.close();
|
zipW.close();
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@ var TESTS = [
|
|||||||
name: "test.txt",
|
name: "test.txt",
|
||||||
size: 232,
|
size: 232,
|
||||||
crc: 0x0373ac26,
|
crc: 0x0373ac26,
|
||||||
time: new Date(2007, 4, 1, 21, 44, 56)
|
time: Date.UTC(2007, 4, 1, 20, 44, 55)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "test.png",
|
name: "test.png",
|
||||||
size: 3402,
|
size: 3402,
|
||||||
crc: 0x504a5c30,
|
crc: 0x504a5c30,
|
||||||
time: new Date(2007, 4, 1, 21, 49, 40)
|
time: Date.UTC(2007, 4, 1, 20, 49, 39)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
var BADENTRY = "unknown.txt";
|
var BADENTRY = "unknown.txt";
|
||||||
@ -70,10 +70,7 @@ function run_test()
|
|||||||
|
|
||||||
do_check_eq(entry.realSize, TESTS[i].size);
|
do_check_eq(entry.realSize, TESTS[i].size);
|
||||||
do_check_eq(entry.CRC32, TESTS[i].crc);
|
do_check_eq(entry.CRC32, TESTS[i].crc);
|
||||||
var diff = Math.abs(TESTS[i].time -
|
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, TESTS[i].time);
|
||||||
(entry.lastModifiedTime / PR_USEC_PER_MSEC));
|
|
||||||
if (diff > TIME_RESOLUTION)
|
|
||||||
do_throw(diff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -56,9 +56,7 @@ function testpass(source)
|
|||||||
// Should be stored
|
// Should be stored
|
||||||
do_check_eq(entry.compression, ZIP_METHOD_STORE);
|
do_check_eq(entry.compression, ZIP_METHOD_STORE);
|
||||||
|
|
||||||
var diff = Math.abs((entry.lastModifiedTime / PR_USEC_PER_MSEC) - time);
|
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, time);
|
||||||
if (diff > TIME_RESOLUTION)
|
|
||||||
do_throw(diff);
|
|
||||||
|
|
||||||
// File size should match our data size.
|
// File size should match our data size.
|
||||||
do_check_eq(entry.realSize, DATA.length);
|
do_check_eq(entry.realSize, DATA.length);
|
||||||
@ -90,6 +88,7 @@ function run_test()
|
|||||||
|
|
||||||
do_check_eq(tmpFile.fileSize,
|
do_check_eq(tmpFile.fileSize,
|
||||||
DATA.length + ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
|
DATA.length + ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
|
||||||
|
(ZIP_EXTENDED_TIMESTAMP_SIZE * 2) +
|
||||||
(FILENAME.length * 2) + ZIP_EOCDR_HEADER_SIZE);
|
(FILENAME.length * 2) + ZIP_EOCDR_HEADER_SIZE);
|
||||||
|
|
||||||
// Check to see if we get the same results loading afresh.
|
// Check to see if we get the same results loading afresh.
|
||||||
|
@ -60,6 +60,7 @@ function run_test()
|
|||||||
zipW.addEntryFile(TESTS[i].name, Ci.nsIZipWriter.COMPRESSION_NONE, source,
|
zipW.addEntryFile(TESTS[i].name, Ci.nsIZipWriter.COMPRESSION_NONE, source,
|
||||||
false);
|
false);
|
||||||
size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
|
size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
|
||||||
|
(ZIP_EXTENDED_TIMESTAMP_SIZE * 2) +
|
||||||
(TESTS[i].name.length*2) + TESTS[i].size;
|
(TESTS[i].name.length*2) + TESTS[i].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,11 +80,8 @@ function run_test()
|
|||||||
do_check_eq(entry.realSize, TESTS[i].size);
|
do_check_eq(entry.realSize, TESTS[i].size);
|
||||||
do_check_eq(entry.size, TESTS[i].size);
|
do_check_eq(entry.size, TESTS[i].size);
|
||||||
do_check_eq(entry.CRC32, TESTS[i].crc);
|
do_check_eq(entry.CRC32, TESTS[i].crc);
|
||||||
|
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC,
|
||||||
var diff = Math.abs((entry.lastModifiedTime/PR_USEC_PER_MSEC) -
|
|
||||||
source.lastModifiedTime);
|
source.lastModifiedTime);
|
||||||
if (diff > TIME_RESOLUTION)
|
|
||||||
do_throw(diff);
|
|
||||||
|
|
||||||
zipR.test(TESTS[i].name);
|
zipR.test(TESTS[i].name);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user