diff --git a/ObjectiveCExample/ObjectiveCExample.xcodeproj/project.pbxproj b/ObjectiveCExample/ObjectiveCExample.xcodeproj/project.pbxproj index 45566a6..4eab62c 100644 --- a/ObjectiveCExample/ObjectiveCExample.xcodeproj/project.pbxproj +++ b/ObjectiveCExample/ObjectiveCExample.xcodeproj/project.pbxproj @@ -265,7 +265,7 @@ 8DFE19E21BDA9FF300709011 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0710; + LastUpgradeCheck = 0820; TargetAttributes = { 8DFE19E91BDA9FF300709011 = { CreatedOnToolsVersion = 7.1; @@ -488,8 +488,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -532,8 +534,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; diff --git a/ObjectiveCExample/ObjectiveCExample.xcodeproj/xcshareddata/xcschemes/ObjectiveCExample.xcscheme b/ObjectiveCExample/ObjectiveCExample.xcodeproj/xcshareddata/xcschemes/ObjectiveCExample.xcscheme index 53d4817..bea96e0 100644 --- a/ObjectiveCExample/ObjectiveCExample.xcodeproj/xcshareddata/xcschemes/ObjectiveCExample.xcscheme +++ b/ObjectiveCExample/ObjectiveCExample.xcodeproj/xcshareddata/xcschemes/ObjectiveCExample.xcscheme @@ -1,6 +1,6 @@ )delegate progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler - completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler + completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError * __nullable error))completionHandler { // Begin opening zipFile zip = unzOpen((const char*)[path UTF8String]); @@ -304,77 +373,80 @@ } if (!fileIsSymbolicLink) { - FILE *fp = fopen((const char*)[fullPath UTF8String], "wb"); - while (fp) { - int readBytes = unzReadCurrentFile(zip, buffer, 4096); - - if (readBytes > 0) { - fwrite(buffer, readBytes, 1, fp ); - } else { - break; - } - } - - 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 ]) { - [[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil]; + // 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"); + while (fp) { + if (readBytes > 0) { + fwrite(buffer, readBytes, 1, fp ); + } else { + break; } + readBytes = unzReadCurrentFile(zip, buffer, 4096); } - - fclose(fp); - - if (preserveAttributes) { - - // Set the original datetime property - if (fileInfo.dosDate != 0) { - NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate]; - NSDictionary *attr = @{NSFileModificationDate: orgDate}; - if (attr) { - if ([fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] == NO) { - // Can't set attributes - NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting modification date"); + 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 ]) { + [[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil]; + } + } + + fclose(fp); + + if (preserveAttributes) { + + // Set the original datetime property + if (fileInfo.dosDate != 0) { + NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate]; + NSDictionary *attr = @{NSFileModificationDate: orgDate}; + + if (attr) { + if ([fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] == NO) { + // Can't set attributes + NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting modification date"); + } } } - } - - // Set the original permissions on the file - uLong permissions = fileInfo.external_fa >> 16; - if (permissions != 0) { - // Store it into a NSNumber - NSNumber *permissionsValue = @(permissions); - // Retrieve any existing attributes - NSMutableDictionary *attrs = [[NSMutableDictionary alloc] initWithDictionary:[fileManager attributesOfItemAtPath:fullPath error:nil]]; + // Set the original permissions on the file + uLong permissions = fileInfo.external_fa >> 16; + if (permissions != 0) { + // Store it into a NSNumber + NSNumber *permissionsValue = @(permissions); - // Set the value in the attributes dict - attrs[NSFilePosixPermissions] = permissionsValue; + // Retrieve any existing attributes + NSMutableDictionary *attrs = [[NSMutableDictionary alloc] initWithDictionary:[fileManager attributesOfItemAtPath:fullPath error:nil]]; - // Update attributes - if ([fileManager setAttributes:attrs ofItemAtPath:fullPath error:nil] == NO) { - // Unable to set the permissions attribute - NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting permissions"); - } + // Set the value in the attributes dict + attrs[NSFilePosixPermissions] = permissionsValue; + + // Update attributes + if ([fileManager setAttributes:attrs ofItemAtPath:fullPath error:nil] == NO) { + // Unable to set the permissions attribute + NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting permissions"); + } #if !__has_feature(objc_arc) - [attrs release]; + [attrs release]; #endif + } } } - } - else - { - // if we couldn't open file descriptor we can validate global errno to see the reason - if (errno == ENOSPC) { - NSError *enospcError = [NSError errorWithDomain:NSPOSIXErrorDomain - code:ENOSPC - userInfo:nil]; - unzippingError = enospcError; - unzCloseCurrentFile(zip); - success = NO; - break; + else + { + // if we couldn't open file descriptor we can validate global errno to see the reason + if (errno == ENOSPC) { + NSError *enospcError = [NSError errorWithDomain:NSPOSIXErrorDomain + code:ENOSPC + userInfo:nil]; + unzippingError = enospcError; + unzCloseCurrentFile(zip); + success = NO; + break; + } } } } @@ -519,15 +591,6 @@ + (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(nullable NSString *)password{ - return [self createZipFileAtPath:password - withContentsOfDirectory:directoryPath - keepParentDirectory:keepParentDirectory - withPassword:password - andProgressHandler:nil - ]; -} - -+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(nullable NSString *)password andProgressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler { BOOL success = NO; NSFileManager *fileManager = nil; @@ -537,10 +600,8 @@ // use a local filemanager (queue/thread compatibility) fileManager = [[NSFileManager alloc] init]; NSDirectoryEnumerator *dirEnumerator = [fileManager enumeratorAtPath:directoryPath]; - NSArray *allObjects = dirEnumerator.allObjects; - NSUInteger total = allObjects.count, complete = 0; NSString *fileName; - for (fileName in allObjects) { + while ((fileName = [dirEnumerator nextObject])) { BOOL isDir; NSString *fullFilePath = [directoryPath stringByAppendingPathComponent:fileName]; [fileManager fileExistsAtPath:fullFilePath isDirectory:&isDir]; @@ -562,10 +623,6 @@ [zipArchive writeFileAtPath:tempFilePath withFileName:tempFileFilename withPassword:password]; } } - complete++; - if (progressHandler) { - progressHandler(complete, total); - } } success = [zipArchive close]; } @@ -828,4 +885,4 @@ return date; } -@end +@end \ No newline at end of file diff --git a/SSZipArchive/minizip/unzip.c b/SSZipArchive/minizip/unzip.c index 4b8eabc..35aaf88 100755 --- a/SSZipArchive/minizip/unzip.c +++ b/SSZipArchive/minizip/unzip.c @@ -1190,7 +1190,8 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, in return UNZ_INTERNALERROR; #ifdef HAVE_AES if (s->cur_file_info.compression_method == AES_METHOD) { - unsigned char passverify[AES_PWVERIFYSIZE]; + unsigned char passverify_archive[AES_PWVERIFYSIZE]; + unsigned char passverify_password[AES_PWVERIFYSIZE]; unsigned char saltvalue[AES_MAXSALTLENGTH]; uInt saltlength; @@ -1202,11 +1203,14 @@ extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, in if (ZREAD64(s->z_filefunc, s->filestream, saltvalue, saltlength) != saltlength) return UNZ_INTERNALERROR; - if (ZREAD64(s->z_filefunc, s->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE) + if (ZREAD64(s->z_filefunc, s->filestream, passverify_archive, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE) return UNZ_INTERNALERROR; - fcrypt_init((int)s->cur_file_info_internal.aes_encryption_mode, (unsigned char *)password, (unsigned int)strlen(password), saltvalue, - passverify, &s->pfile_in_zip_read->aes_ctx); + fcrypt_init(s->cur_file_info_internal.aes_encryption_mode, password, strlen(password), saltvalue, + passverify_password, &s->pfile_in_zip_read->aes_ctx); + + if (memcmp(passverify_archive, passverify_password, AES_PWVERIFYSIZE) != 0) + return UNZ_BADPASSWORD; pfile_in_zip_read_info->rest_read_compressed -= saltlength + AES_PWVERIFYSIZE; pfile_in_zip_read_info->rest_read_compressed -= AES_AUTHCODESIZE; diff --git a/SSZipArchive/minizip/unzip.h b/SSZipArchive/minizip/unzip.h index 7b614ff..d6954d3 100755 --- a/SSZipArchive/minizip/unzip.h +++ b/SSZipArchive/minizip/unzip.h @@ -57,6 +57,7 @@ typedef voidp unzFile; #define UNZ_BADZIPFILE (-103) #define UNZ_INTERNALERROR (-104) #define UNZ_CRCERROR (-105) +#define UNZ_BADPASSWORD (-106) /***************************************************************************/