diff --git a/ChangeLog b/ChangeLog index cc6aa74c5..bef7ab731 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-10-12 Richard Frith-Macdonald + + * Source/NSURL.m: Exactly match the percent escaping used by OSX. + 2010-10-08 Eric Wasylishen * Source/GSAvahiRunLoopIntegration.m: Fix some bugs: @@ -216,7 +220,7 @@ Change sel_getUid to call sel_registerName, in line with OS X behaviour since 10.0 -2010-09-02 9avid Chisnall +2010-09-02 David Chisnall * Source/NSBundle.m * Source/NSMethodSignature.m diff --git a/Source/NSURL.m b/Source/NSURL.m index 36c25937b..36bc003d4 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -40,6 +40,7 @@ function may be incorrect #define EXPOSE_NSURL_IVARS 1 #import "Foundation/NSArray.h" #import "Foundation/NSCoder.h" +#import "Foundation/NSData.h" #import "Foundation/NSDictionary.h" #import "Foundation/NSException.h" #import "Foundation/NSFileManager.h" @@ -54,6 +55,73 @@ function may be incorrect NSString * const NSURLErrorDomain = @"NSURLErrorDomain"; NSString * const NSErrorFailingURLStringKey = @"NSErrorFailingURLStringKey"; +@interface NSString (NSURLPrivate) +- (NSString*) _stringByAddingPercentEscapes; +@end + +@implementation NSString (NSURLPrivate) +/* Like the normal percent escape method, but with additional characters + * escaped. + */ +- (NSString*) _stringByAddingPercentEscapes +{ + NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding]; + NSString *s = nil; + + if (data != nil) + { + unsigned char *src = (unsigned char*)[data bytes]; + unsigned int slen = [data length]; + unsigned char *dst; + unsigned int spos = 0; + unsigned int dpos = 0; + + dst = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), slen * 3); + while (spos < slen) + { + unsigned char c = src[spos++]; + unsigned int hi; + unsigned int lo; + + if (c <= 32 + || c > 126 + || c == 34 + || c == 35 + || c == 37 + || c == 59 + || c == 60 + || c == 62 + || c == 63 + || c == 91 + || c == 92 + || c == 93 + || c == 94 + || c == 96 + || c == 123 + || c == 124 + || c == 125) + { + dst[dpos++] = '%'; + hi = (c & 0xf0) >> 4; + dst[dpos++] = (hi > 9) ? 'A' + hi - 10 : '0' + hi; + lo = (c & 0x0f); + dst[dpos++] = (lo > 9) ? 'A' + lo - 10 : '0' + lo; + } + else + { + dst[dpos++] = c; + } + } + s = [[NSString alloc] initWithBytes: dst + length: dpos + encoding: NSASCIIStringEncoding]; + NSZoneFree(NSDefaultMallocZone(), dst); + IF_NO_GC([s autorelease];) + } + return s; +} +@end + /* * Structure describing a URL. * All the char* fields may be NULL pointers, except path, which @@ -542,8 +610,7 @@ static unsigned urlAlign; { NSString *aUrlString = [NSString alloc]; - aPath - = [aPath stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + aPath = [aPath _stringByAddingPercentEscapes]; if ([aHost length] > 0) { NSRange r = [aHost rangeOfString: @"@"];