Fix for mailing tests regarding unicode filenames and symbolic links.

See my note about ZIPs lack of documentation for symbolic links. A lot
of this seems to be trial and error on my part as the implementation
isn't documented. This seems to do the trick, however, and all of the
tests are now passing on my end.

As always, send more problems my way.
This commit is contained in:
Julius Parishy
2012-05-09 23:53:22 -04:00
parent 581adbb98c
commit 26630b36af
7 changed files with 42 additions and 12 deletions
+14 -7
View File
@@ -11,6 +11,8 @@
#import "zlib.h"
#import "zconf.h"
#include <sys/stat.h>
#define CHUNK 16384
@interface SSZipArchive ()
@@ -116,23 +118,28 @@
// 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, link: %@, dir: %@", filename, S_ISLNK(fileInfo.external_fa) ? @"Yes" : @"NO", S_ISDIR(fileInfo.external_fa) ? @"Yes" : @"No");
//NSLog(@"\"%s\" is symbolic link? %@", filename, fileIsSymbolicLink ? @"Yes." : @"No.");
// Check if it contains directory
+1
View File
@@ -0,0 +1 @@
Hello.
+1
View File
@@ -0,0 +1 @@
Nothing to see here. Move along.
+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.
+1
View File
@@ -0,0 +1 @@
/Applications/GitHub.app
+1
View File
@@ -0,0 +1 @@
/Applications/GitHub.app/Contents/Resources/AppIcon.icns