Prevent the accidental closure of fd[0] for missing zip files.

(cherry picked from commit b1a113f618)
Bug: 16530747

Change-Id: I0d1be3dcadfa5128ffe04cec60f6c998dff61991
This commit is contained in:
Neil Fuller 2014-07-25 14:43:04 +01:00
parent 64567d165a
commit 0047368d7d
2 changed files with 33 additions and 22 deletions

View File

@ -287,7 +287,7 @@ static const char kTempMappingFileName[] = "zip: ExtractFileToFile";
*/
struct ZipArchive {
/* open Zip archive */
int fd;
const int fd;
/* mapped central directory area */
off64_t directory_offset;
@ -304,6 +304,25 @@ struct ZipArchive {
*/
uint32_t hash_table_size;
ZipEntryName* hash_table;
ZipArchive(const int fd) :
fd(fd),
directory_offset(0),
directory_map(NULL),
num_entries(0),
hash_table_size(0),
hash_table(NULL) {}
~ZipArchive() {
if (fd >= 0) {
close(fd);
}
if (directory_map != NULL) {
directory_map->release();
}
free(hash_table);
}
};
// Returns 0 on success and negative values on failure.
@ -661,28 +680,20 @@ static int32_t OpenArchiveInternal(ZipArchive* archive,
int32_t OpenArchiveFd(int fd, const char* debug_file_name,
ZipArchiveHandle* handle) {
ZipArchive* archive = (ZipArchive*) malloc(sizeof(ZipArchive));
memset(archive, 0, sizeof(*archive));
ZipArchive* archive = new ZipArchive(fd);
*handle = archive;
archive->fd = fd;
return OpenArchiveInternal(archive, debug_file_name);
}
int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle) {
ZipArchive* archive = (ZipArchive*) malloc(sizeof(ZipArchive));
memset(archive, 0, sizeof(*archive));
const int fd = open(fileName, O_RDONLY | O_BINARY, 0);
ZipArchive* archive = new ZipArchive(fd);
*handle = archive;
const int fd = open(fileName, O_RDONLY | O_BINARY, 0);
if (fd < 0) {
ALOGW("Unable to open '%s': %s", fileName, strerror(errno));
return kIoError;
} else {
archive->fd = fd;
}
return OpenArchiveInternal(archive, fileName);
}
@ -692,16 +703,7 @@ int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle) {
void CloseArchive(ZipArchiveHandle handle) {
ZipArchive* archive = (ZipArchive*) handle;
ALOGV("Closing archive %p", archive);
if (archive->fd >= 0) {
close(archive->fd);
}
if (archive->directory_map != NULL) {
archive->directory_map->release();
}
free(archive->hash_table);
free(archive);
delete archive;
}
static int32_t UpdateEntryFromDataDescriptor(int fd,

View File

@ -26,6 +26,7 @@
static std::string test_data_dir;
static const std::string kMissingZip = "missing.zip";
static const std::string kValidZip = "valid.zip";
static const uint8_t kATxtContents[] = {
@ -58,6 +59,14 @@ TEST(ziparchive, Open) {
CloseArchive(handle);
}
TEST(ziparchive, OpenMissing) {
ZipArchiveHandle handle;
ASSERT_NE(0, OpenArchiveWrapper(kMissingZip, &handle));
// Confirm the file descriptor is not going to be mistaken for a valid one.
ASSERT_EQ(-1, GetFileDescriptor(handle));
}
TEST(ziparchive, Iteration) {
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));