Revert "Reconcile differences between zip implementations"

This reverts commit 9ffddc7eb50653cf60ce6b27a0e1945eed5b5ce1.

Change-Id: Ifeba63511211bfc2b375f2205e319e91403b7d06
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 4647e68..b84f3b0 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -46,41 +46,31 @@
 /*
  * Zip file constants.
  */
-#define kEOCDSignature       0x06054b50
-#define kEOCDLen             22
-#define kEOCDDiskNumber      4               // number of the current disk
-#define kEOCDDiskNumberForCD 6               // disk number with the Central Directory
-#define kEOCDNumEntries      8               // offset to #of entries in file
-#define kEOCDTotalNumEntries 10              // offset to total #of entries in spanned archives
-#define kEOCDSize            12              // size of the central directory
-#define kEOCDFileOffset      16              // offset to central directory
-#define kEOCDCommentSize     20              // offset to the length of the file comment
+#define kEOCDSignature      0x06054b50
+#define kEOCDLen            22
+#define kEOCDNumEntries     8               // offset to #of entries in file
+#define kEOCDSize           12              // size of the central directory
+#define kEOCDFileOffset     16              // offset to central directory
 
-#define kMaxCommentLen       65535           // longest possible in ushort
-#define kMaxEOCDSearch       (kMaxCommentLen + kEOCDLen)
+#define kMaxCommentLen      65535           // longest possible in ushort
+#define kMaxEOCDSearch      (kMaxCommentLen + kEOCDLen)
 
-#define kLFHSignature        0x04034b50
-#define kLFHLen              30              // excluding variable-len fields
-#define kLFHGPBFlags          6              // offset to GPB flags
-#define kLFHNameLen          26              // offset to filename length
-#define kLFHExtraLen         28              // offset to extra length
+#define kLFHSignature       0x04034b50
+#define kLFHLen             30              // excluding variable-len fields
+#define kLFHNameLen         26              // offset to filename length
+#define kLFHExtraLen        28              // offset to extra length
 
-#define kCDESignature        0x02014b50
-#define kCDELen              46              // excluding variable-len fields
-#define kCDEGPBFlags          8              // offset to GPB flags
-#define kCDEMethod           10              // offset to compression method
-#define kCDEModWhen          12              // offset to modification timestamp
-#define kCDECRC              16              // offset to entry CRC
-#define kCDECompLen          20              // offset to compressed length
-#define kCDEUncompLen        24              // offset to uncompressed length
-#define kCDENameLen          28              // offset to filename length
-#define kCDEExtraLen         30              // offset to extra length
-#define kCDECommentLen       32              // offset to comment length
-#define kCDELocalOffset      42              // offset to local hdr
-
-/* General Purpose Bit Flag */
-#define kGPFEncryptedFlag    (1 << 0)
-#define kGPFUnsupportedMask  (kGPFEncryptedFlag)
+#define kCDESignature       0x02014b50
+#define kCDELen             46              // excluding variable-len fields
+#define kCDEMethod          10              // offset to compression method
+#define kCDEModWhen         12              // offset to modification timestamp
+#define kCDECRC             16              // offset to entry CRC
+#define kCDECompLen         20              // offset to compressed length
+#define kCDEUncompLen       24              // offset to uncompressed length
+#define kCDENameLen         28              // offset to filename length
+#define kCDEExtraLen        30              // offset to extra length
+#define kCDECommentLen      32              // offset to comment length
+#define kCDELocalOffset     42              // offset to local hdr
 
 /*
  * The values we return for ZipEntryRO use 0 as an invalid value, so we
@@ -180,11 +170,6 @@
     if (readAmount > (ssize_t) mFileLength)
         readAmount = mFileLength;
 
-    if (readAmount < kEOCDSize) {
-        ALOGW("File too short to be a zip file");
-        return false;
-    }
-
     unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
     if (scanBuf == NULL) {
         ALOGW("couldn't allocate scanBuf: %s", strerror(errno));
@@ -208,11 +193,17 @@
         return false;
     }
 
-    unsigned int header = get4LE(scanBuf);
-    if (header != kLFHSignature) {
-        ALOGV("Not a Zip archive (found 0x%08x)\n", header);
-        free(scanBuf);
-        return false;
+    {
+        unsigned int header = get4LE(scanBuf);
+        if (header == kEOCDSignature) {
+            ALOGI("Found Zip archive, but it looks empty\n");
+            free(scanBuf);
+            return false;
+        } else if (header != kLFHSignature) {
+            ALOGV("Not a Zip archive (found 0x%08x)\n", header);
+            free(scanBuf);
+            return false;
+        }
     }
 
     /*
@@ -270,38 +261,24 @@
      * Grab the CD offset and size, and the number of entries in the
      * archive. After that, we can release our EOCD hunt buffer.
      */
-    unsigned int diskNumber = get2LE(eocdPtr + kEOCDDiskNumber);
-    unsigned int diskWithCentralDir = get2LE(eocdPtr + kEOCDDiskNumberForCD);
     unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
-    unsigned int totalNumEntries = get2LE(eocdPtr + kEOCDTotalNumEntries);
-    unsigned int centralDirSize = get4LE(eocdPtr + kEOCDSize);
-    unsigned int centralDirOffset = get4LE(eocdPtr + kEOCDFileOffset);
-    unsigned int commentSize = get2LE(eocdPtr + kEOCDCommentSize);
+    unsigned int dirSize = get4LE(eocdPtr + kEOCDSize);
+    unsigned int dirOffset = get4LE(eocdPtr + kEOCDFileOffset);
     free(scanBuf);
 
     // Verify that they look reasonable.
-    if ((long long) centralDirOffset + (long long) centralDirSize > (long long) eocdOffset) {
+    if ((long long) dirOffset + (long long) dirSize > (long long) eocdOffset) {
         ALOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
-            (long) centralDirOffset, centralDirSize, (long) eocdOffset);
+            (long) dirOffset, dirSize, (long) eocdOffset);
         return false;
     }
     if (numEntries == 0) {
         ALOGW("empty archive?\n");
         return false;
-    } else if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) {
-        ALOGW("spanned archives not supported");
-        return false;
-    }
-
-    // Check to see if comment is a sane size
-    if ((commentSize > (mFileLength - kEOCDLen))
-            || (eocdOffset > (mFileLength - kEOCDLen) - commentSize)) {
-        ALOGW("comment size runs off end of file");
-        return false;
     }
 
     ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
-        numEntries, centralDirSize, centralDirOffset);
+        numEntries, dirSize, dirOffset);
 
     mDirectoryMap = new FileMap();
     if (mDirectoryMap == NULL) {
@@ -309,14 +286,14 @@
         return false;
     }
 
-    if (!mDirectoryMap->create(mFileName, mFd, centralDirOffset, centralDirSize, true)) {
+    if (!mDirectoryMap->create(mFileName, mFd, dirOffset, dirSize, true)) {
         ALOGW("Unable to map '%s' (" ZD " to " ZD "): %s\n", mFileName,
-                (ZD_TYPE) centralDirOffset, (ZD_TYPE) (centralDirOffset + centralDirSize), strerror(errno));
+                (ZD_TYPE) dirOffset, (ZD_TYPE) (dirOffset + dirSize), strerror(errno));
         return false;
     }
 
     mNumEntries = numEntries;
-    mDirectoryOffset = centralDirOffset;
+    mDirectoryOffset = dirOffset;
 
     return true;
 }
@@ -375,30 +352,17 @@
             goto bail;
         }
 
-        unsigned int gpbf = get2LE(ptr + kCDEGPBFlags);
-        if ((gpbf & kGPFUnsupportedMask) != 0) {
-            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
-            goto bail;
-        }
+        unsigned int fileNameLen, extraLen, commentLen, hash;
 
-        unsigned int nameLen = get2LE(ptr + kCDENameLen);
-        unsigned int extraLen = get2LE(ptr + kCDEExtraLen);
-        unsigned int commentLen = get2LE(ptr + kCDECommentLen);
-
-        const char *name = (const char *) ptr + kCDELen;
-
-        /* Check name for NULL characters */
-        if (memchr(name, 0, nameLen) != NULL) {
-            ALOGW("Filename contains NUL byte");
-            goto bail;
-        }
+        fileNameLen = get2LE(ptr + kCDENameLen);
+        extraLen = get2LE(ptr + kCDEExtraLen);
+        commentLen = get2LE(ptr + kCDECommentLen);
 
         /* add the CDE filename to the hash table */
-        unsigned int hash = computeHash(name, nameLen);
-        addToHash(name, nameLen, hash);
+        hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
+        addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
 
-        /* We don't care about the comment or extra data. */
-        ptr += kCDELen + nameLen + extraLen + commentLen;
+        ptr += kCDELen + fileNameLen + extraLen + commentLen;
         if ((size_t)(ptr - cdPtr) > cdLength) {
             ALOGW("bad CD advance (%d vs " ZD ") at entry %d\n",
                 (int) (ptr - cdPtr), (ZD_TYPE) cdLength, i);
@@ -511,10 +475,8 @@
     bool ret = false;
 
     const int ent = entryToIndex(entry);
-    if (ent < 0) {
-        ALOGW("cannot find entry");
+    if (ent < 0)
         return false;
-    }
 
     HashEntry hashEntry = mHashTable[ent];
 
@@ -623,12 +585,6 @@
         }
 #endif /* HAVE_PREAD */
 
-        unsigned int gpbf = get2LE(lfhBuf + kLFHGPBFlags);
-        if ((gpbf & kGPFUnsupportedMask) != 0) {
-            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
-            return false;
-        }
-
         off64_t dataOffset = localHdrOffset + kLFHLen
             + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
         if (dataOffset >= cdOffset) {
@@ -637,15 +593,14 @@
         }
 
         /* check lengths */
-        if ((dataOffset >= cdOffset) || (compLen >= (cdOffset - dataOffset))) {
+        if ((off64_t)(dataOffset + compLen) > cdOffset) {
             ALOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
                 (long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
             return false;
         }
 
         if (method == kCompressStored &&
-            ((dataOffset >= cdOffset) ||
-             (uncompLen >= (cdOffset - dataOffset))))
+            (off64_t)(dataOffset + uncompLen) > cdOffset)
         {
             ALOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
                 (long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
@@ -690,24 +645,14 @@
      */
 
     FileMap* newMap;
-    int method;
-    size_t uncompLen;
     size_t compLen;
     off64_t offset;
 
-    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+    if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
         return NULL;
-    }
-
-    size_t actualLen;
-    if (method == kCompressStored) {
-        actualLen = uncompLen;
-    } else {
-        actualLen = compLen;
-    }
 
     newMap = new FileMap();
-    if (!newMap->create(mFileName, mFd, offset, actualLen, true)) {
+    if (!newMap->create(mFileName, mFd, offset, compLen, true)) {
         newMap->release();
         return NULL;
     }
@@ -726,21 +671,17 @@
     const size_t kSequentialMin = 32768;
     bool result = false;
     int ent = entryToIndex(entry);
-    if (ent < 0) {
-        return false;
-    }
+    if (ent < 0)
+        return -1;
 
     int method;
     size_t uncompLen, compLen;
     off64_t offset;
     const unsigned char* ptr;
-    FileMap *file;
 
-    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
-        goto bail;
-    }
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
 
-    file = createEntryFileMap(entry);
+    FileMap* file = createEntryFileMap(entry);
     if (file == NULL) {
         goto bail;
     }
@@ -790,21 +731,17 @@
 {
     bool result = false;
     int ent = entryToIndex(entry);
-    if (ent < 0) {
-        return false;
-    }
+    if (ent < 0)
+        return -1;
 
     int method;
     size_t uncompLen, compLen;
     off64_t offset;
     const unsigned char* ptr;
-    FileMap *file;
 
-    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
-        goto bail;
-    }
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
 
-    file = createEntryFileMap(entry);
+    FileMap* file = createEntryFileMap(entry);
     if (file == NULL) {
         goto bail;
     }
@@ -824,9 +761,8 @@
             ALOGI("+++ successful write\n");
         }
     } else {
-        if (!inflateBuffer(fd, ptr, uncompLen, compLen)) {
+        if (!inflateBuffer(fd, ptr, uncompLen, compLen))
             goto unmap;
-        }
     }
 
     result = true;