Bug 1269185 - Prevent crashes in Windows when zip files cannot be read
MozReview-Commit-ID: 32uEegoKL4J
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -214,17 +214,22 @@ nsresult nsZipHandle::Init(nsIFile *file
}
#else
handle->mNSPRFileDesc = fd.forget();
#endif
handle->mMap = map;
handle->mFile.Init(file);
handle->mTotalLen = (uint32_t) size;
handle->mFileStart = buf;
- handle->findDataStart();
+ rv = handle->findDataStart();
+ if (NS_FAILED(rv)) {
+ PR_MemUnmap(buf, (uint32_t) size);
+ PR_CloseFileMap(map);
+ return rv;
+ }
handle.forget(ret);
return NS_OK;
}
nsresult nsZipHandle::Init(nsZipArchive *zip, const char *entry,
nsZipHandle **ret)
{
RefPtr<nsZipHandle> handle = new nsZipHandle();
@@ -237,29 +242,35 @@ nsresult nsZipHandle::Init(nsZipArchive
if (!handle->mBuf->Buffer())
return NS_ERROR_UNEXPECTED;
handle->mMap = nullptr;
handle->mFile.Init(zip, entry);
handle->mTotalLen = handle->mBuf->Length();
handle->mFileStart = handle->mBuf->Buffer();
- handle->findDataStart();
+ nsresult rv = handle->findDataStart();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
handle.forget(ret);
return NS_OK;
}
nsresult nsZipHandle::Init(const uint8_t* aData, uint32_t aLen,
nsZipHandle **aRet)
{
RefPtr<nsZipHandle> handle = new nsZipHandle();
handle->mFileStart = aData;
handle->mTotalLen = aLen;
- handle->findDataStart();
+ nsresult rv = handle->findDataStart();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
handle.forget(aRet);
return NS_OK;
}
// This function finds the start of the ZIP data. If the file is a regular ZIP,
// this is just the start of the file. If the file is a CRX file, the start of
// the data is after the CRX header.
// CRX header reference: (CRX version 2)
@@ -271,37 +282,40 @@ nsresult nsZipHandle::Init(const uint8_t
// 32 bits : pubKeyLength - Unsigned integer representing the length
// of the public key in bytes.
// 32 bits : sigLength - Unsigned integer representing the length
// of the signature in bytes.
// pubKeyLength : publicKey - Contents of the author's public key.
// sigLength : signature - Signature of the ZIP content.
// Signature is created using the RSA
// algorighm with the SHA-1 hash function.
-void nsZipHandle::findDataStart()
+nsresult nsZipHandle::findDataStart()
{
// In the CRX header, integers are 32 bits. Our pointer to the file is of
// type |uint8_t|, which is guaranteed to be 8 bits.
const uint32_t CRXIntSize = 4;
+MOZ_WIN_MEM_TRY_BEGIN
if (mTotalLen > CRXIntSize * 4 && xtolong(mFileStart) == kCRXMagic) {
const uint8_t* headerData = mFileStart;
headerData += CRXIntSize * 2; // Skip magic number and version number
uint32_t pubKeyLength = xtolong(headerData);
headerData += CRXIntSize;
uint32_t sigLength = xtolong(headerData);
uint32_t headerSize = CRXIntSize * 4 + pubKeyLength + sigLength;
if (mTotalLen > headerSize) {
mLen = mTotalLen - headerSize;
mFileData = mFileStart + headerSize;
- return;
+ return NS_OK;
}
}
mLen = mTotalLen;
mFileData = mFileStart;
+MOZ_WIN_MEM_TRY_CATCH(return NS_ERROR_FAILURE)
+ return NS_OK;
}
int64_t nsZipHandle::SizeOfMapping()
{
return mTotalLen;
}
nsresult nsZipHandle::GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc)
--- a/modules/libjar/nsZipArchive.h
+++ b/modules/libjar/nsZipArchive.h
@@ -411,17 +411,17 @@ protected:
const uint8_t * mFileData; /* pointer to zip data */
uint32_t mLen; /* length of zip data */
mozilla::FileLocation mFile; /* source file if any, for logging */
private:
nsZipHandle();
~nsZipHandle();
- void findDataStart();
+ nsresult findDataStart();
PRFileMap * mMap; /* nspr datastructure for mmap */
mozilla::AutoFDClose mNSPRFileDesc;
nsAutoPtr<nsZipItemPtr<uint8_t> > mBuf;
mozilla::ThreadSafeAutoRefCnt mRefCnt; /* ref count */
NS_DECL_OWNINGTHREAD
const uint8_t * mFileStart; /* pointer to mmaped file */