optional AES and custom compressionLevel

This commit is contained in:
Antoine Cœur
2017-10-08 13:28:00 +08:00
parent df25a4a43e
commit 181bdc693e
9 changed files with 130 additions and 38 deletions
+15 -2
View File
@@ -70,6 +70,7 @@ typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
// Zip
// default compression level is Z_DEFAULT_COMPRESSION (from "zlib.h")
// without password
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths;
@@ -77,7 +78,8 @@ typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory;
// with password, password could be nil
// with optional password, default encryption is AES
// don't use AES if you need compatibility with native macOS unzip and Archive Utility
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths withPassword:(nullable NSString *)password;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath withPassword:(nullable NSString *)password;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(nullable NSString *)password;
@@ -86,17 +88,28 @@ typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
keepParentDirectory:(BOOL)keepParentDirectory
withPassword:(nullable NSString *)password
andProgressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath
keepParentDirectory:(BOOL)keepParentDirectory
compressionLevel:(int)compressionLevel
password:(nullable NSString *)password
AES:(BOOL)aes
progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
- (BOOL)open;
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password;
/// write empty folder
- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(nullable NSString *)password;
/// write file
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password;
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName withPassword:(nullable NSString *)password;
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes;
/// write data
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename withPassword:(nullable NSString *)password;
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes;
- (BOOL)close;
@end
+33 -24
View File
@@ -17,6 +17,7 @@ NSString *const SSZipArchiveErrorDomain = @"SSZipArchiveErrorDomain";
#define CHUNK 16384
int _zipOpenEntry(zipFile entry, NSString *name, const zip_fileinfo *zipfi, int level, NSString *password, BOOL aes);
BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
#ifndef API_AVAILABLE
@@ -656,6 +657,16 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
keepParentDirectory:(BOOL)keepParentDirectory
withPassword:(nullable NSString *)password
andProgressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler {
return [self createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:keepParentDirectory compressionLevel:Z_DEFAULT_COMPRESSION password:password AES:YES progressHandler:progressHandler];
}
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath
keepParentDirectory:(BOOL)keepParentDirectory
compressionLevel:(int)compressionLevel
password:(nullable NSString *)password
AES:(BOOL)aes
progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler {
SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];
BOOL success = [zipArchive open];
@@ -677,7 +688,7 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
}
if (!isDir) {
success &= [zipArchive writeFileAtPath:fullFilePath withFileName:fileName withPassword:password];
success &= [zipArchive writeFileAtPath:fullFilePath withFileName:fileName compressionLevel:compressionLevel password:password AES:aes];
}
else
{
@@ -724,37 +735,27 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
[SSZipArchive zipInfo:&zipInfo setAttributesOfItemAtPath:path];
int error = 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);
int error = _zipOpenEntry(_zip, [folderName stringByAppendingString:@"/"], &zipInfo, Z_NO_COMPRESSION, password, 0);
const void *buffer = NULL;
zipWriteInFileInZip(_zip, buffer, 0);
zipCloseFileInZip(_zip);
return error == ZIP_OK;
}
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password;
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password
{
return [self writeFileAtPath:path withFileName:nil withPassword:password];
}
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName withPassword:(nullable NSString *)password
{
return [self writeFileAtPath:path withFileName:fileName compressionLevel:Z_DEFAULT_COMPRESSION password:password AES:YES];
}
// supports writing files with logical folder/directory structure
// *path* is the absolute path of the file that will be compressed
// *fileName* is the relative name of the file how it is stored within the zip e.g. /folder/subfolder/text1.txt
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName withPassword:(nullable NSString *)password
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes
{
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
@@ -766,7 +767,6 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
if (!fileName) {
fileName = path.lastPathComponent;
}
const char *aFileName = fileName.fileSystemRepresentation;
zip_fileinfo zipInfo = {};
@@ -779,7 +779,7 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
return NO;
}
int error = 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);
int error = _zipOpenEntry(_zip, fileName, &zipInfo, compressionLevel, password, aes);
while (!feof(input) && !ferror(input))
{
@@ -793,7 +793,12 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
return error == ZIP_OK;
}
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename withPassword:(nullable NSString *)password;
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename withPassword:(nullable NSString *)password
{
return [self writeData:data filename:filename compressionLevel:Z_DEFAULT_COMPRESSION password:password AES:YES];
}
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes
{
if (!_zip) {
return NO;
@@ -804,7 +809,7 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
zip_fileinfo zipInfo = {};
[SSZipArchive zipInfo:&zipInfo setDate:[NSDate date]];
int error = 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);
int error = _zipOpenEntry(_zip, filename, &zipInfo, compressionLevel, password, aes);
zipWriteInFileInZip(_zip, data.bytes, (unsigned int)data.length);
@@ -812,7 +817,6 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
return error == ZIP_OK;
}
- (BOOL)close
{
NSAssert((_zip != NULL), @"[SSZipArchive] Attempting to close an archive which was never opened");
@@ -957,6 +961,11 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
@end
int _zipOpenEntry(zipFile entry, NSString *name, const zip_fileinfo *zipfi, int level, NSString *password, BOOL aes)
{
return zipOpenNewFileInZip5(entry, name.fileSystemRepresentation, zipfi, NULL, 0, NULL, 0, NULL, 0, 0, Z_DEFLATED, level, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password.UTF8String, aes);
}
#pragma mark - Private tools for file info
BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo)
+45 -5
View File
@@ -910,10 +910,25 @@ extern zipFile ZEXPORT zipOpen64(const void *path, int append)
return zipOpen3(path, append, 0, NULL, NULL);
}
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64)
extern int ZEXPORT zipOpenNewFileInZip_internal(zipFile file,
const char *filename,
const zip_fileinfo *zipfi,
const void *extrafield_local,
uint16_t size_extrafield_local,
const void *extrafield_global,
uint16_t size_extrafield_global,
const char *comment,
uint16_t flag_base,
int zip64,
uint16_t method,
int level,
int raw,
int windowBits,
int memLevel,
int strategy,
const char *password,
int aes,
uint16_t version_madeby)
{
zip64_internal *zi = NULL;
uint64_t size_available = 0;
@@ -978,7 +993,8 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, c
{
zi->ci.flag |= 1;
#ifdef HAVE_AES
zi->ci.method = AES_METHOD;
if (aes)
zi->ci.method = AES_METHOD;
#endif
}
else
@@ -1255,6 +1271,30 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, c
return err;
}
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi,
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
uint16_t size_extrafield_global, const char *comment, uint16_t flag_base, int zip64, uint16_t method, int level, int raw,
int windowBits, int memLevel, int strategy, const char *password, int aes)
{
return zipOpenNewFileInZip_internal(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
VERSIONMADEBY);
}
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64)
{
uint8_t aes = 0;
#ifdef HAVE_AES
aes = 1;
#endif
return zipOpenNewFileInZip_internal(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
version_madeby);
}
extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
+20
View File
@@ -166,6 +166,26 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, c
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64);
/* Same as zipOpenNewFileInZip4 with zip64 support */
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file,
const char *filename,
const zip_fileinfo *zipfi,
const void *extrafield_local,
uint16_t size_extrafield_local,
const void *extrafield_global,
uint16_t size_extrafield_global,
const char *comment,
uint16_t flag_base,
int zip64,
uint16_t method,
int level,
int raw,
int windowBits,
int memLevel,
int strategy,
const char *password,
int aes);
/* Allowing optional aes */
extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len);
/* Write data in the zipfile */