Bug 1269185 - Prevent crashes in Windows when zip files cannot be read draft
authorKirk Steuber <ksteuber@mozilla.com>
Wed, 04 May 2016 12:57:21 -0700
changeset 363474 2b4e22e7d0a2e8bd90a6e5f3f04a9c656725fb63
parent 363286 369a5ee3a2880a4a98df3a00bf3db8d8f36b181b
child 520048 b7456c23fa9f7aba8e1342fb58267e2780a0994a
push id17214
push userksteuber@mozilla.com
push dateWed, 04 May 2016 19:58:09 +0000
bugs1269185
milestone49.0a1
Bug 1269185 - Prevent crashes in Windows when zip files cannot be read MozReview-Commit-ID: 32uEegoKL4J
modules/libjar/nsZipArchive.cpp
modules/libjar/nsZipArchive.h
--- 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 */