ZipFileRO: moar logging and wrap close

There is apparently still a race upon reading the entry Local File
Header that can't be tracked down, so move the LFH check inside the
mutex-protected block so we can call lseek again to see where we are
when we log an error.

Also, close() can fail so use TEMP_FAILURE_RETRY on it so we don't
unwittingly leak file descriptors when Mean Mr. EINTR comes a-knocking.

Change-Id: I753abad0bd882fe28f7281c406fa76f64393ef4c
This commit is contained in:
Kenny Root 2010-10-01 18:28:28 -07:00
parent db193288b2
commit dbf6f272a2
2 changed files with 21 additions and 16 deletions

View File

@ -64,15 +64,8 @@ public:
mNumEntries(-1), mDirectoryOffset(-1),
mHashTableSize(-1), mHashTable(NULL)
{}
~ZipFileRO() {
free(mHashTable);
if (mDirectoryMap)
mDirectoryMap->release();
if (mFd >= 0)
close(mFd);
if (mFileName)
free(mFileName);
}
~ZipFileRO();
/*
* Open an archive.

View File

@ -86,6 +86,16 @@ using namespace android;
*/
#define kZipEntryAdj 10000
ZipFileRO::~ZipFileRO() {
free(mHashTable);
if (mDirectoryMap)
mDirectoryMap->release();
if (mFd >= 0)
TEMP_FAILURE_RETRY(close(mFd));
if (mFileName)
free(mFileName);
}
/*
* Convert a ZipEntryRO to a hash table index, verifying that it's in a
* valid range.
@ -122,7 +132,7 @@ status_t ZipFileRO::open(const char* zipFileName)
mFileLength = lseek(fd, 0, SEEK_END);
if (mFileLength < kEOCDLen) {
close(fd);
TEMP_FAILURE_RETRY(close(fd));
return UNKNOWN_ERROR;
}
@ -152,7 +162,7 @@ status_t ZipFileRO::open(const char* zipFileName)
bail:
free(mFileName);
mFileName = NULL;
close(fd);
TEMP_FAILURE_RETRY(close(fd));
return UNKNOWN_ERROR;
}
@ -512,13 +522,15 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
return false;
}
}
if (get4LE(lfhBuf) != kLFHSignature) {
LOGW("didn't find signature at start of lfh, offset=%ld (got 0x%08lx, expected 0x%08x)\n",
localHdrOffset, get4LE(lfhBuf), kLFHSignature);
off_t actualOffset = lseek(mFd, 0, SEEK_CUR);
LOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
"got: offset=%zd data=0x%08lx\n",
localHdrOffset, kLFHSignature, (size_t)actualOffset, get4LE(lfhBuf));
return false;
}
}
off_t dataOffset = localHdrOffset + kLFHLen
+ get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);