Bug 832162 - fix jar BuildSynthetics r=taras, a=tef+
authorJason Duell <jduell.mcbugs@gmail.com>
Thu, 24 Jan 2013 17:47:05 -0800
changeset 118332 ed53e2df9157
parent 118331 63f6c3b4930a
child 118333 56254819e70e
push id356
push userjst@mozilla.com
push dateFri, 25 Jan 2013 08:40:04 +0000
reviewerstaras, tef
bugs832162
milestone18.0
Bug 832162 - fix jar BuildSynthetics r=taras, a=tef+
modules/libjar/nsZipArchive.cpp
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -553,18 +553,21 @@ MOZ_WIN_MEM_TRY_BEGIN
     uint16_t extralen = xtoint(central->extrafield_len);
     uint16_t commentlen = xtoint(central->commentfield_len);
 
     // Point to the next item at the top of loop
     buf += ZIPCENTRAL_SIZE + namelen + extralen + commentlen;
 
     // Sanity check variable sizes and refuse to deal with
     // anything too big: it's likely a corrupt archive.
-    if (namelen > kMaxNameLength || buf >= endp)
+    if (namelen < 1 ||
+        namelen > kMaxNameLength ||
+        buf >= endp) {
       return NS_ERROR_FILE_CORRUPTED;
+    }
 
     nsZipItem* item = CreateZipItem();
     if (!item)
       return NS_ERROR_OUT_OF_MEMORY;
 
     item->central = central;
     item->nameLength = namelen;
     item->isSynthetic = false;
@@ -605,34 +608,40 @@ nsresult nsZipArchive::BuildSynthetics()
     return NS_OK;
   mBuiltSynthetics = true;
 
 MOZ_WIN_MEM_TRY_BEGIN
   // Create synthetic entries for any missing directories.
   // Do this when all ziptable has scanned to prevent double entries.
   for (int i = 0; i < ZIP_TABSIZE; ++i)
   {
-    for (nsZipItem* item = mFiles[i]; item != 0; item = item->next)
+    for (nsZipItem* item = mFiles[i]; item != nullptr; item = item->next)
     {
       if (item->isSynthetic)
         continue;
     
       //-- add entries for directories in the current item's path
       //-- go from end to beginning, because then we can stop trying
       //-- to create diritems if we find that the diritem we want to
       //-- create already exists
       //-- start just before the last char so as to not add the item
       //-- twice if it's a directory
       uint16_t namelen = item->nameLength;
+      MOZ_ASSERT(namelen > 0, "Attempt to build synthetic for zero-length entry name!");
       const char *name = item->Name();
       for (uint16_t dirlen = namelen - 1; dirlen > 0; dirlen--)
       {
         if (name[dirlen-1] != '/')
           continue;
 
+        // The character before this is '/', so if this is also '/' then we
+        // have an empty path component. Skip it.
+        if (name[dirlen] == '/')
+          continue;
+
         // Is the directory already in the file table?
         uint32_t hash = HashName(item->Name(), dirlen);
         bool found = false;
         for (nsZipItem* zi = mFiles[hash]; zi != NULL; zi = zi->next)
         {
           if ((dirlen == zi->nameLength) &&
               (0 == memcmp(item->Name(), zi->Name(), dirlen)))
           {