diff options
Diffstat (limited to 'tools/zipalign/ZipFile.cpp')
-rw-r--r-- | tools/zipalign/ZipFile.cpp | 114 |
1 files changed, 83 insertions, 31 deletions
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp index 63fb962767..1e3c4135f1 100644 --- a/tools/zipalign/ZipFile.cpp +++ b/tools/zipalign/ZipFile.cpp @@ -35,7 +35,7 @@ #include <assert.h> #include <inttypes.h> -using namespace android; +namespace android { /* * Some environments require the "b", some choke on it. @@ -134,7 +134,7 @@ status_t ZipFile::open(const char* zipFileName, int flags) /* * Return the Nth entry in the archive. */ -android::ZipEntry* ZipFile::getEntryByIndex(int idx) const +ZipEntry* ZipFile::getEntryByIndex(int idx) const { if (idx < 0 || idx >= (int) mEntries.size()) return NULL; @@ -145,7 +145,7 @@ android::ZipEntry* ZipFile::getEntryByIndex(int idx) const /* * Find an entry by name. */ -android::ZipEntry* ZipFile::getEntryByName(const char* fileName) const +ZipEntry* ZipFile::getEntryByName(const char* fileName) const { /* * Do a stupid linear string-compare search. @@ -245,7 +245,11 @@ status_t ZipFile::readCentralDir(void) /* read the last part of the file into the buffer */ if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) { - ALOGD("short file? wanted %ld\n", readAmount); + if (feof(mZipFp)) { + ALOGW("fread %ld bytes failed, unexpected EOF", readAmount); + } else { + ALOGW("fread %ld bytes failed, %s", readAmount, strerror(errno)); + } result = UNKNOWN_ERROR; goto bail; } @@ -327,7 +331,11 @@ status_t ZipFile::readCentralDir(void) { uint8_t checkBuf[4]; if (fread(checkBuf, 1, 4, mZipFp) != 4) { - ALOGD("EOCD check read failed\n"); + if (feof(mZipFp)) { + ALOGW("fread EOCD failed, unexpected EOF"); + } else { + ALOGW("fread EOCD failed, %s", strerror(errno)); + } result = INVALID_OPERATION; goto bail; } @@ -503,6 +511,32 @@ bail: } /* + * Based on the current position in the output zip, assess where the entry + * payload will end up if written as-is. If alignment is not satisfactory, + * add some padding in the extra field. + * + */ +status_t ZipFile::alignEntry(android::ZipEntry* pEntry, uint32_t alignTo){ + if (alignTo == 0 || alignTo == 1) + return OK; + + // Calculate where the entry payload offset will end up if we were to write + // it as-is. + uint64_t expectedPayloadOffset = ftell(mZipFp) + + android::ZipEntry::LocalFileHeader::kLFHLen + + pEntry->mLFH.mFileNameLength + + pEntry->mLFH.mExtraFieldLength; + + // If the alignment is not what was requested, add some padding in the extra + // so the payload ends up where is requested. + uint64_t alignDiff = alignTo - (expectedPayloadOffset % alignTo); + if (alignDiff == 0) + return OK; + + return pEntry->addPadding(alignDiff); +} + +/* * Add an entry by copying it from another zip file. If "padding" is * nonzero, the specified number of bytes will be added to the "extra" * field in the header. @@ -510,7 +544,7 @@ bail: * If "ppEntry" is non-NULL, a pointer to the new entry will be returned. */ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, - int padding, ZipEntry** ppEntry) + int alignTo, ZipEntry** ppEntry) { ZipEntry* pEntry = NULL; status_t result; @@ -537,11 +571,10 @@ status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry, result = pEntry->initFromExternal(pSourceEntry); if (result != OK) goto bail; - if (padding != 0) { - result = pEntry->addPadding(padding); - if (result != OK) - goto bail; - } + + result = alignEntry(pEntry, alignTo); + if (result != OK) + goto bail; /* * From here on out, failures are more interesting. @@ -760,15 +793,18 @@ status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, uint32_t* pCRC32) while (1) { count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp); - if (ferror(srcFp) || ferror(dstFp)) - return errnoToStatus(errno); + if (ferror(srcFp) || ferror(dstFp)) { + status_t status = errnoToStatus(errno); + ALOGW("fread %zu bytes failed, %s", count, strerror(errno)); + return status; + } if (count == 0) break; *pCRC32 = crc32(*pCRC32, tmpBuf, count); if (fwrite(tmpBuf, 1, count, dstFp) != count) { - ALOGD("fwrite %d bytes failed\n", (int) count); + ALOGW("fwrite %zu bytes failed, %s", count, strerror(errno)); return UNKNOWN_ERROR; } } @@ -788,7 +824,7 @@ status_t ZipFile::copyDataToFp(FILE* dstFp, if (size > 0) { *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size); if (fwrite(data, 1, size, dstFp) != size) { - ALOGD("fwrite %d bytes failed\n", (int) size); + ALOGW("fwrite %zu bytes failed, %s", size, strerror(errno)); return UNKNOWN_ERROR; } } @@ -822,7 +858,11 @@ status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, size_t length, count = fread(tmpBuf, 1, readSize, srcFp); if (count != readSize) { // error or unexpected EOF - ALOGD("fread %d bytes failed\n", (int) readSize); + if (feof(srcFp)) { + ALOGW("fread %zu bytes failed, unexpected EOF", readSize); + } else { + ALOGW("fread %zu bytes failed, %s", readSize, strerror(errno)); + } return UNKNOWN_ERROR; } @@ -830,7 +870,7 @@ status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, size_t length, *pCRC32 = crc32(*pCRC32, tmpBuf, count); if (fwrite(tmpBuf, 1, count, dstFp) != count) { - ALOGD("fwrite %d bytes failed\n", (int) count); + ALOGW("fwrite %zu bytes failed, %s", count, strerror(errno)); return UNKNOWN_ERROR; } @@ -890,8 +930,7 @@ status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp, goto bail; } if (getSize < kBufSize) { - ALOGV("+++ got %d bytes, EOF reached\n", - (int)getSize); + ALOGV("+++ got %zu bytes, EOF reached\n", getSize); atEof = true; } @@ -901,9 +940,9 @@ status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp, delete[] inBuf; } - ALOGV("+++ writing %d bytes\n", (int)outSize); + ALOGV("+++ writing %zu bytes\n", outSize); if (fwrite(outBuf, 1, outSize, dstFp) != outSize) { - ALOGD("write %d failed in deflate\n", (int)outSize); + ALOGW("fwrite %zu bytes failed, %s", outSize, strerror(errno)); result = UNKNOWN_ERROR; goto bail; } @@ -1109,24 +1148,31 @@ status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n) getSize = n; if (fseek(fp, (long) src, SEEK_SET) != 0) { - ALOGD("filemove src seek %ld failed\n", (long) src); + ALOGW("filemove src seek %ld failed, %s", + (long) src, strerror(errno)); return UNKNOWN_ERROR; } if (fread(readBuf, 1, getSize, fp) != getSize) { - ALOGD("filemove read %ld off=%ld failed\n", - (long) getSize, (long) src); + if (feof(fp)) { + ALOGW("fread %zu bytes off=%ld failed, unexpected EOF", + getSize, (long) src); + } else { + ALOGW("fread %zu bytes off=%ld failed, %s", + getSize, (long) src, strerror(errno)); + } return UNKNOWN_ERROR; } if (fseek(fp, (long) dst, SEEK_SET) != 0) { - ALOGD("filemove dst seek %ld failed\n", (long) dst); + ALOGW("filemove dst seek %ld failed, %s", + (long) dst, strerror(errno)); return UNKNOWN_ERROR; } if (fwrite(readBuf, 1, getSize, fp) != getSize) { - ALOGD("filemove write %ld off=%ld failed\n", - (long) getSize, (long) dst); + ALOGW("filemove write %zu off=%ld failed, %s", + getSize, (long) dst, strerror(errno)); return UNKNOWN_ERROR; } @@ -1221,7 +1267,7 @@ class FileReader : public zip_archive::Reader { FileReader(FILE* fp) : Reader(), fp_(fp), current_offset_(0) { } - bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const { + 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 // here because the original API was designed around pread and pwrite. @@ -1244,7 +1290,7 @@ class FileReader : public zip_archive::Reader { private: FILE* fp_; - mutable uint32_t current_offset_; + mutable off64_t current_offset_; }; // free the memory when you're done @@ -1374,12 +1420,17 @@ status_t ZipFile::EndOfCentralDir::write(FILE* fp) ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset); ZipEntry::putShortLE(&buf[0x14], mCommentLen); - if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen) + if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen) { + ALOGW("fwrite EOCD failed, %s", strerror(errno)); return UNKNOWN_ERROR; + } if (mCommentLen > 0) { assert(mComment != NULL); - if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen) + if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen) { + ALOGW("fwrite %d bytes failed, %s", + (int) mCommentLen, strerror(errno)); return UNKNOWN_ERROR; + } } return OK; @@ -1397,3 +1448,4 @@ void ZipFile::EndOfCentralDir::dump(void) const mCentralDirSize, mCentralDirOffset, mCommentLen); } +} // namespace android |