Merge pull request #23 from jparishy/master
Fix for issues with Unicode filenames and Symbolic Links. Fixes #14
This commit is contained in:
+12
-9
@@ -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;
|
||||
|
||||
@@ -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.
Reference in New Issue
Block a user