Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 407753c4 authored by Narayan Kamath's avatar Narayan Kamath
Browse files

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

(cherry picked from commit 4600dd05)

Change-Id: I7886cb37a229cc27c625699c80e6a6a6117d2203
parent dc22cfed
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -530,7 +530,7 @@ bool BootAnimation::movie()
        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) {
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ namespace {
        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);
+7 −6
Original line number Diff line number Diff line
#include <dirent.h>
#include <inttypes.h>
#include <sys/stat.h>

#include "idmap.h"
@@ -130,14 +131,14 @@ namespace {
            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 @@ namespace {
        }
        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;
+14 −13
Original line number Diff line number Diff line
@@ -105,8 +105,8 @@ isFilenameSafe(const char* filename)
}

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 @@ isFileDifferent(const char* filePath, size_t fileSize, time_t modifiedTime,
        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 @@ isFileDifferent(const char* filePath, size_t fileSize, time_t modifiedTime,
    }
    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 @@ static install_status_t
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 @@ copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntr

    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 @@ copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntr
    // 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;
+3 −4
Original line number Diff line number Diff line
@@ -182,11 +182,11 @@ private:

    /*
     * 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 @@ public:
     *
     * 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.
Loading