Merge pull request #390 from ZipArchive/empty_zip
compatibility with empty zip files
This commit is contained in:
@@ -7,6 +7,9 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3754B1331F88961C00A58AA0 /* Empty.zip in Resources */ = {isa = PBXBuildFile; fileRef = 3754B1311F88961800A58AA0 /* Empty.zip */; };
|
||||
3754B1341F88961D00A58AA0 /* Empty.zip in Resources */ = {isa = PBXBuildFile; fileRef = 3754B1311F88961800A58AA0 /* Empty.zip */; };
|
||||
3754B1351F88961E00A58AA0 /* Empty.zip in Resources */ = {isa = PBXBuildFile; fileRef = 3754B1311F88961800A58AA0 /* Empty.zip */; };
|
||||
3773ADB61F7F453E009A4B2D /* CollectingDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DFE1A131BDAA0A800709011 /* CollectingDelegate.m */; };
|
||||
3773ADB71F7F4541009A4B2D /* SSZipArchiveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DFE1A071BDA9FF300709011 /* SSZipArchiveTests.m */; };
|
||||
3773ADB81F7F4D13009A4B2D /* hello.zip in Resources */ = {isa = PBXBuildFile; fileRef = 8DFE1A161BDAA10100709011 /* hello.zip */; };
|
||||
@@ -83,6 +86,7 @@
|
||||
/* Begin PBXFileReference section */
|
||||
04CB37570807602F7E5C66D9 /* Pods-core-ObjectiveCExampleTests_macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-core-ObjectiveCExampleTests_macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-core-ObjectiveCExampleTests_macOS/Pods-core-ObjectiveCExampleTests_macOS.release.xcconfig"; sourceTree = "<group>"; };
|
||||
254DE0B206EE66F57BBE7EEE /* Pods-core-ObjectiveCExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-core-ObjectiveCExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-core-ObjectiveCExample/Pods-core-ObjectiveCExample.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3754B1311F88961800A58AA0 /* Empty.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Empty.zip; sourceTree = "<group>"; };
|
||||
3773ADAE1F7F44D8009A4B2D /* ObjectiveCExampleTests_macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ObjectiveCExampleTests_macOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3793E6D71F7F5F93000B1A19 /* ObjectiveCExampleTests_tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ObjectiveCExampleTests_tvOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
37FF0CB11F8533E0006E4361 /* CancelDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CancelDelegate.h; sourceTree = "<group>"; };
|
||||
@@ -251,6 +255,7 @@
|
||||
8DFE1A151BDAA10100709011 /* Fixtures */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3754B1311F88961800A58AA0 /* Empty.zip */,
|
||||
8DFE1A161BDAA10100709011 /* hello.zip */,
|
||||
8DFE1A171BDAA10100709011 /* IncorrectHeaders.zip */,
|
||||
8DFE1A181BDAA10100709011 /* PermissionsTestApp.app */,
|
||||
@@ -425,6 +430,7 @@
|
||||
3773ADC31F7F4D1C009A4B2D /* 3.m4a in Resources */,
|
||||
3773ADC21F7F4D1C009A4B2D /* 2.m4a in Resources */,
|
||||
3773ADC41F7F4D1C009A4B2D /* 4.m4a in Resources */,
|
||||
3754B1341F88961D00A58AA0 /* Empty.zip in Resources */,
|
||||
3773ADC01F7F4D1C009A4B2D /* 0.m4a in Resources */,
|
||||
3773ADC51F7F4D1C009A4B2D /* 5.m4a in Resources */,
|
||||
3773ADB91F7F4D13009A4B2D /* IncorrectHeaders.zip in Resources */,
|
||||
@@ -448,6 +454,7 @@
|
||||
3793E6E71F7F6052000B1A19 /* 6.m4a in Resources */,
|
||||
3793E6E91F7F6059000B1A19 /* hello.zip in Resources */,
|
||||
3793E6F01F7F605C000B1A19 /* PermissionsTestApp.app in Resources */,
|
||||
3754B1351F88961E00A58AA0 /* Empty.zip in Resources */,
|
||||
3793E6ED1F7F6059000B1A19 /* TestArchive.zip in Resources */,
|
||||
3793E6E61F7F6052000B1A19 /* 5.m4a in Resources */,
|
||||
3793E6E41F7F6052000B1A19 /* 3.m4a in Resources */,
|
||||
@@ -482,6 +489,7 @@
|
||||
8DFE1A321BDAA10100709011 /* 3.m4a in Resources */,
|
||||
8DFE1A311BDAA10100709011 /* 2.m4a in Resources */,
|
||||
8DFE1A331BDAA10100709011 /* 4.m4a in Resources */,
|
||||
3754B1331F88961C00A58AA0 /* Empty.zip in Resources */,
|
||||
8DFE1A2F1BDAA10100709011 /* 0.m4a in Resources */,
|
||||
8DFE1A341BDAA10100709011 /* 5.m4a in Resources */,
|
||||
8DFE1A2D1BDAA10100709011 /* TestPasswordArchive.zip in Resources */,
|
||||
|
||||
BIN
ObjectiveCExample/ObjectiveCExampleTests/Fixtures/Empty.zip
Normal file
BIN
ObjectiveCExample/ObjectiveCExampleTests/Fixtures/Empty.zip
Normal file
Binary file not shown.
@@ -313,6 +313,14 @@
|
||||
XCTAssertTrue(unicodeFolderWasExtracted, @"Folders with names in unicode should be extracted propertly.");
|
||||
}
|
||||
|
||||
- (void)testUnzippingEmptyArchive {
|
||||
|
||||
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"Empty" ofType:@"zip"];
|
||||
NSString *outputPath = [self _cachesPath:@"Empty"];
|
||||
|
||||
BOOL success = [SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:nil];
|
||||
XCTAssertTrue(success);
|
||||
}
|
||||
|
||||
- (void)testZippingAndUnzippingForDate {
|
||||
|
||||
|
||||
@@ -248,7 +248,9 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
unzGetGlobalInfo(zip, &globalInfo);
|
||||
|
||||
// Begin unzipping
|
||||
if (unzGoToFirstFile(zip) != UNZ_OK)
|
||||
int ret = 0;
|
||||
ret = unzGoToFirstFile(zip);
|
||||
if (ret != UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE)
|
||||
{
|
||||
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open first file in zip file"};
|
||||
NSError *err = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFailedOpenFileInZip userInfo:userInfo];
|
||||
@@ -265,7 +267,6 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
BOOL success = YES;
|
||||
BOOL canceled = NO;
|
||||
int ret = 0;
|
||||
int crc_ret = 0;
|
||||
unsigned char buffer[4096] = {0};
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
@@ -282,6 +283,8 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
NSInteger currentFileNumber = 0;
|
||||
NSError *unzippingError;
|
||||
do {
|
||||
if (ret == UNZ_END_OF_LIST_OF_FILE)
|
||||
break;
|
||||
@autoreleasepool {
|
||||
if (password.length == 0) {
|
||||
ret = unzOpenCurrentFile(zip);
|
||||
|
||||
@@ -252,19 +252,19 @@ static int unzReadUInt64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidp
|
||||
}
|
||||
|
||||
/* Locate the Central directory of a zip file (at the end, just before the global comment) */
|
||||
static uint64_t unzSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)
|
||||
static int unzSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, uint64_t *pos_found, voidpf filestream)
|
||||
{
|
||||
uint8_t buf[BUFREADCOMMENT + 4];
|
||||
uint64_t file_size = 0;
|
||||
uint64_t back_read = 4;
|
||||
uint64_t max_back = UINT16_MAX; /* maximum size of global comment */
|
||||
uint64_t pos_found = 0;
|
||||
uint32_t read_size = 0;
|
||||
uint64_t read_pos = 0;
|
||||
uint32_t i = 0;
|
||||
*pos_found = 0;
|
||||
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
|
||||
file_size = ZTELL64(*pzlib_filefunc_def, filestream);
|
||||
|
||||
@@ -293,52 +293,49 @@ static uint64_t unzSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc
|
||||
((*(buf+i+2)) == (ENDHEADERMAGIC >> 16 & 0xff)) &&
|
||||
((*(buf+i+3)) == (ENDHEADERMAGIC >> 24 & 0xff)))
|
||||
{
|
||||
pos_found = read_pos+i;
|
||||
break;
|
||||
*pos_found = read_pos+i;
|
||||
return UNZ_OK;
|
||||
}
|
||||
|
||||
if (pos_found != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return pos_found;
|
||||
return UNZ_ERRNO;
|
||||
}
|
||||
|
||||
/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */
|
||||
static uint64_t unzSearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
|
||||
static int unzSearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, uint64_t *offset, voidpf filestream,
|
||||
const uint64_t endcentraloffset)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
uint32_t value32 = 0;
|
||||
*offset = 0;
|
||||
|
||||
/* Zip64 end of central directory locator */
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
|
||||
/* Read locator signature */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
if (value32 != ZIP64ENDLOCHEADERMAGIC)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
/* Number of the disk with the start of the zip64 end of central directory */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
/* Relative offset of the zip64 end of central directory record */
|
||||
if (unzReadUInt64(pzlib_filefunc_def, filestream, &offset) != UNZ_OK)
|
||||
return 0;
|
||||
if (unzReadUInt64(pzlib_filefunc_def, filestream, offset) != UNZ_OK)
|
||||
return UNZ_ERRNO;
|
||||
/* Total number of disks */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
/* Goto end of central directory record */
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
return 0;
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, *offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
return UNZ_ERRNO;
|
||||
/* The signature */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
if (value32 != ZIP64ENDHEADERMAGIC)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
|
||||
return offset;
|
||||
return UNZ_OK;
|
||||
}
|
||||
|
||||
static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_filefunc64_32_def)
|
||||
@@ -373,8 +370,8 @@ static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_f
|
||||
us.is_zip64 = 0;
|
||||
|
||||
/* Search for end of central directory header */
|
||||
central_pos = unzSearchCentralDir(&us.z_filefunc, us.filestream);
|
||||
if (central_pos)
|
||||
err = unzSearchCentralDir(&us.z_filefunc, ¢ral_pos, us.filestream);
|
||||
if (err == UNZ_OK)
|
||||
{
|
||||
if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
err = UNZ_ERRNO;
|
||||
@@ -415,8 +412,8 @@ static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_f
|
||||
if (err == UNZ_OK)
|
||||
{
|
||||
/* Search for Zip64 end of central directory header */
|
||||
central_pos64 = unzSearchCentralDir64(&us.z_filefunc, us.filestream, central_pos);
|
||||
if (central_pos64)
|
||||
int err64 = unzSearchCentralDir64(&us.z_filefunc, ¢ral_pos64, us.filestream, central_pos);
|
||||
if (err64 == UNZ_OK)
|
||||
{
|
||||
central_pos = central_pos64;
|
||||
us.is_zip64 = 1;
|
||||
@@ -1668,6 +1665,9 @@ extern int ZEXPORT unzGoToFirstFile2(unzFile file, unz_file_info64 *pfile_info,
|
||||
return UNZ_PARAMERROR;
|
||||
s = (unz64_internal*)file;
|
||||
|
||||
if (s->gi.number_entry == 0)
|
||||
return UNZ_END_OF_LIST_OF_FILE;
|
||||
|
||||
s->pos_in_central_dir = s->offset_central_dir;
|
||||
s->num_file = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user