summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-09-11 18:10:09 +0000
committerKenny Root <kroot@google.com>2013-09-11 18:10:09 +0000
commit0c4b3646b0feb1bed89bf374ff03af797834d8c3 (patch)
tree874a3a61fe15c54de266336360a5b9d93b52cbe0 /libs
parent9ffddc7eb50653cf60ce6b27a0e1945eed5b5ce1 (diff)
downloadframeworks_base-0c4b3646b0feb1bed89bf374ff03af797834d8c3.zip
frameworks_base-0c4b3646b0feb1bed89bf374ff03af797834d8c3.tar.gz
frameworks_base-0c4b3646b0feb1bed89bf374ff03af797834d8c3.tar.bz2
Revert "Reconcile differences between zip implementations"
This reverts commit 9ffddc7eb50653cf60ce6b27a0e1945eed5b5ce1. Change-Id: Ifeba63511211bfc2b375f2205e319e91403b7d06
Diffstat (limited to 'libs')
-rw-r--r--libs/androidfw/ZipFileRO.cpp194
1 files changed, 65 insertions, 129 deletions
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 4647e68..b84f3b0 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -46,41 +46,31 @@ using namespace android;
/*
* Zip file constants.
*/
-#define kEOCDSignature 0x06054b50
-#define kEOCDLen 22
-#define kEOCDDiskNumber 4 // number of the current disk
-#define kEOCDDiskNumberForCD 6 // disk number with the Central Directory
-#define kEOCDNumEntries 8 // offset to #of entries in file
-#define kEOCDTotalNumEntries 10 // offset to total #of entries in spanned archives
-#define kEOCDSize 12 // size of the central directory
-#define kEOCDFileOffset 16 // offset to central directory
-#define kEOCDCommentSize 20 // offset to the length of the file comment
-
-#define kMaxCommentLen 65535 // longest possible in ushort
-#define kMaxEOCDSearch (kMaxCommentLen + kEOCDLen)
-
-#define kLFHSignature 0x04034b50
-#define kLFHLen 30 // excluding variable-len fields
-#define kLFHGPBFlags 6 // offset to GPB flags
-#define kLFHNameLen 26 // offset to filename length
-#define kLFHExtraLen 28 // offset to extra length
-
-#define kCDESignature 0x02014b50
-#define kCDELen 46 // excluding variable-len fields
-#define kCDEGPBFlags 8 // offset to GPB flags
-#define kCDEMethod 10 // offset to compression method
-#define kCDEModWhen 12 // offset to modification timestamp
-#define kCDECRC 16 // offset to entry CRC
-#define kCDECompLen 20 // offset to compressed length
-#define kCDEUncompLen 24 // offset to uncompressed length
-#define kCDENameLen 28 // offset to filename length
-#define kCDEExtraLen 30 // offset to extra length
-#define kCDECommentLen 32 // offset to comment length
-#define kCDELocalOffset 42 // offset to local hdr
-
-/* General Purpose Bit Flag */
-#define kGPFEncryptedFlag (1 << 0)
-#define kGPFUnsupportedMask (kGPFEncryptedFlag)
+#define kEOCDSignature 0x06054b50
+#define kEOCDLen 22
+#define kEOCDNumEntries 8 // offset to #of entries in file
+#define kEOCDSize 12 // size of the central directory
+#define kEOCDFileOffset 16 // offset to central directory
+
+#define kMaxCommentLen 65535 // longest possible in ushort
+#define kMaxEOCDSearch (kMaxCommentLen + kEOCDLen)
+
+#define kLFHSignature 0x04034b50
+#define kLFHLen 30 // excluding variable-len fields
+#define kLFHNameLen 26 // offset to filename length
+#define kLFHExtraLen 28 // offset to extra length
+
+#define kCDESignature 0x02014b50
+#define kCDELen 46 // excluding variable-len fields
+#define kCDEMethod 10 // offset to compression method
+#define kCDEModWhen 12 // offset to modification timestamp
+#define kCDECRC 16 // offset to entry CRC
+#define kCDECompLen 20 // offset to compressed length
+#define kCDEUncompLen 24 // offset to uncompressed length
+#define kCDENameLen 28 // offset to filename length
+#define kCDEExtraLen 30 // offset to extra length
+#define kCDECommentLen 32 // offset to comment length
+#define kCDELocalOffset 42 // offset to local hdr
/*
* The values we return for ZipEntryRO use 0 as an invalid value, so we
@@ -180,11 +170,6 @@ bool ZipFileRO::mapCentralDirectory(void)
if (readAmount > (ssize_t) mFileLength)
readAmount = mFileLength;
- if (readAmount < kEOCDSize) {
- ALOGW("File too short to be a zip file");
- return false;
- }
-
unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
if (scanBuf == NULL) {
ALOGW("couldn't allocate scanBuf: %s", strerror(errno));
@@ -208,11 +193,17 @@ bool ZipFileRO::mapCentralDirectory(void)
return false;
}
- unsigned int header = get4LE(scanBuf);
- if (header != kLFHSignature) {
- ALOGV("Not a Zip archive (found 0x%08x)\n", header);
- free(scanBuf);
- return false;
+ {
+ unsigned int header = get4LE(scanBuf);
+ if (header == kEOCDSignature) {
+ ALOGI("Found Zip archive, but it looks empty\n");
+ free(scanBuf);
+ return false;
+ } else if (header != kLFHSignature) {
+ ALOGV("Not a Zip archive (found 0x%08x)\n", header);
+ free(scanBuf);
+ return false;
+ }
}
/*
@@ -270,38 +261,24 @@ bool ZipFileRO::mapCentralDirectory(void)
* Grab the CD offset and size, and the number of entries in the
* archive. After that, we can release our EOCD hunt buffer.
*/
- unsigned int diskNumber = get2LE(eocdPtr + kEOCDDiskNumber);
- unsigned int diskWithCentralDir = get2LE(eocdPtr + kEOCDDiskNumberForCD);
unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
- unsigned int totalNumEntries = get2LE(eocdPtr + kEOCDTotalNumEntries);
- unsigned int centralDirSize = get4LE(eocdPtr + kEOCDSize);
- unsigned int centralDirOffset = get4LE(eocdPtr + kEOCDFileOffset);
- unsigned int commentSize = get2LE(eocdPtr + kEOCDCommentSize);
+ unsigned int dirSize = get4LE(eocdPtr + kEOCDSize);
+ unsigned int dirOffset = get4LE(eocdPtr + kEOCDFileOffset);
free(scanBuf);
// Verify that they look reasonable.
- if ((long long) centralDirOffset + (long long) centralDirSize > (long long) eocdOffset) {
+ if ((long long) dirOffset + (long long) dirSize > (long long) eocdOffset) {
ALOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
- (long) centralDirOffset, centralDirSize, (long) eocdOffset);
+ (long) dirOffset, dirSize, (long) eocdOffset);
return false;
}
if (numEntries == 0) {
ALOGW("empty archive?\n");
return false;
- } else if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) {
- ALOGW("spanned archives not supported");
- return false;
- }
-
- // Check to see if comment is a sane size
- if ((commentSize > (mFileLength - kEOCDLen))
- || (eocdOffset > (mFileLength - kEOCDLen) - commentSize)) {
- ALOGW("comment size runs off end of file");
- return false;
}
ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
- numEntries, centralDirSize, centralDirOffset);
+ numEntries, dirSize, dirOffset);
mDirectoryMap = new FileMap();
if (mDirectoryMap == NULL) {
@@ -309,14 +286,14 @@ bool ZipFileRO::mapCentralDirectory(void)
return false;
}
- if (!mDirectoryMap->create(mFileName, mFd, centralDirOffset, centralDirSize, true)) {
+ if (!mDirectoryMap->create(mFileName, mFd, dirOffset, dirSize, true)) {
ALOGW("Unable to map '%s' (" ZD " to " ZD "): %s\n", mFileName,
- (ZD_TYPE) centralDirOffset, (ZD_TYPE) (centralDirOffset + centralDirSize), strerror(errno));
+ (ZD_TYPE) dirOffset, (ZD_TYPE) (dirOffset + dirSize), strerror(errno));
return false;
}
mNumEntries = numEntries;
- mDirectoryOffset = centralDirOffset;
+ mDirectoryOffset = dirOffset;
return true;
}
@@ -375,30 +352,17 @@ bool ZipFileRO::parseZipArchive(void)
goto bail;
}
- unsigned int gpbf = get2LE(ptr + kCDEGPBFlags);
- if ((gpbf & kGPFUnsupportedMask) != 0) {
- ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
- goto bail;
- }
-
- unsigned int nameLen = get2LE(ptr + kCDENameLen);
- unsigned int extraLen = get2LE(ptr + kCDEExtraLen);
- unsigned int commentLen = get2LE(ptr + kCDECommentLen);
-
- const char *name = (const char *) ptr + kCDELen;
+ unsigned int fileNameLen, extraLen, commentLen, hash;
- /* Check name for NULL characters */
- if (memchr(name, 0, nameLen) != NULL) {
- ALOGW("Filename contains NUL byte");
- goto bail;
- }
+ fileNameLen = get2LE(ptr + kCDENameLen);
+ extraLen = get2LE(ptr + kCDEExtraLen);
+ commentLen = get2LE(ptr + kCDECommentLen);
/* add the CDE filename to the hash table */
- unsigned int hash = computeHash(name, nameLen);
- addToHash(name, nameLen, hash);
+ hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
+ addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
- /* We don't care about the comment or extra data. */
- ptr += kCDELen + nameLen + extraLen + commentLen;
+ ptr += kCDELen + fileNameLen + extraLen + commentLen;
if ((size_t)(ptr - cdPtr) > cdLength) {
ALOGW("bad CD advance (%d vs " ZD ") at entry %d\n",
(int) (ptr - cdPtr), (ZD_TYPE) cdLength, i);
@@ -511,10 +475,8 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
bool ret = false;
const int ent = entryToIndex(entry);
- if (ent < 0) {
- ALOGW("cannot find entry");
+ if (ent < 0)
return false;
- }
HashEntry hashEntry = mHashTable[ent];
@@ -623,12 +585,6 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
}
#endif /* HAVE_PREAD */
- unsigned int gpbf = get2LE(lfhBuf + kLFHGPBFlags);
- if ((gpbf & kGPFUnsupportedMask) != 0) {
- ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
- return false;
- }
-
off64_t dataOffset = localHdrOffset + kLFHLen
+ get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
if (dataOffset >= cdOffset) {
@@ -637,15 +593,14 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
}
/* check lengths */
- if ((dataOffset >= cdOffset) || (compLen >= (cdOffset - dataOffset))) {
+ if ((off64_t)(dataOffset + compLen) > cdOffset) {
ALOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
(long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
return false;
}
if (method == kCompressStored &&
- ((dataOffset >= cdOffset) ||
- (uncompLen >= (cdOffset - dataOffset))))
+ (off64_t)(dataOffset + uncompLen) > cdOffset)
{
ALOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
(long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
@@ -690,24 +645,14 @@ FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
*/
FileMap* newMap;
- int method;
- size_t uncompLen;
size_t compLen;
off64_t offset;
- if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+ if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
return NULL;
- }
-
- size_t actualLen;
- if (method == kCompressStored) {
- actualLen = uncompLen;
- } else {
- actualLen = compLen;
- }
newMap = new FileMap();
- if (!newMap->create(mFileName, mFd, offset, actualLen, true)) {
+ if (!newMap->create(mFileName, mFd, offset, compLen, true)) {
newMap->release();
return NULL;
}
@@ -726,21 +671,17 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
const size_t kSequentialMin = 32768;
bool result = false;
int ent = entryToIndex(entry);
- if (ent < 0) {
- return false;
- }
+ if (ent < 0)
+ return -1;
int method;
size_t uncompLen, compLen;
off64_t offset;
const unsigned char* ptr;
- FileMap *file;
- if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
- goto bail;
- }
+ getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
- file = createEntryFileMap(entry);
+ FileMap* file = createEntryFileMap(entry);
if (file == NULL) {
goto bail;
}
@@ -790,21 +731,17 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
{
bool result = false;
int ent = entryToIndex(entry);
- if (ent < 0) {
- return false;
- }
+ if (ent < 0)
+ return -1;
int method;
size_t uncompLen, compLen;
off64_t offset;
const unsigned char* ptr;
- FileMap *file;
- if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
- goto bail;
- }
+ getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
- file = createEntryFileMap(entry);
+ FileMap* file = createEntryFileMap(entry);
if (file == NULL) {
goto bail;
}
@@ -824,9 +761,8 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
ALOGI("+++ successful write\n");
}
} else {
- if (!inflateBuffer(fd, ptr, uncompLen, compLen)) {
+ if (!inflateBuffer(fd, ptr, uncompLen, compLen))
goto unmap;
- }
}
result = true;