Created
March 18, 2013 22:44
-
-
Save novocaine/5191558 to your computer and use it in GitHub Desktop.
decode content disposition header using utf8 for ios, which by default interprets the header as ASCII
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (NSString*)getFilenameFromContentDisposition:(NSString*)contentDisposition { | |
// filename is optionally quoted. | |
// | |
// note that if the disposition indicates the asterisk | |
// notation - filename*= - this indicates an explicit encoding; | |
// in that case we will drop through to just using the responses | |
// suggestedFilename (don't want to deal with the complexity, | |
// hopefully the system has reasonably behaviour when the | |
// encoding is actually unambiguous) | |
NSString* suggestedFilename = nil; | |
NSRegularExpression* regex = [NSRegularExpression | |
regularExpressionWithPattern: | |
@"^attachment;\\s*filename=\"([^\"]*)\"|(.*)" | |
options:0 | |
error:nil]; | |
NSArray* matches = [regex matchesInString:contentDisposition | |
options:0 | |
range:NSMakeRange(0, | |
[contentDisposition length])]; | |
if ([matches count] > 0) { | |
NSTextCheckingResult *match = [matches objectAtIndex:0]; | |
if ([match numberOfRanges] >= 2) { | |
// contentDisposition is ascii encoded; process it as utf8 | |
NSString* suggestedFilenameAscii = [contentDisposition | |
substringWithRange:[match rangeAtIndex:1]]; | |
// apparently there's actually no way of accessing the underlying | |
// bytes in an NSString*, so we ask for an array of utf32 characters | |
// which should not result in any transcoding of the existing data | |
const char* data = [suggestedFilenameAscii cStringUsingEncoding:NSUTF32LittleEndianStringEncoding]; | |
if (!data) { | |
return nil; | |
} | |
NSMutableData* repackedData = [NSMutableData dataWithLength:[suggestedFilenameAscii length]]; | |
for (int i=0; i < [suggestedFilenameAscii length] * 4; i += 4) { | |
if (data[i] > 0xFF) { | |
// not actually just octets in unicode like we thought! bail! | |
return nil; | |
} | |
((char*)[repackedData mutableBytes])[i >> 2] = data[i]; | |
} | |
suggestedFilename = [[[NSString alloc] initWithData:repackedData | |
encoding:NSUTF8StringEncoding] autorelease]; | |
// don't allow filenames with slashes in them | |
NSRange slashRange = ([suggestedFilename rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]]); | |
if (slashRange.location == NSNotFound) { | |
return nil; | |
} | |
NSLog(@"forced utf8 interpetation of contentDisposition: %@", | |
suggestedFilename); | |
} | |
} | |
return suggestedFilename; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment