handle short writes when unzipping files
minzip fails if write() doesn't write all the data in one call. Apparently this was good enough before, but it causes OTAs to fail all the time now (maybe due to the recently-submitted kernel)? Change code to attempt continuing after short writes.
This commit is contained in:
38
minzip/Zip.c
38
minzip/Zip.c
@@ -41,7 +41,7 @@ enum {
|
|||||||
CENSIZ = 20,
|
CENSIZ = 20,
|
||||||
CENLEN = 24,
|
CENLEN = 24,
|
||||||
CENNAM = 28,
|
CENNAM = 28,
|
||||||
CENEXT = 30,
|
CENEXT = 30,
|
||||||
CENCOM = 32,
|
CENCOM = 32,
|
||||||
CENDSK = 34,
|
CENDSK = 34,
|
||||||
CENATT = 36,
|
CENATT = 36,
|
||||||
@@ -66,13 +66,13 @@ enum {
|
|||||||
|
|
||||||
LOCSIG = 0x04034b50, // PK34
|
LOCSIG = 0x04034b50, // PK34
|
||||||
LOCHDR = 30,
|
LOCHDR = 30,
|
||||||
|
|
||||||
LOCVER = 4,
|
LOCVER = 4,
|
||||||
LOCFLG = 6,
|
LOCFLG = 6,
|
||||||
LOCHOW = 8,
|
LOCHOW = 8,
|
||||||
LOCTIM = 10,
|
LOCTIM = 10,
|
||||||
LOCCRC = 14,
|
LOCCRC = 14,
|
||||||
LOCSIZ = 18,
|
LOCSIZ = 18,
|
||||||
LOCLEN = 22,
|
LOCLEN = 22,
|
||||||
LOCNAM = 26,
|
LOCNAM = 26,
|
||||||
LOCEXT = 28,
|
LOCEXT = 28,
|
||||||
@@ -757,7 +757,7 @@ bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
|
|||||||
{
|
{
|
||||||
CopyProcessArgs args;
|
CopyProcessArgs args;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
args.buf = buf;
|
args.buf = buf;
|
||||||
args.bufLen = bufLen;
|
args.bufLen = bufLen;
|
||||||
ret = mzProcessZipEntryContents(pArchive, pEntry, copyProcessFunction,
|
ret = mzProcessZipEntryContents(pArchive, pEntry, copyProcessFunction,
|
||||||
@@ -772,13 +772,29 @@ bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
|
|||||||
static bool writeProcessFunction(const unsigned char *data, int dataLen,
|
static bool writeProcessFunction(const unsigned char *data, int dataLen,
|
||||||
void *fd)
|
void *fd)
|
||||||
{
|
{
|
||||||
ssize_t n = write((int)fd, data, dataLen);
|
int zeroWrites = 0;
|
||||||
if (n != dataLen) {
|
ssize_t soFar = 0;
|
||||||
LOGE("Can't write %d bytes (only %ld) from zip file: %s\n",
|
do {
|
||||||
dataLen, n, strerror(errno));
|
ssize_t n = write((int)fd, data+soFar, dataLen-soFar);
|
||||||
return false;
|
if (n < 0) {
|
||||||
}
|
LOGE("Error writing %ld bytes from zip file: %s\n",
|
||||||
return true;
|
dataLen-soFar, strerror(errno));
|
||||||
|
return false;
|
||||||
|
} else if (n > 0) {
|
||||||
|
soFar += n;
|
||||||
|
if (soFar == dataLen) return true;
|
||||||
|
if (soFar > dataLen) {
|
||||||
|
LOGE("write overrun? (%ld bytes instead of %d)\n",
|
||||||
|
soFar, dataLen);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
zeroWrites = 0;
|
||||||
|
} else {
|
||||||
|
++zeroWrites;
|
||||||
|
}
|
||||||
|
} while (zeroWrites < 5);
|
||||||
|
LOGE("too many consecutive zero-length writes\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user