Merge pull request #23 from jparishy/master

Fix for issues with Unicode filenames and Symbolic Links. Fixes #14
This commit is contained in:
Sam Soffes
2012-05-09 21:32:13 -07:00
3 changed files with 36 additions and 14 deletions
+12 -9
View File
@@ -11,6 +11,8 @@
#import "zlib.h"
#import "zconf.h"
#include <sys/stat.h>
#define CHUNK 16384
@interface SSZipArchive ()
@@ -116,25 +118,26 @@
// http://www.pkware.com/documents/casestudies/APPNOTE.TXT
//
// ...to deduce this method of detecting whether the file in the ZIP is a symbolic link.
// If it is, it is listed as a directory but has an uncompressed data size greater than
// zero (real directories have it equal to 0) and the included, uncompressed data is the
// symbolic link path.
// If it is, it is listed as a directory but has a data size greater than zero (real
// directories have it equal to 0) and the included, uncompressed data is the symbolic link path.
//
// ZIP files did not originally include support for symbolic links so the specification
// doesn't include anything in them that isn't part of a unix extension that isn't being used
// by the archivers we're testing. Most of this is figured out through trial and error and
// reading ZIP headers in hex editors. This seems to do the trick though.
//
const uLong ZipDirectoryVersion = 10;
const uLong ZipCompressionMethodStore = 0;
BOOL fileIsSymbolicLink = NO;
if((fileInfo.version_needed == ZipDirectoryVersion) && // Is it a directory?
(fileInfo.compression_method == ZipCompressionMethodStore) && // Is it compressed?
(fileInfo.compressed_size > 0)) // Is there any data there?
if((fileInfo.compression_method == ZipCompressionMethodStore) && // Is it compressed?
(S_ISDIR(fileInfo.external_fa)) && // Is it marked as a directory
(fileInfo.compressed_size > 0)) // Is there any data?
{
fileIsSymbolicLink = YES;
}
//NSLog(@"\"%s\" is symbolic link? %@", filename, fileIsSymbolicLink ? @"Yes." : @"No.");
// Check if it contains directory
NSString *strPath = [NSString stringWithCString:filename encoding:NSUTF8StringEncoding];
BOOL isDirectory = NO;
+24 -5
View File
@@ -91,16 +91,35 @@
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:self];
NSString* testSymlink = [outputPath stringByAppendingPathComponent:@"SymbolicLink/GitHub.app"];
NSString *testSymlinkFolder = [outputPath stringByAppendingPathComponent:@"SymbolicLink/GitHub.app"];
NSString *testSymlinkFile = [outputPath stringByAppendingPathComponent:@"SymbolicLink/Icon.icns"];
NSError* error = nil;
NSString* symlinkPath = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:testSymlink error:&error];
NSError *error = nil;
NSString *symlinkFolderPath = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:testSymlinkFolder error:&error];
bool symbolicLinkToFolderPersists = ((symlinkFolderPath != nil) && [symlinkFolderPath isEqualToString:@"/Applications/GitHub.app"]) && (error == nil);
bool symbolicLinkPersists = ((symlinkPath != nil) && [symlinkPath isEqualToString:@"/Applications/GitHub.app"]) && (error == nil);
error = nil;
STAssertTrue(symbolicLinkPersists, @"Symbolic links should persist from the original archive to the outputted files.");
NSString *symlinkFilePath = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:testSymlinkFile error:&error];
bool symbolicLinkToFilePersists = ((symlinkFilePath != nil) && [symlinkFilePath isEqualToString:@"/Applications/GitHub.app/Contents/Resources/AppIcon.icns"]) && (error == nil);
STAssertTrue(symbolicLinkToFilePersists && symbolicLinkToFolderPersists, @"Symbolic links should persist from the original archive to the outputted files.");
}
- (void)testUnzippingWithUnicodeFilenameInside {
NSString* zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"Unicode" ofType:@"zip"];
NSString* outputPath = [self _cachesPath:@"Unicode"];
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:self];
bool unicodeFilenameWasExtracted = [[NSFileManager defaultManager] fileExistsAtPath:[outputPath stringByAppendingPathComponent:@"Accént.txt"]];
bool unicodeFolderWasExtracted = [[NSFileManager defaultManager] fileExistsAtPath:[outputPath stringByAppendingPathComponent:@"Fólder/Nothing.txt"]];
STAssertTrue(unicodeFilenameWasExtracted, @"Files with filenames in unicode should be extracted properly.");
STAssertTrue(unicodeFolderWasExtracted, @"Folders with names in unicode should be extracted propertly.");
}
// Commented out to avoid checking in several gig file into the repository. Simply add a file named
// `LargeArchive.zip` to the project and uncomment out these lines to test.
Binary file not shown.