Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@novocaine
Created March 18, 2013 22:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save novocaine/5191558 to your computer and use it in GitHub Desktop.
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
- (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