From 6069a793eaa2e11e0c53af0ab063d22fb1f9f531 Mon Sep 17 00:00:00 2001 From: nkk71 Date: Tue, 19 Jan 2016 16:36:47 +0200 Subject: minzip: Add support for >2GB zipfile normal zip limit is 4GB, but due to signed variables it will only access 2GB (32bit signed integer is from -2GB to +2GB). these changes allow for a theoretical limit of 4GB zips to be flashed. RAM restrictions still apply, and on a 32bit system it's likely to max out at approx 2.8GB flashable zip, above that mmap will probably fail. Note: the flashable zip also needs a compatible update-binary which include these changes. (this also applies to both aroma installer if it's being used). Change-Id: Ib3af2945c9bd4890a2e6dc45acfc2b80ec55473b --- minzip/SysUtil.c | 19 ++++++++++++------- minzip/Zip.c | 2 +- minzip/Zip.h | 4 ++-- 3 files changed, 15 insertions(+), 10 deletions(-) (limited to 'minzip') diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c index 1858cd515..0ac1fa9b8 100644 --- a/minzip/SysUtil.c +++ b/minzip/SysUtil.c @@ -19,9 +19,9 @@ #include "Log.h" #include "SysUtil.h" -static int getFileStartAndLength(int fd, off_t *start_, size_t *length_) +static int getFileStartAndLength(int fd, loff_t *start_, size_t *length_) { - off_t start, end; + loff_t start, end; size_t length; assert(start_ != NULL); @@ -29,11 +29,11 @@ static int getFileStartAndLength(int fd, off_t *start_, size_t *length_) // TODO: isn't start always 0 for the single call site? just use fstat instead? - start = TEMP_FAILURE_RETRY(lseek(fd, 0L, SEEK_CUR)); - end = TEMP_FAILURE_RETRY(lseek(fd, 0L, SEEK_END)); + start = TEMP_FAILURE_RETRY(lseek64(fd, 0L, SEEK_CUR)); + end = TEMP_FAILURE_RETRY(lseek64(fd, 0L, SEEK_END)); - if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1 || - start == (off_t) -1 || end == (off_t) -1) { + if (TEMP_FAILURE_RETRY(lseek64(fd, start, SEEK_SET)) == -1 || + start == (loff_t) -1 || end == (loff_t) -1) { LOGE("could not determine length of file\n"); return -1; } @@ -59,7 +59,7 @@ static int getFileStartAndLength(int fd, off_t *start_, size_t *length_) */ static int sysMapFD(int fd, MemMapping* pMap) { - off_t start; + loff_t start; size_t length; void* memPtr; @@ -68,7 +68,12 @@ static int sysMapFD(int fd, MemMapping* pMap) if (getFileStartAndLength(fd, &start, &length) < 0) return -1; +#if (PLATFORM_SDK_VERSION >= 21) + memPtr = mmap64(NULL, length, PROT_READ, MAP_PRIVATE, fd, start); +#else + // Older versions of Android do not have mmap64 so we will just use mmap instead memPtr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, start); +#endif if (memPtr == MAP_FAILED) { LOGW("mmap(%d, R, PRIVATE, %d, %d) failed: %s\n", (int) length, fd, (int) start, strerror(errno)); diff --git a/minzip/Zip.c b/minzip/Zip.c index 1f035add5..f47a480f1 100644 --- a/minzip/Zip.c +++ b/minzip/Zip.c @@ -366,7 +366,7 @@ static bool parseZipArchive(ZipArchive* pArchive) } pEntry->offset = localHdrOffset + LOCHDR + get2LE(localHdr + LOCNAM) + get2LE(localHdr + LOCEXT); - if (!safe_add(NULL, pEntry->offset, pEntry->compLen)) { + if (!safe_add(NULL, pEntry->offset, (typeof(pEntry->offset))pEntry->compLen)) { LOGW("Integer overflow adding in parseZipArchive\n"); goto bail; } diff --git a/minzip/Zip.h b/minzip/Zip.h index 86d8db597..0a0345159 100644 --- a/minzip/Zip.h +++ b/minzip/Zip.h @@ -32,7 +32,7 @@ extern "C" { typedef struct ZipEntry { unsigned int fileNameLen; const char* fileName; // not null-terminated - long offset; + loff_t offset; long compLen; long uncompLen; int compression; @@ -85,7 +85,7 @@ void mzCloseZipArchive(ZipArchive* pArchive); const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive, const char* entryName); -INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) { +INLINE loff_t mzGetZipEntryOffset(const ZipEntry* pEntry) { return pEntry->offset; } INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) { -- cgit v1.2.3