ZipFileRO: Use precise widths for zip file types.

getEntryInfo crashes on 64-bit devices because "long" types
were being passed int pointers (that pointed to a stack frame)
that were reinterpret_cast'ed to long* (sigh.). To fix this issue
once and for all, use types with explicitly defined widths.

This change also removes some dead invariant checking from
Asset.cpp instead of cleaning it up.

Note that we've introduced a wart in NativeLibraryHelper, where
we need to deal with zlib's uLong type, which is "at least 32 bits
wide".

bug: 21622286

Change-Id: Iae675a9601db7aae03a8b80b40321d2cc1d97f50
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 21dc1e2..fba462b 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -530,7 +530,7 @@
         if (leaf.size() > 0) {
             for (size_t j=0 ; j<pcount ; j++) {
                 if (path == animation.parts[j].path) {
-                    int method;
+                    uint16_t method;
                     // supports only stored png files
                     if (mZip->getEntryInfo(entry, &method, NULL, NULL, NULL, NULL, NULL)) {
                         if (method == ZipFileRO::kCompressStored) {
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
index 16532b8..41395f1 100644
--- a/cmds/idmap/create.cpp
+++ b/cmds/idmap/create.cpp
@@ -23,7 +23,7 @@
         if (entry == NULL) {
             return -1;
         }
-        if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, reinterpret_cast<long*>(crc))) {
+        if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, crc)) {
             return -1;
         }
         zip->releaseEntry(entry);
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index 84158d3..612a7eb 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -1,4 +1,5 @@
 #include <dirent.h>
+#include <inttypes.h>
 #include <sys/stat.h>
 
 #include "idmap.h"
@@ -130,14 +131,14 @@
             ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__);
             return -1;
         }
-        size_t uncompLen = 0;
-        int method;
+        uint32_t uncompLen = 0;
+        uint16_t method;
         if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) {
             ALOGW("%s: failed to read entry info\n", __FUNCTION__);
             return -1;
         }
         if (method != ZipFileRO::kCompressDeflated) {
-            ALOGW("%s: cannot handle zip compression method %d\n", __FUNCTION__, method);
+            ALOGW("%s: cannot handle zip compression method %" PRIu16 "\n", __FUNCTION__, method);
             return -1;
         }
         FileMap *dataMap = zip->createEntryFileMap(entry);
@@ -147,19 +148,19 @@
         }
         char *buf = new char[uncompLen];
         if (NULL == buf) {
-            ALOGW("%s: failed to allocate %zd byte\n", __FUNCTION__, uncompLen);
+            ALOGW("%s: failed to allocate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
             delete dataMap;
             return -1;
         }
         StreamingZipInflater inflater(dataMap, uncompLen);
         if (inflater.read(buf, uncompLen) < 0) {
-            ALOGW("%s: failed to inflate %zd byte\n", __FUNCTION__, uncompLen);
+            ALOGW("%s: failed to inflate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
             delete[] buf;
             delete dataMap;
             return -1;
         }
 
-        int priority = parse_manifest(buf, uncompLen, target_package_name);
+        int priority = parse_manifest(buf, static_cast<size_t>(uncompLen), target_package_name);
         delete[] buf;
         delete dataMap;
         return priority;
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 9307ff9..a526223 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -105,8 +105,8 @@
 }
 
 static bool
-isFileDifferent(const char* filePath, size_t fileSize, time_t modifiedTime,
-        long zipCrc, struct stat64* st)
+isFileDifferent(const char* filePath, uint32_t fileSize, time_t modifiedTime,
+        uint32_t zipCrc, struct stat64* st)
 {
     if (lstat64(filePath, st) < 0) {
         // File is not found or cannot be read.
@@ -134,7 +134,9 @@
         return true;
     }
 
-    long crc = crc32(0L, Z_NULL, 0);
+    // uLong comes from zlib.h. It's a bit of a wart that they're
+    // potentially using a 64-bit type for a 32-bit CRC.
+    uLong crc = crc32(0L, Z_NULL, 0);
     unsigned char crcBuffer[16384];
     ssize_t numBytes;
     while ((numBytes = TEMP_FAILURE_RETRY(read(fd, crcBuffer, sizeof(crcBuffer)))) > 0) {
@@ -142,9 +144,9 @@
     }
     close(fd);
 
-    ALOGV("%s: crc = %lx, zipCrc = %lx\n", filePath, crc, zipCrc);
+    ALOGV("%s: crc = %lx, zipCrc = %" PRIu32 "\n", filePath, crc, zipCrc);
 
-    if (crc != zipCrc) {
+    if (crc != static_cast<uLong>(zipCrc)) {
         return true;
     }
 
@@ -155,13 +157,13 @@
 sumFiles(JNIEnv*, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char*)
 {
     size_t* total = (size_t*) arg;
-    size_t uncompLen;
+    uint32_t uncompLen;
 
     if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, NULL, NULL)) {
         return INSTALL_FAILED_INVALID_APK;
     }
 
-    *total += uncompLen;
+    *total += static_cast<size_t>(uncompLen);
 
     return INSTALL_SUCCEEDED;
 }
@@ -181,12 +183,11 @@
 
     ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
 
-    size_t uncompLen;
-    long when;
-    long crc;
-    time_t modTime;
+    uint32_t uncompLen;
+    uint32_t when;
+    uint32_t crc;
 
-    int method;
+    uint16_t method;
     off64_t offset;
 
     if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, NULL, &offset, &when, &crc)) {
@@ -233,7 +234,7 @@
     // Only copy out the native file if it's different.
     struct tm t;
     ZipUtils::zipTimeToTimespec(when, &t);
-    modTime = mktime(&t);
+    const time_t modTime = mktime(&t);
     struct stat64 st;
     if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) {
         return INSTALL_SUCCEEDED;
diff --git a/include/androidfw/Asset.h b/include/androidfw/Asset.h
index 1fe0e06..ee77e97 100644
--- a/include/androidfw/Asset.h
+++ b/include/androidfw/Asset.h
@@ -182,11 +182,11 @@
 
     /*
      * Create the asset from a memory-mapped file segment with compressed
-     * data.  "method" is a Zip archive compression method constant.
+     * data.
      *
      * The asset takes ownership of the FileMap.
      */
-    static Asset* createFromCompressedMap(FileMap* dataMap, int method,
+    static Asset* createFromCompressedMap(FileMap* dataMap,
         size_t uncompressedLen, AccessMode mode);
 
 
@@ -286,8 +286,7 @@
      *
      * On success, the object takes ownership of "fd".
      */
-    status_t openChunk(FileMap* dataMap, int compressionMethod,
-        size_t uncompressedLen);
+    status_t openChunk(FileMap* dataMap, size_t uncompressedLen);
 
     /*
      * Standard Asset interfaces.
diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h
index ad5be12..1410d87 100644
--- a/include/androidfw/ZipFileRO.h
+++ b/include/androidfw/ZipFileRO.h
@@ -35,6 +35,7 @@
 #include <utils/FileMap.h>
 #include <utils/threads.h>
 
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -68,9 +69,9 @@
 class ZipFileRO {
 public:
     /* Zip compression methods we support */
-    enum {
-        kCompressStored     = 0,        // no compression
-        kCompressDeflated   = 8,        // standard deflate
+    enum : uint16_t {
+        kCompressStored = 0,
+        kCompressDeflated = 8
     };
 
     /*
@@ -108,10 +109,10 @@
 
     /*
      * Copy the filename into the supplied buffer.  Returns 0 on success,
-     * -1 if "entry" is invalid, or the filename length if it didn't fit.  The
+     * -1 if "entry" is invalid, or the filename length if it didn't fit. The
      * length, and the returned string, include the null-termination.
      */
-    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
+    int getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen) const;
 
     /*
      * Get the vital stats for an entry.  Pass in NULL pointers for anything
@@ -122,8 +123,9 @@
      * Returns "false" if "entry" is bogus or if the data in the Zip file
      * appears to be bad.
      */
-    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
+    bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen,
+        uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen,
+        uint32_t* pCrc32) const;
 
     /*
      * Create a new FileMap object that maps a subset of the archive.  For
diff --git a/include/androidfw/ZipUtils.h b/include/androidfw/ZipUtils.h
index 6bea25a..094eaa8 100644
--- a/include/androidfw/ZipUtils.h
+++ b/include/androidfw/ZipUtils.h
@@ -20,6 +20,7 @@
 #ifndef __LIBS_ZIPUTILS_H
 #define __LIBS_ZIPUTILS_H
 
+#include <stdint.h>
 #include <stdio.h>
 #include <time.h>
 
@@ -63,8 +64,8 @@
     /*
      * Utility function to convert ZIP's time format to a timespec struct.
      */
-    static inline void zipTimeToTimespec(long when, struct tm* timespec) {
-        const long date = when >> 16;
+    static inline void zipTimeToTimespec(uint32_t when, struct tm* timespec) {
+        const uint32_t date = when >> 16;
         timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980
         timespec->tm_mon = (date >> 5) & 0x0F;
         timespec->tm_mday = date & 0x1F;
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index 782806e..4e14b13 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -296,13 +296,13 @@
  * Create a new Asset from compressed data in a memory mapping.
  */
 /*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,
-    int method, size_t uncompressedLen, AccessMode mode)
+    size_t uncompressedLen, AccessMode mode)
 {
     _CompressedAsset* pAsset;
     status_t result;
 
     pAsset = new _CompressedAsset;
-    result = pAsset->openChunk(dataMap, method, uncompressedLen);
+    result = pAsset->openChunk(dataMap, uncompressedLen);
     if (result != NO_ERROR)
         return NULL;
 
@@ -734,18 +734,12 @@
  *
  * Nothing is expanded until the first read call.
  */
-status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,
-    size_t uncompressedLen)
+status_t _CompressedAsset::openChunk(FileMap* dataMap, size_t uncompressedLen)
 {
     assert(mFd < 0);        // no re-open
     assert(mMap == NULL);
     assert(dataMap != NULL);
 
-    if (compressionMethod != ZipFileRO::kCompressDeflated) {
-        assert(false);
-        return UNKNOWN_ERROR;
-    }
-
     mMap = dataMap;
     mStart = -1;        // not used
     mCompressedLen = dataMap->getDataLength();
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 25cd363..2dc1c96 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -1156,13 +1156,11 @@
     Asset* pAsset = NULL;
 
     // TODO: look for previously-created shared memory slice?
-    int method;
-    size_t uncompressedLen;
+    uint16_t method;
+    uint32_t uncompressedLen;
 
     //printf("USING Zip '%s'\n", pEntry->getFileName());
 
-    //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,
-    //    &offset);
     if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
             NULL, NULL))
     {
@@ -1181,8 +1179,8 @@
         ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
                 dataMap->getFileName(), mode, pAsset);
     } else {
-        pAsset = Asset::createFromCompressedMap(dataMap, method,
-            uncompressedLen, mode);
+        pAsset = Asset::createFromCompressedMap(dataMap,
+            static_cast<size_t>(uncompressedLen), mode);
         ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
                 dataMap->getFileName(), mode, pAsset);
     }
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 93b1d56..6f927b4 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -97,8 +97,9 @@
  * Returns "false" if the offsets to the fields or the contents of the fields
  * appear to be bogus.
  */
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
+    uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
+    uint32_t* pModWhen, uint32_t* pCrc32) const
 {
     const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
     const ZipEntry& ze = zipEntry->entry;
@@ -166,7 +167,7 @@
 /*
  * Copy the entry's filename to the buffer.
  */
-int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
+int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen)
     const
 {
     const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);