Bug 595924: API change to go with Bug 598416 to fix crash r=mwu a=blocking2.0-betaN
authorTaras Glek <tglek@mozilla.com>
Thu, 11 Nov 2010 12:13:57 -0800
changeset 57342 964821cb53ace230092ead8b73f2f2e2104412ac
parent 57341 be3852cc225ba0ed09621439c7f53a7c3fae9c47
child 57343 9bbe81c91524e35fa6d18d2dda57bbe68b45dd59
push idunknown
push userunknown
push dateunknown
reviewersmwu, blocking2
bugs595924, 598416
milestone2.0b8pre
Bug 595924: API change to go with Bug 598416 to fix crash r=mwu a=blocking2.0-betaN
modules/libjar/nsZipArchive.cpp
modules/libjar/nsZipArchive.h
startupcache/StartupCache.cpp
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -773,22 +773,16 @@ MOZ_WIN_MEM_TRY_BEGIN
   // -- check if there is enough source data in the file
   if (offset + aItem->Size() > len)
     return nsnull;
 
   return data + offset;
 MOZ_WIN_MEM_TRY_CATCH(return nsnull)
 }
 
-PRBool 
-nsZipArchive::CheckCRC(nsZipItem* aItem, const PRUint8* aItemData) {
-  PRUint32 crc = crc32(0, (const unsigned char*)aItemData, aItem->Size());
-  return crc == aItem->CRC32();
-}
-
 //------------------------------------------
 // nsZipArchive constructor and destructor
 //------------------------------------------
 
 nsZipArchive::nsZipArchive() :
   mBuiltSynthetics(false)
 {
   MOZ_COUNT_CTOR(nsZipArchive);
--- a/modules/libjar/nsZipArchive.h
+++ b/modules/libjar/nsZipArchive.h
@@ -216,18 +216,16 @@ public:
 
   /**
    * Get pointer to the data of the item.
    * @param   aItem       Pointer to nsZipItem
    * reutrns null when zip file is corrupt.
    */
   const PRUint8* GetData(nsZipItem* aItem);
 
-  PRBool CheckCRC(nsZipItem* aItem, const PRUint8* aData);
-
 private:
   //--- private members ---
 
   nsZipItem*    mFiles[ZIP_TABSIZE];
   PLArenaPool   mArena;
 
   // Whether we synthesized the directory entries
   bool          mBuiltSynthetics;
@@ -348,16 +346,35 @@ public:
    */
   const T* Buffer() const {
     return (const T*)mReturnBuf;
   }
 
   operator const T*() const {
     return Buffer();
   }
+
+  /**
+   * Relinquish ownership of zip member if compressed.
+   * Copy member into a new buffer if uncompressed.
+   * @return a buffer with whole zip member. It is caller's responsibility to free() it.
+   */
+  T* Forget() {
+    if (!mReturnBuf)
+      return NULL;
+    // In uncompressed mmap case, give up buffer
+    if (mAutoBuf.get() == mReturnBuf) {
+      mReturnBuf = NULL;
+      return (T*) mAutoBuf.forget();
+    }
+    T *ret = (T*) malloc(Length());
+    memcpy(ret, mReturnBuf, Length());
+    mReturnBuf = NULL;
+    return ret;
+  }
 };
 
 class nsZipHandle {
 friend class nsZipArchive;
 public:
   static nsresult Init(nsILocalFile *file, nsZipHandle **ret NS_OUTPARAM);
   static nsresult Init(nsZipArchive *zip, const char *entry,
                        nsZipHandle **ret NS_OUTPARAM);
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -16,16 +16,17 @@
  *
  * The Initial Developer of the Original Code is
  * The Mozilla Foundation <http://www.mozilla.org/>.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Benedict Hsieh <bhsieh@mozilla.com>
+ *  Taras Glek <tglek@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -210,49 +211,35 @@ StartupCache::LoadArchive()
   return mArchive->OpenArchive(mFile);
 }
 
 // NOTE: this will not find a new entry until it has been written to disk!
 // Consumer should take ownership of the resulting buffer.
 nsresult
 StartupCache::GetBuffer(const char* id, char** outbuf, PRUint32* length) 
 {
-  char* data = NULL;
-  PRUint32 len;
-
   if (!mStartupWriteInitiated) {
     CacheEntry* entry; 
     nsDependentCString idStr(id);
     mTable.Get(idStr, &entry);
     if (entry) {
-      data = entry->data;
-      len = entry->size;
+      *outbuf = new char[entry->size];
+      memcpy(*outbuf, entry->data, entry->size);
+      *length = entry->size;
+      return NS_OK;
     }
   }
 
-  if (!data && mArchive) {
-    nsZipItem* zipItem = mArchive->GetItem(id);
+  if (mArchive) {
+    nsZipItemPtr<char> zipItem(mArchive, id, true);
     if (zipItem) {
-      const PRUint8* itemData = mArchive->GetData(zipItem);
-      if (!itemData || !mArchive->CheckCRC(zipItem, itemData)) {
-        NS_WARNING("StartupCache file corrupted!");
-        InvalidateCache();
-        return NS_ERROR_FILE_CORRUPTED;
-      }
-
-      len = zipItem->Size();
-      data = (char*) itemData;
-    }
-  }
-
-  if (data) {
-    *outbuf = new char[len];
-    memcpy(*outbuf, data, len);
-    *length = len;
-    return NS_OK;
+      *outbuf = zipItem.Forget();
+      *length = zipItem.Length();
+      return NS_OK;
+    } 
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 // Makes a copy of the buffer, client retains ownership of inbuf.
 nsresult
 StartupCache::PutBuffer(const char* id, const char* inbuf, PRUint32 len)