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:
Michal Novotny 2009-12-16 00:01:08 +01:00
parent a090ac8577
commit a107124c97
19 changed files with 246 additions and 135 deletions

View File

@ -259,14 +259,9 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
}
if (NS_FAILED(rv)) return rv;
PRTime prtime = GetModTime(item->Date(), item->Time());
// 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
outFile->SetLastModifiedTime(newTime);
outFile->SetLastModifiedTime(item->LastModTime() / PR_USEC_PER_MSEC);
return NS_OK;
}
@ -933,8 +928,7 @@ nsJARItem::nsJARItem(nsZipItem* aZipItem)
: mSize(aZipItem->Size()),
mRealsize(aZipItem->RealSize()),
mCrc32(aZipItem->CRC32()),
mDate(aZipItem->Date()),
mTime(aZipItem->Time()),
mLastModTime(aZipItem->LastModTime()),
mCompression(aZipItem->Compression()),
mIsDirectory(aZipItem->IsDirectory()),
mIsSynthetic(aZipItem->isSynthetic)
@ -1021,7 +1015,7 @@ nsJARItem::GetLastModifiedTime(PRTime* aLastModTime)
{
NS_ENSURE_ARG_POINTER(aLastModTime);
*aLastModTime = GetModTime(mDate, mTime);
*aLastModTime = mLastModTime;
return NS_OK;
}
@ -1267,27 +1261,4 @@ nsZipReaderCache::Observe(nsISupports *aSubject,
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);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -85,8 +85,6 @@ typedef enum
JAR_NOT_SIGNED = 7
} JARManifestStatusType;
PRTime GetModTime(PRUint16 aDate, PRUint16 aTime);
/*-------------------------------------------------------------------------
* Class nsJAR declaration.
* nsJAR serves as an XPCOM wrapper for nsZipArchive with the addition of
@ -184,8 +182,7 @@ private:
PRUint32 mSize; /* size in original file */
PRUint32 mRealsize; /* inflated size */
PRUint32 mCrc32;
PRUint16 mDate;
PRUint16 mTime;
PRTime mLastModTime;
PRUint16 mCompression;
PRPackedBool mIsDirectory;
PRPackedBool mIsSynthetic;

View File

@ -346,7 +346,7 @@ nsJARInputStream::ReadDirectory(char* aBuffer, PRUint32 aCount, PRUint32 *aBytes
// Last Modified Time
PRExplodedTime tm;
PR_ExplodeTime(GetModTime(ze->Date(), ze->Time()), PR_GMTParameters, &tm);
PR_ExplodeTime(ze->LastModTime(), PR_GMTParameters, &tm);
char itemLastModTime[65];
PR_FormatTimeUSEnglish(itemLastModTime,
sizeof(itemLastModTime),

View File

@ -104,8 +104,8 @@ static const PRUint32 kMaxNameLength = PATH_MAX; /* Maximum name length */
static const PRUint16 kSyntheticTime = 0;
static const PRUint16 kSyntheticDate = (1 + (1 << 5) + (0 << 9));
static PRUint16 xtoint(const unsigned char *ii);
static PRUint32 xtolong(const unsigned char *ll);
static PRUint16 xtoint(const PRUint8 *ii);
static PRUint32 xtolong(const PRUint8 *ll);
static PRUint32 HashName(const char* aName, PRUint16 nameLen);
#if defined(XP_UNIX) || defined(XP_BEOS)
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
* 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));
}
@ -859,7 +859,7 @@ static PRUint16 xtoint (const unsigned char *ii)
* Converts a four byte ugly endianed integer
* to our platform's integer.
*/
static PRUint32 xtolong (const unsigned char *ll)
static PRUint32 xtolong (const PRUint8 *ll)
{
return (PRUint32)( (ll [0] << 0) |
(ll [1] << 8) |
@ -867,56 +867,129 @@ static PRUint32 xtolong (const unsigned char *ll)
(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);
}
PRUint32 const nsZipItem::Size()
PRUint32 nsZipItem::Size()
{
return isSynthetic ? 0 : xtolong(central->size);
}
PRUint32 const nsZipItem::RealSize()
PRUint32 nsZipItem::RealSize()
{
return isSynthetic ? 0 : xtolong(central->orglen);
}
PRUint32 const nsZipItem::CRC32()
PRUint32 nsZipItem::CRC32()
{
return isSynthetic ? 0 : xtolong(central->crc32);
}
PRUint16 const nsZipItem::Date()
PRUint16 nsZipItem::Date()
{
return isSynthetic ? kSyntheticDate : xtoint(central->date);
}
PRUint16 const nsZipItem::Time()
PRUint16 nsZipItem::Time()
{
return isSynthetic ? kSyntheticTime : xtoint(central->time);
}
PRUint16 const nsZipItem::Compression()
PRUint16 nsZipItem::Compression()
{
return isSynthetic ? STORED : xtoint(central->method);
}
bool const nsZipItem::IsDirectory()
bool nsZipItem::IsDirectory()
{
return isSynthetic || ((nameLength > 0) && ('/' == Name()[nameLength - 1]));
}
PRUint16 const nsZipItem::Mode()
PRUint16 nsZipItem::Mode()
{
if (isSynthetic) return 0755;
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)
bool const nsZipItem::IsSymlink()
bool nsZipItem::IsSymlink()
{
if (isSynthetic) return false;
return (xtoint(central->external_attributes+2) & S_IFMT) == S_IFLNK;
}
#endif

View File

@ -83,18 +83,20 @@ class nsZipItem
public:
const char* Name() { return ((const char*)central) + ZIPCENTRAL_SIZE; }
PRUint32 const LocalOffset();
PRUint32 const Size();
PRUint32 const RealSize();
PRUint32 const CRC32();
PRUint16 const Date();
PRUint16 const Time();
PRUint16 const Compression();
bool const IsDirectory();
PRUint16 const Mode();
PRUint32 LocalOffset();
PRUint32 Size();
PRUint32 RealSize();
PRUint32 CRC32();
PRUint16 Date();
PRUint16 Time();
PRUint16 Compression();
bool IsDirectory();
PRUint16 Mode();
const PRUint8* GetExtraField(PRUint16 aTag, PRUint16 *aBlockSize);
PRTime LastModTime();
#if defined(XP_UNIX) || defined(XP_BEOS)
bool const IsSymlink();
bool IsSymlink();
#endif
nsZipItem* next;

View File

@ -7,8 +7,8 @@ const path = "data/test_bug379841.zip";
const MAX_TIME_DIFF = 2000000;
var ENTRY_NAME = "test";
// Actual time of file was 07 May 2007 14:35:49
var ENTRY_TIME = new Date(2007, 4, 7, 14, 35, 49, 0);
// Actual time of file was 07 May 2007 13:35:49 UTC
var ENTRY_TIME = new Date(Date.UTC(2007, 4, 7, 13, 35, 49, 0));
function run_test() {
var file = do_get_file(path);

View File

@ -122,6 +122,10 @@ typedef struct ZipEnd_
#define CENTRALSIG 0x02014B50l
#define ENDSIG 0x06054B50l
/* extra fields */
#define EXTENDED_TIMESTAMP_FIELD 0x5455
#define EXTENDED_TIMESTAMP_MODTIME 0x01
/* compression methods */
#define STORED 0
#define SHRUNK 1

View File

@ -50,47 +50,43 @@
* The off argument, where present, is incremented according to the number of
* 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;
buf[(*off)++] = (val >> 8) & 0xff;
WRITE8(buf, off, val & 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;
buf[(*off)++] = (val >> 8) & 0xff;
buf[(*off)++] = (val >> 16) & 0xff;
buf[(*off)++] = (val >> 24) & 0xff;
WRITE16(buf, off, val & 0xffff);
WRITE16(buf, off, (val >> 16) & 0xffff);
}
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;
val |= ((PRUint16)buf[(*off)++] & 0xff) << 8;
PRUint16 val = READ8(buf, off);
val |= READ8(buf, off) << 8;
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;
val |= ((PRUint32)buf[(*off)++] & 0xff) << 8;
val |= ((PRUint32)buf[(*off)++] & 0xff) << 16;
val |= ((PRUint32)buf[(*off)++] & 0xff) << 24;
PRUint32 val = READ16(buf, off);
val |= READ16(buf, off) << 16;
return val;
}
inline NS_HIDDEN_(PRUint32) PEEK32(unsigned char *buf)
inline NS_HIDDEN_(PRUint32) PEEK32(const PRUint8* buf)
{
return (PRUint32)( (buf [0] ) |
(buf [1] << 8) |

View File

@ -47,6 +47,9 @@
#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.
*/
@ -105,11 +108,28 @@ NS_IMETHODIMP nsZipHeader::GetLastModifiedTime(PRTime *aLastModifiedTime)
{
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;
time.tm_usec = 0;
time.tm_hour = mTime >> 11;
time.tm_hour = (mTime >> 11) & 0x1F;
time.tm_min = (mTime >> 5) & 0x3F;
time.tm_sec = (mTime & 0x1F) * 2;
@ -121,7 +141,9 @@ NS_IMETHODIMP nsZipHeader::GetLastModifiedTime(PRTime *aLastModifiedTime)
time.tm_params.tp_dst_offset = 0;
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);
@ -149,6 +171,27 @@ void nsZipHeader::Init(const nsACString & aPath, PRTime aDate, PRUint32 aAttr,
mDate = time.tm_mday + ((time.tm_month + 1) << 5) +
((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;
mOffset = aOffset;
mName = aPath;
@ -160,14 +203,14 @@ void nsZipHeader::Init(const nsACString & aPath, PRTime aDate, PRUint32 aAttr,
PRUint32 nsZipHeader::GetFileHeaderLength()
{
return ZIP_FILE_HEADER_SIZE + mName.Length();
return ZIP_FILE_HEADER_SIZE + mName.Length() + mLocalFieldLength;
}
nsresult nsZipHeader::WriteFileHeader(nsIOutputStream *aStream)
{
NS_ASSERTION(mInited, "Not initalised");
char buf[ZIP_FILE_HEADER_SIZE];
PRUint8 buf[ZIP_FILE_HEADER_SIZE];
PRUint32 pos = 0;
WRITE32(buf, &pos, ZIP_FILE_HEADER_SIGNATURE);
WRITE16(buf, &pos, mVersionNeeded);
@ -179,12 +222,21 @@ nsresult nsZipHeader::WriteFileHeader(nsIOutputStream *aStream)
WRITE32(buf, &pos, mCSize);
WRITE32(buf, &pos, mUSize);
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);
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()
@ -197,7 +249,7 @@ nsresult nsZipHeader::WriteCDSHeader(nsIOutputStream *aStream)
{
NS_ASSERTION(mInited, "Not initalised");
char buf[ZIP_CDS_HEADER_SIZE];
PRUint8 buf[ZIP_CDS_HEADER_SIZE];
PRUint32 pos = 0;
WRITE32(buf, &pos, ZIP_CDS_HEADER_SIGNATURE);
WRITE16(buf, &pos, mVersionMade);
@ -217,13 +269,13 @@ nsresult nsZipHeader::WriteCDSHeader(nsIOutputStream *aStream)
WRITE32(buf, &pos, mEAttr);
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);
rv = ZW_WriteData(aStream, mName.get(), mName.Length());
NS_ENSURE_SUCCESS(rv, rv);
if (mExtraField) {
rv = ZW_WriteData(aStream, mExtraField, mFieldLength);
rv = ZW_WriteData(aStream, (const char *)mExtraField.get(), mFieldLength);
NS_ENSURE_SUCCESS(rv, rv);
}
return ZW_WriteData(aStream, mComment.get(), mComment.Length());
@ -233,9 +285,9 @@ nsresult nsZipHeader::ReadCDSHeader(nsIInputStream *stream)
{
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);
PRUint32 pos = 0;
@ -271,9 +323,9 @@ nsresult nsZipHeader::ReadCDSHeader(nsIInputStream *stream)
mName = NS_LITERAL_CSTRING("");
if (mFieldLength > 0) {
mExtraField = new char[mFieldLength];
mExtraField = new PRUint8[mFieldLength];
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);
}
@ -290,3 +342,25 @@ nsresult nsZipHeader::ReadCDSHeader(nsIInputStream *stream)
mInited = PR_TRUE;
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;
}

View File

@ -68,6 +68,7 @@ public:
mEAttr(0),
mOffset(0),
mFieldLength(0),
mLocalFieldLength(0),
mVersionMade(0x0300 + 23), // Generated on Unix by v2.3 (matches infozip)
mVersionNeeded(20), // Requires v2.0 to extract
mFlags(0),
@ -77,13 +78,15 @@ public:
mDisk(0),
mIAttr(0),
mInited(PR_FALSE),
mExtraField(NULL)
mExtraField(NULL),
mLocalExtraField(NULL)
{
}
~nsZipHeader()
{
mExtraField = NULL;
mLocalExtraField = NULL;
}
PRUint32 mCRC;
@ -92,6 +95,7 @@ public:
PRUint32 mEAttr;
PRUint32 mOffset;
PRUint32 mFieldLength;
PRUint32 mLocalFieldLength;
PRUint16 mVersionMade;
PRUint16 mVersionNeeded;
PRUint16 mFlags;
@ -103,7 +107,8 @@ public:
PRPackedBool mInited;
nsCString mName;
nsCString mComment;
nsAutoArrayPtr<char> mExtraField;
nsAutoArrayPtr<PRUint8> mExtraField;
nsAutoArrayPtr<PRUint8> mLocalExtraField;
void Init(const nsACString & aPath, PRTime aDate, PRUint32 aAttr,
PRUint32 aOffset);
@ -112,6 +117,7 @@ public:
PRUint32 GetCDSHeaderLength();
nsresult WriteCDSHeader(nsIOutputStream *aStream);
nsresult ReadCDSHeader(nsIInputStream *aStream);
const PRUint8 * GetExtraField(PRUint16 aTag, PRBool aLocal, PRUint16 *aBlockSize);
};
#endif

View File

@ -147,7 +147,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), aFile);
NS_ENSURE_SUCCESS(rv, rv);
char buf[1024];
PRUint8 buf[1024];
PRInt64 seek = size - 1024;
PRUint32 length = 1024;
@ -164,7 +164,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
inputStream->Close();
return rv;
}
rv = ZW_ReadData(inputStream, buf, length);
rv = ZW_ReadData(inputStream, (char *)buf, length);
if (NS_FAILED(rv)) {
inputStream->Close();
return rv;
@ -177,7 +177,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
// We know it's at least this far from the end
for (PRUint32 pos = length - ZIP_EOCDR_HEADER_SIZE;
(PRInt32)pos >= 0; pos--) {
PRUint32 sig = PEEK32((unsigned char *)buf + pos);
PRUint32 sig = PEEK32(buf + pos);
if (sig == ZIP_EOCDR_HEADER_SIGNATURE) {
// Skip down to entry count
pos += 10;
@ -190,7 +190,7 @@ nsresult nsZipWriter::ReadFile(nsIFile *aFile)
if (commentlen == 0)
mComment.Truncate();
else if (pos + commentlen <= length)
mComment.Assign(buf + pos, commentlen);
mComment.Assign((const char *)buf + pos, commentlen);
else {
if ((seek + pos + commentlen) > size) {
inputStream->Close();
@ -682,7 +682,7 @@ NS_IMETHODIMP nsZipWriter::Close()
size += mHeaders[i]->GetCDSHeaderLength();
}
char buf[ZIP_EOCDR_HEADER_SIZE];
PRUint8 buf[ZIP_EOCDR_HEADER_SIZE];
PRUint32 pos = 0;
WRITE32(buf, &pos, ZIP_EOCDR_HEADER_SIGNATURE);
WRITE16(buf, &pos, 0);
@ -693,7 +693,7 @@ NS_IMETHODIMP nsZipWriter::Close()
WRITE32(buf, &pos, mCDSOffset);
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)) {
Cleanup();
return rv;

View File

@ -55,12 +55,10 @@ const ZIP_FILE_HEADER_SIZE = 30;
const ZIP_CDS_HEADER_SIZE = 46;
const ZIP_METHOD_STORE = 0
const ZIP_METHOD_DEFLATE = 8
const ZIP_EXTENDED_TIMESTAMP_SIZE = 9;
const PR_USEC_PER_MSEC = 1000;
// ZIP times are stored at a 2 second resolution.
const TIME_RESOLUTION = 2000;
const DATA_DIR = "data/";
var ZipWriter = Components.Constructor("@mozilla.org/zipwriter;1",

View File

@ -77,11 +77,8 @@ var observer = {
do_check_eq(entry.realSize, TESTS[i].size);
do_check_eq(entry.size, TESTS[i].size);
do_check_eq(entry.CRC32, TESTS[i].crc);
var diff = Math.abs((entry.lastModifiedTime/PR_USEC_PER_MSEC) -
source.lastModifiedTime);
if (diff > TIME_RESOLUTION)
do_throw(diff);
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC,
source.lastModifiedTime);
zipR.test(TESTS[i].name);
}
@ -100,6 +97,7 @@ function run_test()
zipW.addEntryFile(TESTS[i].name, Ci.nsIZipWriter.COMPRESSION_NONE, source,
true);
size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
(ZIP_EXTENDED_TIMESTAMP_SIZE * 2) +
(TESTS[i].name.length*2) + TESTS[i].size;
}
do_test_pending();

View File

@ -55,9 +55,7 @@ function testpass(source)
// Should be stored
do_check_eq(entry.compression, ZIP_METHOD_DEFLATE);
var diff = Math.abs((entry.lastModifiedTime / PR_USEC_PER_MSEC) - time);
if (diff > TIME_RESOLUTION)
do_throw(diff);
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, time);
// File size should match our data size.
do_check_eq(entry.realSize, DATA.length);

View File

@ -57,6 +57,8 @@ function run_test()
// Adding the directory would have added a fixed amount to the file size.
// 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);
}

View File

@ -65,9 +65,7 @@ function run_test()
do_check_eq(entry.compression, ZIP_METHOD_DEFLATE);
do_check_eq(entry.CRC32, CRC);
do_check_eq(entry.realSize, DATA.length);
var diff = Math.abs((entry.lastModifiedTime/PR_USEC_PER_MSEC) - time);
if (diff > TIME_RESOLUTION)
do_throw(diff);
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, time);
zipW.close();

View File

@ -42,13 +42,13 @@ var TESTS = [
name: "test.txt",
size: 232,
crc: 0x0373ac26,
time: new Date(2007, 4, 1, 21, 44, 56)
time: Date.UTC(2007, 4, 1, 20, 44, 55)
},
{
name: "test.png",
size: 3402,
crc: 0x504a5c30,
time: new Date(2007, 4, 1, 21, 49, 40)
time: Date.UTC(2007, 4, 1, 20, 49, 39)
}
];
var BADENTRY = "unknown.txt";
@ -70,10 +70,7 @@ function run_test()
do_check_eq(entry.realSize, TESTS[i].size);
do_check_eq(entry.CRC32, TESTS[i].crc);
var diff = Math.abs(TESTS[i].time -
(entry.lastModifiedTime / PR_USEC_PER_MSEC));
if (diff > TIME_RESOLUTION)
do_throw(diff);
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, TESTS[i].time);
}
try {

View File

@ -56,9 +56,7 @@ function testpass(source)
// Should be stored
do_check_eq(entry.compression, ZIP_METHOD_STORE);
var diff = Math.abs((entry.lastModifiedTime / PR_USEC_PER_MSEC) - time);
if (diff > TIME_RESOLUTION)
do_throw(diff);
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC, time);
// File size should match our data size.
do_check_eq(entry.realSize, DATA.length);
@ -90,6 +88,7 @@ function run_test()
do_check_eq(tmpFile.fileSize,
DATA.length + ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
(ZIP_EXTENDED_TIMESTAMP_SIZE * 2) +
(FILENAME.length * 2) + ZIP_EOCDR_HEADER_SIZE);
// Check to see if we get the same results loading afresh.

View File

@ -60,6 +60,7 @@ function run_test()
zipW.addEntryFile(TESTS[i].name, Ci.nsIZipWriter.COMPRESSION_NONE, source,
false);
size += ZIP_FILE_HEADER_SIZE + ZIP_CDS_HEADER_SIZE +
(ZIP_EXTENDED_TIMESTAMP_SIZE * 2) +
(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.size, TESTS[i].size);
do_check_eq(entry.CRC32, TESTS[i].crc);
var diff = Math.abs((entry.lastModifiedTime/PR_USEC_PER_MSEC) -
source.lastModifiedTime);
if (diff > TIME_RESOLUTION)
do_throw(diff);
do_check_eq(entry.lastModifiedTime / PR_USEC_PER_MSEC,
source.lastModifiedTime);
zipR.test(TESTS[i].name);
}