From 04434739a2f65e1b0230fe8e7d8abd7586ed3a76 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 10 Jan 2023 22:59:40 +0000 Subject: [PATCH] zipalign/ziptime: use ftello()/fseeko(). Even if we were shipping 64-bit Windows host tools (which we still aren't), this would still be a bug. Windows is LLP64 instead of LP64, so the long that ftell()/fseek() uses isn't big enough for a 64-bit off_t. Test: treehugger Change-Id: I4e24afe811ff9b7d5696887cc5ee92e54e4a3b76 --- tools/zipalign/ZipEntry.cpp | 14 +-- tools/zipalign/ZipFile.cpp | 178 ++++++++++++++++-------------------- tools/ziptime/ZipEntry.cpp | 11 +-- tools/ziptime/ZipFile.cpp | 81 ++++++---------- 4 files changed, 115 insertions(+), 169 deletions(-) diff --git a/tools/zipalign/ZipEntry.cpp b/tools/zipalign/ZipEntry.cpp index fcad96cfa9..689999ee18 100644 --- a/tools/zipalign/ZipEntry.cpp +++ b/tools/zipalign/ZipEntry.cpp @@ -40,14 +40,10 @@ namespace android { */ status_t ZipEntry::initFromCDE(FILE* fp) { - status_t result; - long posn; // NOLINT(google-runtime-int), for ftell/fseek - bool hasDD; - //ALOGV("initFromCDE ---\n"); /* read the CDE */ - result = mCDE.read(fp); + status_t result = mCDE.read(fp); if (result != OK) { ALOGD("mCDE.read failed\n"); return result; @@ -56,8 +52,8 @@ status_t ZipEntry::initFromCDE(FILE* fp) //mCDE.dump(); /* using the info in the CDE, go load up the LFH */ - posn = ftell(fp); - if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) { + off_t posn = ftello(fp); + if (fseeko(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) { ALOGD("local header seek failed (%" PRIu32 ")\n", mCDE.mLocalHeaderRelOffset); return UNKNOWN_ERROR; @@ -69,7 +65,7 @@ status_t ZipEntry::initFromCDE(FILE* fp) return result; } - if (fseek(fp, posn, SEEK_SET) != 0) + if (fseeko(fp, posn, SEEK_SET) != 0) return UNKNOWN_ERROR; //mLFH.dump(); @@ -80,7 +76,7 @@ status_t ZipEntry::initFromCDE(FILE* fp) * compressed size, and uncompressed size will be zero. In practice * these seem to be rare. */ - hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0; + bool hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0; if (hasDD) { // do something clever //ALOGD("+++ has data descriptor\n"); diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp index ff15b156d7..42cc349e8f 100644 --- a/tools/zipalign/ZipFile.cpp +++ b/tools/zipalign/ZipFile.cpp @@ -35,6 +35,8 @@ #include #include +_Static_assert(sizeof(off_t) == 8, "off_t too small"); + namespace android { /* @@ -205,56 +207,43 @@ void ZipFile::discardEntries(void) */ status_t ZipFile::readCentralDir(void) { - status_t result = OK; - uint8_t* buf = NULL; - off_t fileLength, seekStart; - long readAmount; - int i; - - fseek(mZipFp, 0, SEEK_END); - fileLength = ftell(mZipFp); + fseeko(mZipFp, 0, SEEK_END); + off_t fileLength = ftello(mZipFp); rewind(mZipFp); /* too small to be a ZIP archive? */ if (fileLength < EndOfCentralDir::kEOCDLen) { - ALOGD("Length is %ld -- too small\n", (long)fileLength); - result = INVALID_OPERATION; - goto bail; - } - - buf = new uint8_t[EndOfCentralDir::kMaxEOCDSearch]; - if (buf == NULL) { - ALOGD("Failure allocating %d bytes for EOCD search", - EndOfCentralDir::kMaxEOCDSearch); - result = NO_MEMORY; - goto bail; + ALOGD("Length is %lld -- too small\n", (long long) fileLength); + return INVALID_OPERATION; } + off_t seekStart; + size_t readAmount; if (fileLength > EndOfCentralDir::kMaxEOCDSearch) { seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch; readAmount = EndOfCentralDir::kMaxEOCDSearch; } else { seekStart = 0; - readAmount = (long) fileLength; + readAmount = fileLength; } - if (fseek(mZipFp, seekStart, SEEK_SET) != 0) { - ALOGD("Failure seeking to end of zip at %ld", (long) seekStart); - result = UNKNOWN_ERROR; - goto bail; + if (fseeko(mZipFp, seekStart, SEEK_SET) != 0) { + ALOGD("Failure seeking to end of zip at %lld", (long long) seekStart); + return UNKNOWN_ERROR; } /* read the last part of the file into the buffer */ - if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) { + uint8_t buf[EndOfCentralDir::kMaxEOCDSearch]; + if (fread(buf, 1, readAmount, mZipFp) != readAmount) { if (feof(mZipFp)) { - ALOGW("fread %ld bytes failed, unexpected EOF", readAmount); + ALOGW("fread %zu bytes failed, unexpected EOF", readAmount); } else { - ALOGW("fread %ld bytes failed, %s", readAmount, strerror(errno)); + ALOGW("fread %zu bytes failed, %s", readAmount, strerror(errno)); } - result = UNKNOWN_ERROR; - goto bail; + return UNKNOWN_ERROR; } /* find the end-of-central-dir magic */ + int i; for (i = readAmount - 4; i >= 0; i--) { if (buf[i] == 0x50 && ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature) @@ -265,15 +254,14 @@ status_t ZipFile::readCentralDir(void) } if (i < 0) { ALOGD("EOCD not found, not Zip\n"); - result = INVALID_OPERATION; - goto bail; + return INVALID_OPERATION; } /* extract eocd values */ - result = mEOCD.readBuf(buf + i, readAmount - i); + status_t result = mEOCD.readBuf(buf + i, readAmount - i); if (result != OK) { - ALOGD("Failure reading %ld bytes of EOCD values", readAmount - i); - goto bail; + ALOGD("Failure reading %zu bytes of EOCD values", readAmount - i); + return result; } //mEOCD.dump(); @@ -281,8 +269,7 @@ status_t ZipFile::readCentralDir(void) mEOCD.mNumEntries != mEOCD.mTotalNumEntries) { ALOGD("Archive spanning not supported\n"); - result = INVALID_OPERATION; - goto bail; + return INVALID_OPERATION; } /* @@ -299,11 +286,10 @@ status_t ZipFile::readCentralDir(void) * The only thing we really need right now is the file comment, which * we're hoping to preserve. */ - if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { + if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { ALOGD("Failure seeking to central dir offset %" PRIu32 "\n", mEOCD.mCentralDirOffset); - result = UNKNOWN_ERROR; - goto bail; + return UNKNOWN_ERROR; } /* @@ -318,7 +304,7 @@ status_t ZipFile::readCentralDir(void) if (result != OK) { ALOGD("initFromCDE failed\n"); delete pEntry; - goto bail; + return result; } mEntries.add(pEntry); @@ -336,20 +322,16 @@ status_t ZipFile::readCentralDir(void) } else { ALOGW("fread EOCD failed, %s", strerror(errno)); } - result = INVALID_OPERATION; - goto bail; + return INVALID_OPERATION; } if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) { ALOGD("EOCD read check failed\n"); - result = UNKNOWN_ERROR; - goto bail; + return UNKNOWN_ERROR; } ALOGV("+++ EOCD read check passed\n"); } -bail: - delete[] buf; - return result; + return OK; } @@ -370,8 +352,7 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, { ZipEntry* pEntry = NULL; status_t result = OK; - long lfhPosn, startPosn, endPosn, uncompressedLen; - FILE* inputFp = NULL; + off_t lfhPosn, startPosn, endPosn, uncompressedLen; uint32_t crc = 0; time_t modWhen; @@ -389,13 +370,14 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, if (getEntryByName(storageName) != NULL) return ALREADY_EXISTS; + FILE* inputFp = NULL; if (!data) { inputFp = fopen(fileName, FILE_OPEN_RO); if (inputFp == NULL) return errnoToStatus(errno); } - if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { + if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { result = UNKNOWN_ERROR; goto bail; } @@ -413,9 +395,9 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, * as a place-holder. In theory the LFH isn't necessary, but in * practice some utilities demand it. */ - lfhPosn = ftell(mZipFp); + lfhPosn = ftello(mZipFp); pEntry->mLFH.write(mZipFp); - startPosn = ftell(mZipFp); + startPosn = ftello(mZipFp); /* * Copy the data in, possibly compressing it as we go. @@ -432,11 +414,11 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, * to be set through an API call, but I don't expect our * criteria to change over time. */ - long src = inputFp ? ftell(inputFp) : size; - long dst = ftell(mZipFp) - startPosn; + off_t src = inputFp ? ftello(inputFp) : size; + off_t dst = ftello(mZipFp) - startPosn; if (dst + (dst / 10) > src) { - ALOGD("insufficient compression (src=%ld dst=%ld), storing\n", - src, dst); + ALOGD("insufficient compression (src=%lld dst=%lld), storing\n", + (long long) src, (long long) dst); failed = true; } } @@ -444,7 +426,7 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, if (failed) { compressionMethod = ZipEntry::kCompressStored; if (inputFp) rewind(inputFp); - fseek(mZipFp, startPosn, SEEK_SET); + fseeko(mZipFp, startPosn, SEEK_SET); /* fall through to kCompressStored case */ } } @@ -463,7 +445,7 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, } // currently seeked to end of file - uncompressedLen = inputFp ? ftell(inputFp) : size; + uncompressedLen = inputFp ? ftello(inputFp) : size; /* * We could write the "Data Descriptor", but there doesn't seem to @@ -471,7 +453,7 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, * * Update file offsets. */ - endPosn = ftell(mZipFp); // seeked to end of compressed data + endPosn = ftello(mZipFp); // seeked to end of compressed data /* * Success! Fill out new values. @@ -489,7 +471,7 @@ status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size, /* * Go back and write the LFH. */ - if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) { + if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) { result = UNKNOWN_ERROR; goto bail; } @@ -522,7 +504,7 @@ status_t ZipFile::alignEntry(android::ZipEntry* pEntry, uint32_t alignTo){ // Calculate where the entry payload offset will end up if we were to write // it as-is. - uint64_t expectedPayloadOffset = ftell(mZipFp) + + uint64_t expectedPayloadOffset = ftello(mZipFp) + android::ZipEntry::LocalFileHeader::kLFHLen + pEntry->mLFH.mFileNameLength + pEntry->mLFH.mExtraFieldLength; @@ -548,7 +530,7 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, { ZipEntry* pEntry = NULL; status_t result; - long lfhPosn, endPosn; + off_t lfhPosn, endPosn; if (mReadOnly) return INVALID_OPERATION; @@ -557,7 +539,7 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, assert(mZipFp != NULL); assert(mEntries.size() == mEOCD.mTotalNumEntries); - if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { + if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { result = UNKNOWN_ERROR; goto bail; } @@ -585,7 +567,7 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, * Write the LFH. Since we're not recompressing the data, we already * have all of the fields filled out. */ - lfhPosn = ftell(mZipFp); + lfhPosn = ftello(mZipFp); pEntry->mLFH.write(mZipFp); /* @@ -595,8 +577,7 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, * fields as well. This is a fixed-size area immediately following * the data. */ - if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) - { + if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) { result = UNKNOWN_ERROR; goto bail; } @@ -617,7 +598,7 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, /* * Update file offsets. */ - endPosn = ftell(mZipFp); + endPosn = ftello(mZipFp); /* * Success! Fill out new values. @@ -654,7 +635,7 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour { ZipEntry* pEntry = NULL; status_t result; - long lfhPosn, uncompressedLen; + off_t lfhPosn, uncompressedLen; if (mReadOnly) return INVALID_OPERATION; @@ -663,7 +644,7 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour assert(mZipFp != NULL); assert(mEntries.size() == mEOCD.mTotalNumEntries); - if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { + if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { result = UNKNOWN_ERROR; goto bail; } @@ -688,7 +669,7 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour * as a place-holder. In theory the LFH isn't necessary, but in * practice some utilities demand it. */ - lfhPosn = ftell(mZipFp); + lfhPosn = ftello(mZipFp); pEntry->mLFH.write(mZipFp); /* @@ -698,8 +679,7 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour * fields as well. This is a fixed-size area immediately following * the data. */ - if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) - { + if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) { result = UNKNOWN_ERROR; goto bail; } @@ -712,7 +692,7 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour result = NO_MEMORY; goto bail; } - long startPosn = ftell(mZipFp); + off_t startPosn = ftello(mZipFp); uint32_t crc; if (compressFpToFp(mZipFp, NULL, buf, uncompressedLen, &crc) != OK) { ALOGW("recompress of '%s' failed\n", pEntry->mCDE.mFileName); @@ -720,13 +700,12 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour free(buf); goto bail; } - long endPosn = ftell(mZipFp); + off_t endPosn = ftello(mZipFp); pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, pSourceEntry->getCRC32(), ZipEntry::kCompressDeflated); free(buf); } else { - off_t copyLen; - copyLen = pSourceEntry->getCompressedLen(); + off_t copyLen = pSourceEntry->getCompressedLen(); if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0) copyLen += ZipEntry::kDataDescriptorLen; @@ -746,12 +725,12 @@ status_t ZipFile::addRecompress(const ZipFile* pSourceZip, const ZipEntry* pSour mEOCD.mNumEntries++; mEOCD.mTotalNumEntries++; mEOCD.mCentralDirSize = 0; // mark invalid; set by flush() - mEOCD.mCentralDirOffset = ftell(mZipFp); + mEOCD.mCentralDirOffset = ftello(mZipFp); /* * Go back and write the LFH. */ - if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) { + if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) { result = UNKNOWN_ERROR; goto bail; } @@ -978,7 +957,7 @@ status_t ZipFile::remove(ZipEntry* pEntry) status_t ZipFile::flush(void) { status_t result = OK; - long eocdPosn; + off_t eocdPosn; int i, count; if (mReadOnly) @@ -992,8 +971,7 @@ status_t ZipFile::flush(void) if (result != OK) return result; - if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) - return UNKNOWN_ERROR; + if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) return UNKNOWN_ERROR; count = mEntries.size(); for (i = 0; i < count; i++) { @@ -1001,7 +979,7 @@ status_t ZipFile::flush(void) pEntry->mCDE.write(mZipFp); } - eocdPosn = ftell(mZipFp); + eocdPosn = ftello(mZipFp); mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset; mEOCD.write(mZipFp); @@ -1011,8 +989,8 @@ status_t ZipFile::flush(void) * with plain files, or if we deleted some entries, there's a lot * of wasted space at the end of the file. Remove it now. */ - if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) { - ALOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno)); + if (ftruncate(fileno(mZipFp), ftello(mZipFp)) != 0) { + ALOGW("ftruncate failed %lld: %s\n", (long long) ftello(mZipFp), strerror(errno)); // not fatal } @@ -1141,32 +1119,32 @@ status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n) if (getSize > n) getSize = n; - if (fseek(fp, (long) src, SEEK_SET) != 0) { - ALOGW("filemove src seek %ld failed, %s", - (long) src, strerror(errno)); + if (fseeko(fp, src, SEEK_SET) != 0) { + ALOGW("filemove src seek %lld failed, %s", + (long long) src, strerror(errno)); return UNKNOWN_ERROR; } if (fread(readBuf, 1, getSize, fp) != getSize) { if (feof(fp)) { - ALOGW("fread %zu bytes off=%ld failed, unexpected EOF", - getSize, (long) src); + ALOGW("fread %zu bytes off=%lld failed, unexpected EOF", + getSize, (long long) src); } else { - ALOGW("fread %zu bytes off=%ld failed, %s", - getSize, (long) src, strerror(errno)); + ALOGW("fread %zu bytes off=%lld failed, %s", + getSize, (long long) src, strerror(errno)); } return UNKNOWN_ERROR; } - if (fseek(fp, (long) dst, SEEK_SET) != 0) { - ALOGW("filemove dst seek %ld failed, %s", - (long) dst, strerror(errno)); + if (fseeko(fp, dst, SEEK_SET) != 0) { + ALOGW("filemove dst seek %lld failed, %s", + (long long) dst, strerror(errno)); return UNKNOWN_ERROR; } if (fwrite(readBuf, 1, getSize, fp) != getSize) { - ALOGW("filemove write %zu off=%ld failed, %s", - getSize, (long) dst, strerror(errno)); + ALOGW("filemove write %zu off=%lld failed, %s", + getSize, (long long) dst, strerror(errno)); return UNKNOWN_ERROR; } @@ -1263,10 +1241,10 @@ class FileReader : public zip_archive::Reader { bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const { // Data is usually requested sequentially, so this helps avoid pointless - // fseeks every time we perform a read. There's an impedence mismatch + // seeks every time we perform a read. There's an impedence mismatch // here because the original API was designed around pread and pwrite. if (offset != current_offset_) { - if (fseek(fp_, offset, SEEK_SET) != 0) { + if (fseeko(fp_, offset, SEEK_SET) != 0) { return false; } @@ -1298,10 +1276,10 @@ void* ZipFile::uncompress(const ZipEntry* entry) const return NULL; } - fseek(mZipFp, 0, SEEK_SET); + fseeko(mZipFp, 0, SEEK_SET); off_t offset = entry->getFileOffset(); - if (fseek(mZipFp, offset, SEEK_SET) != 0) { + if (fseeko(mZipFp, offset, SEEK_SET) != 0) { goto bail; } diff --git a/tools/ziptime/ZipEntry.cpp b/tools/ziptime/ZipEntry.cpp index e7b52ed0a7..c8eb377e46 100644 --- a/tools/ziptime/ZipEntry.cpp +++ b/tools/ziptime/ZipEntry.cpp @@ -43,19 +43,16 @@ using namespace android; */ status_t ZipEntry::initAndRewriteFromCDE(FILE* fp) { - status_t result; - long posn; - /* read the CDE */ - result = mCDE.rewrite(fp); + status_t result = mCDE.rewrite(fp); if (result != 0) { LOG("mCDE.rewrite failed\n"); return result; } /* using the info in the CDE, go load up the LFH */ - posn = ftell(fp); - if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) { + off_t posn = ftello(fp); + if (fseeko(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) { LOG("local header seek failed (%" PRIu32 ")\n", mCDE.mLocalHeaderRelOffset); return -1; @@ -67,7 +64,7 @@ status_t ZipEntry::initAndRewriteFromCDE(FILE* fp) return result; } - if (fseek(fp, posn, SEEK_SET) != 0) + if (fseeko(fp, posn, SEEK_SET) != 0) return -1; return 0; diff --git a/tools/ziptime/ZipFile.cpp b/tools/ziptime/ZipFile.cpp index 1d111af535..3002a65bd5 100644 --- a/tools/ziptime/ZipFile.cpp +++ b/tools/ziptime/ZipFile.cpp @@ -40,8 +40,7 @@ status_t ZipFile::rewrite(const char* zipFileName) /* open the file */ mZipFp = fopen(zipFileName, "r+b"); if (mZipFp == NULL) { - int err = errno; - LOG("fopen failed: %d\n", err); + LOG("fopen \"%s\" failed: %s\n", zipFileName, strerror(errno)); return -1; } @@ -72,52 +71,39 @@ status_t ZipFile::rewrite(const char* zipFileName) */ status_t ZipFile::rewriteCentralDir(void) { - status_t result = 0; - uint8_t* buf = NULL; - off_t fileLength, seekStart; - long readAmount; - int i; - - fseek(mZipFp, 0, SEEK_END); - fileLength = ftell(mZipFp); + fseeko(mZipFp, 0, SEEK_END); + off_t fileLength = ftello(mZipFp); rewind(mZipFp); /* too small to be a ZIP archive? */ if (fileLength < EndOfCentralDir::kEOCDLen) { - LOG("Length is %ld -- too small\n", (long)fileLength); - result = -1; - goto bail; - } - - buf = new uint8_t[EndOfCentralDir::kMaxEOCDSearch]; - if (buf == NULL) { - LOG("Failure allocating %d bytes for EOCD search", - EndOfCentralDir::kMaxEOCDSearch); - result = -1; - goto bail; + LOG("Length is %lld -- too small\n", (long long) fileLength); + return -1; } + off_t seekStart; + size_t readAmount; if (fileLength > EndOfCentralDir::kMaxEOCDSearch) { seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch; readAmount = EndOfCentralDir::kMaxEOCDSearch; } else { seekStart = 0; - readAmount = (long) fileLength; + readAmount = fileLength; } - if (fseek(mZipFp, seekStart, SEEK_SET) != 0) { - LOG("Failure seeking to end of zip at %ld", (long) seekStart); - result = -1; - goto bail; + if (fseeko(mZipFp, seekStart, SEEK_SET) != 0) { + LOG("Failure seeking to end of zip at %lld", (long long) seekStart); + return -1; } /* read the last part of the file into the buffer */ - if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) { - LOG("short file? wanted %ld\n", readAmount); - result = -1; - goto bail; + uint8_t buf[EndOfCentralDir::kMaxEOCDSearch]; + if (fread(buf, 1, readAmount, mZipFp) != readAmount) { + LOG("short file? wanted %zu\n", readAmount); + return -1; } /* find the end-of-central-dir magic */ + int i; for (i = readAmount - 4; i >= 0; i--) { if (buf[i] == 0x50 && ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature) @@ -127,15 +113,14 @@ status_t ZipFile::rewriteCentralDir(void) } if (i < 0) { LOG("EOCD not found, not Zip\n"); - result = -1; - goto bail; + return -1; } /* extract eocd values */ - result = mEOCD.readBuf(buf + i, readAmount - i); + status_t result = mEOCD.readBuf(buf + i, readAmount - i); if (result != 0) { - LOG("Failure reading %ld bytes of EOCD values", readAmount - i); - goto bail; + LOG("Failure reading %zu bytes of EOCD values", readAmount - i); + return result; } /* @@ -152,49 +137,39 @@ status_t ZipFile::rewriteCentralDir(void) * The only thing we really need right now is the file comment, which * we're hoping to preserve. */ - if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { + if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) { LOG("Failure seeking to central dir offset %" PRIu32 "\n", mEOCD.mCentralDirOffset); - result = -1; - goto bail; + return -1; } /* * Loop through and read the central dir entries. */ - int entry; - for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) { + for (int entry = 0; entry < mEOCD.mTotalNumEntries; entry++) { ZipEntry* pEntry = new ZipEntry; - result = pEntry->initAndRewriteFromCDE(mZipFp); + delete pEntry; if (result != 0) { LOG("initFromCDE failed\n"); - delete pEntry; - goto bail; + return -1; } - - delete pEntry; } - /* * If all went well, we should now be back at the EOCD. */ uint8_t checkBuf[4]; if (fread(checkBuf, 1, 4, mZipFp) != 4) { LOG("EOCD check read failed\n"); - result = -1; - goto bail; + return -1; } if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) { LOG("EOCD read check failed\n"); - result = -1; - goto bail; + return -1; } -bail: - delete[] buf; - return result; + return 0; } /*