Skip to content

Commit

Permalink
minzip: Add support for >2GB zipfile
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nkk71 authored and Dees-Troy committed Jan 22, 2016
1 parent 3c36697 commit 6069a79
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
19 changes: 12 additions & 7 deletions minzip/SysUtil.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@
#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);
assert(length_ != NULL);

// 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;
}
Expand All @@ -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;

Expand All @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion minzip/Zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions minzip/Zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 6069a79

Please sign in to comment.