14 Commits
v1.7 ... v1.8

Author SHA1 Message Date
Joshua Hudson
98eeb1a862 Merge pull request #328 from MaddTheSane/fileSysRep
Use -fileSystemRepresentation for file names
2017-03-28 10:35:48 -07:00
Joshua Hudson
18703ddb15 Merge pull request #322 from Gucky/master
Public constants for error domain and error codes
2017-03-28 10:35:31 -07:00
Joshua Hudson
fc6123aae5 Merge pull request #318 from Coeur/errorForCompletionHandler
giving an NSError to completionHandler on failure
2017-03-28 10:34:37 -07:00
Joshua Hudson
4aa70f4237 Merge pull request #317 from Coeur/codeFormat
more consistent code format
2017-03-28 10:34:28 -07:00
Wolfgang Muhsal
4aaec09339 Merge pull request #1 from MaddTheSane/errDomains
Fix duplicate symbols of SSZipArchiveErrorDomain.
2017-03-28 17:18:31 +02:00
C.W. Betts
6614014ecc Fix duplicate symbols of SSZipArchiveErrorDomain. 2017-03-28 09:14:39 -06:00
C.W. Betts
ea2f4fc321 Use -fileSystemRepresentation for file names. 2017-03-28 09:04:05 -06:00
Wolfgang Muhsal
e451317de6 Public constants for error domain and error codes 2017-03-15 10:57:46 +01:00
Antoine Cœur
05789bd171 giving an NSError to completionHandler on failure; always calling completionHandler 2017-02-24 14:04:41 +08:00
Antoine Cœur
451fadc9be more consistent code format 2017-02-24 13:32:28 +08:00
Joshua Hudson
98c0fbf084 Add test for invalid password 2017-02-13 15:42:50 -08:00
Joshua Hudson
032173ba3d Pod loc file updated 2017-01-31 13:04:54 -08:00
Joshua Hudson
c063640a55 Merge pull request #311 from Coeur/xcodeWarning
Fix Xcode 8.3 beta warning message by changing code structure: if directoryCreated is false, we can’t call writeToFile:atomically:encoding:error:
2017-01-30 10:58:08 -08:00
Antoine Cœur
23db0c4b7d Xcode warning: if directoryCreated is false, we can’t call writeToFile:atomically:encoding:error: 2017-01-28 22:47:43 +08:00
5 changed files with 89 additions and 58 deletions

View File

@@ -173,7 +173,23 @@
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"LICENSE unzipped");
}
- (void)testValidatePassword {
- (void)testUnzippingWithInvalidPassword {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestPasswordArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Password"];
NSError *error = nil;
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath overwrite:YES password:@"passw0rd123" error:&error delegate:self];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [outputPath stringByAppendingPathComponent:@"Readme.markdown"];
XCTAssertFalse([fileManager fileExistsAtPath:testPath], @"Readme not unzipped");
testPath = [outputPath stringByAppendingPathComponent:@"LICENSE"];
XCTAssertFalse([fileManager fileExistsAtPath:testPath], @"LICENSE not unzipped");
}
- (void)testIsPasswordInvalidForArchiveAtPath {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestPasswordArchive" ofType:@"zip"];
NSError *error = nil;
@@ -188,7 +204,7 @@
}
- (void)testFilePasswordCheck {
- (void)testIsFilePasswordProtectedAtPath {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestArchive" ofType:@"zip"];
BOOL protected = [SSZipArchive isFilePasswordProtectedAtPath:zipPath];

View File

@@ -13,4 +13,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: ae5fb993e5dc339b15e10067d1e60549fa585f32
COCOAPODS: 1.1.1
COCOAPODS: 1.2.0

View File

@@ -14,6 +14,14 @@
NS_ASSUME_NONNULL_BEGIN
extern NSString *const SSZipArchiveErrorDomain;
typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
SSZipArchiveErrorCodeFailedOpenZipFile = -1,
SSZipArchiveErrorCodeFailedOpenFirstFile = -2,
SSZipArchiveErrorCodeFileInfoNotLoadable = -3,
SSZipArchiveErrorCodeFileContentNotReadable = -4,
};
@protocol SSZipArchiveDelegate;
@interface SSZipArchive : NSObject

View File

@@ -13,6 +13,8 @@
#include <sys/stat.h>
NSString *const SSZipArchiveErrorDomain = @"SSZipArchiveErrorDomain";
#define CHUNK 16384
@interface SSZipArchive ()
@@ -30,7 +32,7 @@
+ (BOOL)isFilePasswordProtectedAtPath:(NSString *)path {
// Begin opening
zipFile zip = unzOpen((const char*)[path UTF8String]);
zipFile zip = unzOpen((const char*)[path fileSystemRepresentation]);
if (zip == NULL) {
return NO;
}
@@ -39,21 +41,20 @@
if (ret == UNZ_OK) {
do {
ret = unzOpenCurrentFile(zip);
if( ret!=UNZ_OK ) {
if (ret != UNZ_OK) {
return NO;
}
unz_file_info fileInfo ={0};
unz_file_info fileInfo = {0};
ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
if (ret!= UNZ_OK) {
if (ret != UNZ_OK) {
return NO;
} else if((fileInfo.flag & 1) == 1) {
} else if ((fileInfo.flag & 1) == 1) {
return YES;
}
unzCloseCurrentFile(zip);
ret = unzGoToNextFile(zip);
} while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE );
} while (ret == UNZ_OK && UNZ_OK != UNZ_END_OF_LIST_OF_FILE);
}
return NO;
@@ -64,11 +65,11 @@
*error = nil;
}
zipFile zip = unzOpen((const char*)[path UTF8String]);
zipFile zip = unzOpen((const char*)[path fileSystemRepresentation]);
if (zip == NULL) {
if (error) {
*error = [NSError errorWithDomain:@"SSZipArchiveErrorDomain"
code:-1
*error = [NSError errorWithDomain:SSZipArchiveErrorDomain
code:SSZipArchiveErrorCodeFailedOpenZipFile
userInfo:@{NSLocalizedDescriptionKey: @"failed to open zip file"}];
}
return NO;
@@ -85,8 +86,8 @@
if (ret != UNZ_OK) {
if (ret != UNZ_BADPASSWORD) {
if (error) {
*error = [NSError errorWithDomain:@"SSZipArchiveErrorDomain"
code:-2
*error = [NSError errorWithDomain:SSZipArchiveErrorDomain
code:SSZipArchiveErrorCodeFailedOpenFirstFile
userInfo:@{NSLocalizedDescriptionKey: @"failed to open first file in zip file"}];
}
}
@@ -96,20 +97,20 @@
ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
if (ret != UNZ_OK) {
if (error) {
*error = [NSError errorWithDomain:@"SSZipArchiveErrorDomain"
code:-3
*error = [NSError errorWithDomain:SSZipArchiveErrorDomain
code:SSZipArchiveErrorCodeFileInfoNotLoadable
userInfo:@{NSLocalizedDescriptionKey: @"failed to retrieve info for file"}];
}
return NO;
} else if((fileInfo.flag & 1) == 1) {
} else if ((fileInfo.flag & 1) == 1) {
unsigned char buffer[10] = {0};
int readBytes = unzReadCurrentFile(zip, buffer, (unsigned)MIN(10UL,fileInfo.uncompressed_size));
if (readBytes < 0) {
// Let's assume the invalid password caused this error
if (readBytes != Z_DATA_ERROR) {
if (error) {
*error = [NSError errorWithDomain:@"SSZipArchiveErrorDomain"
code:-4
*error = [NSError errorWithDomain:SSZipArchiveErrorDomain
code:SSZipArchiveErrorCodeFileContentNotReadable
userInfo:@{NSLocalizedDescriptionKey: @"failed to read contents of file entry"}];
}
}
@@ -120,8 +121,7 @@
unzCloseCurrentFile(zip);
ret = unzGoToNextFile(zip);
} while (ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE);
} while (ret == UNZ_OK && UNZ_OK != UNZ_END_OF_LIST_OF_FILE);
}
// No password required
@@ -190,11 +190,11 @@
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError * __nullable error))completionHandler
{
// Begin opening
zipFile zip = unzOpen((const char*)[path UTF8String]);
zipFile zip = unzOpen((const char*)[path fileSystemRepresentation]);
if (zip == NULL)
{
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open zip file"};
NSError *err = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-1 userInfo:userInfo];
NSError *err = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFailedOpenZipFile userInfo:userInfo];
if (error)
{
*error = err;
@@ -217,7 +217,7 @@
if (unzGoToFirstFile(zip) != UNZ_OK)
{
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open first file in zip file"};
NSError *err = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-2 userInfo:userInfo];
NSError *err = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFailedOpenFirstFile userInfo:userInfo];
if (error)
{
*error = err;
@@ -232,7 +232,7 @@
BOOL success = YES;
BOOL canceled = NO;
int ret = 0;
int crc_ret =0;
int crc_ret = 0;
unsigned char buffer[4096] = {0};
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableArray *directoriesModificationDates = [[NSMutableArray alloc] init];
@@ -256,6 +256,7 @@
}
if (ret != UNZ_OK) {
unzippingError = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-2 userInfo:@{NSLocalizedDescriptionKey: @"failed to open file in zip file"}];
success = NO;
break;
}
@@ -266,6 +267,7 @@
ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
if (ret != UNZ_OK) {
unzippingError = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-3 userInfo:@{NSLocalizedDescriptionKey: @"failed to retrieve info for file"}];
success = NO;
unzCloseCurrentFile(zip);
break;
@@ -294,7 +296,8 @@
char *filename = (char *)malloc(fileInfo.size_filename + 1);
if (filename == NULL)
{
return NO;
success = NO;
break;
}
unzGetCurrentFileInfo(zip, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0);
@@ -376,10 +379,10 @@
// ensure we are not creating stale file entries
int readBytes = unzReadCurrentFile(zip, buffer, 4096);
if (readBytes >= 0) {
FILE *fp = fopen((const char*)[fullPath UTF8String], "wb");
FILE *fp = fopen((const char*)[fullPath fileSystemRepresentation], "wb");
while (fp) {
if (readBytes > 0) {
fwrite(buffer, readBytes, 1, fp );
fwrite(buffer, readBytes, 1, fp);
} else {
break;
}
@@ -389,7 +392,7 @@
if (fp) {
if ([[[fullPath pathExtension] lowercaseString] isEqualToString:@"zip"]) {
NSLog(@"Unzipping nested .zip file: %@", [fullPath lastPathComponent]);
if ([self unzipFileAtPath:fullPath toDestination:[fullPath stringByDeletingLastPathComponent] overwrite:overwrite password:password error:nil delegate:nil ]) {
if ([self unzipFileAtPath:fullPath toDestination:[fullPath stringByDeletingLastPathComponent] overwrite:overwrite password:password error:nil delegate:nil]) {
[[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];
}
}
@@ -455,7 +458,7 @@
// Assemble the path for the symbolic link
NSMutableString* destinationPath = [NSMutableString string];
int bytesRead = 0;
while((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0)
while ((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0)
{
buffer[bytesRead] = (int)0;
[destinationPath appendString:@((const char*)buffer)];
@@ -465,19 +468,19 @@
int symlinkError = symlink([destinationPath cStringUsingEncoding:NSUTF8StringEncoding],
[fullPath cStringUsingEncoding:NSUTF8StringEncoding]);
if(symlinkError != 0)
if (symlinkError != 0)
{
NSLog(@"Failed to create symbolic link at \"%@\" to \"%@\". symlink() error code: %d", fullPath, destinationPath, errno);
}
}
crc_ret = unzCloseCurrentFile( zip );
crc_ret = unzCloseCurrentFile(zip);
if (crc_ret == UNZ_CRCERROR) {
//CRC ERROR
success = NO;
break;
}
ret = unzGoToNextFile( zip );
ret = unzGoToNextFile(zip);
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
@@ -494,7 +497,7 @@
progressHandler(strPath, fileInfo, currentFileNumber, globalInfo.number_entry);
}
}
} while(ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE);
} while (ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE);
// Close
unzClose(zip);
@@ -530,7 +533,7 @@
if (crc_ret == UNZ_CRCERROR)
{
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"crc check failed for file"};
retErr = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-3 userInfo:userInfo];
retErr = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFileInfoNotLoadable userInfo:userInfo];
}
if (error) {
@@ -592,10 +595,10 @@
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(nullable NSString *)password{
return [SSZipArchive createZipFileAtPath:path
withContentsOfDirectory:directoryPath
keepParentDirectory:keepParentDirectory
withPassword:password
andProgressHandler:nil
withContentsOfDirectory:directoryPath
keepParentDirectory:keepParentDirectory
withPassword:password
andProgressHandler:nil
];
}
@@ -627,7 +630,7 @@
}
else
{
if([[NSFileManager defaultManager] subpathsOfDirectoryAtPath:fullFilePath error:nil].count == 0)
if ([[NSFileManager defaultManager] subpathsOfDirectoryAtPath:fullFilePath error:nil].count == 0)
{
NSString *tempFilePath = [self _temporaryPathForDiscardableFile];
NSString *tempFileFilename = [fileName stringByAppendingPathComponent:tempFilePath.lastPathComponent];
@@ -672,7 +675,7 @@
- (BOOL)open
{
NSAssert((_zip == NULL), @"Attempting open an archive which is already open");
_zip = zipOpen([_path UTF8String], APPEND_STATUS_CREATE);
_zip = zipOpen([_path fileSystemRepresentation], APPEND_STATUS_CREATE);
return (NULL != _zip);
}
@@ -701,12 +704,12 @@
zip_fileinfo zipInfo = {{0}};
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
if( attr )
if (attr)
{
NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];
if( fileDate )
if (fileDate)
{
[self zipInfo:&zipInfo setDate: fileDate ];
[self zipInfo:&zipInfo setDate: fileDate];
}
// Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727
@@ -728,7 +731,7 @@
}
unsigned int len = 0;
zipOpenNewFileInZip3(_zip, [[folderName stringByAppendingString:@"/"] UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL,
zipOpenNewFileInZip3(_zip, [[folderName stringByAppendingString:@"/"] fileSystemRepresentation], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY, [password UTF8String], 0);
zipWriteInFileInZip(_zip, &len, 0);
zipCloseFileInZip(_zip);
@@ -747,28 +750,28 @@
{
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
FILE *input = fopen([path UTF8String], "r");
FILE *input = fopen([path fileSystemRepresentation], "r");
if (NULL == input) {
return NO;
}
const char *afileName;
if (!fileName) {
afileName = [path.lastPathComponent UTF8String];
afileName = [path.lastPathComponent fileSystemRepresentation];
}
else {
afileName = [fileName UTF8String];
afileName = [fileName fileSystemRepresentation];
}
zip_fileinfo zipInfo = {{0}};
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
if( attr )
if (attr)
{
NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];
if( fileDate )
if (fileDate)
{
[self zipInfo:&zipInfo setDate: fileDate ];
[self zipInfo:&zipInfo setDate: fileDate];
}
// Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727
@@ -798,7 +801,7 @@
zipOpenNewFileInZip3(_zip, afileName, &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, [password UTF8String], 0);
unsigned int len = 0;
while(!feof(input) && !ferror(input))
while (!feof(input) && !ferror(input))
{
len = (unsigned int) fread(buffer, 1, CHUNK, input);
zipWriteInFileInZip(_zip, buffer, len);
@@ -821,7 +824,7 @@
zip_fileinfo zipInfo = {{0,0,0,0,0,0},0,0,0};
[self zipInfo:&zipInfo setDate:[NSDate date]];
zipOpenNewFileInZip3(_zip, [filename UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, [password UTF8String], 0);
zipOpenNewFileInZip3(_zip, [filename fileSystemRepresentation], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, [password UTF8String], 0);
zipWriteInFileInZip(_zip, data.bytes, (unsigned int)data.length);
@@ -848,8 +851,10 @@
NSString *temporaryDirectoryName = [[NSUUID UUID] UUIDString];
NSString *temporaryDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:temporaryDirectoryName];
BOOL directoryCreated = [[NSFileManager defaultManager] createDirectoryAtPath:temporaryDirectory withIntermediateDirectories:YES attributes:nil error:nil];
discardableFilePath = directoryCreated ? [temporaryDirectory stringByAppendingPathComponent:discardableFileName] : nil;
[@"" writeToFile:discardableFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (directoryCreated) {
discardableFilePath = [temporaryDirectory stringByAppendingPathComponent:discardableFileName];
[@"" writeToFile:discardableFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
});
return discardableFilePath;
}

View File

@@ -463,6 +463,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -476,7 +477,7 @@
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
@@ -511,6 +512,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -524,7 +526,7 @@
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 1;