aboutsummaryrefslogtreecommitdiff
path: root/tools/zipalign/ZipFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/zipalign/ZipFile.cpp')
-rw-r--r--tools/zipalign/ZipFile.cpp114
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