@@ -23,54 +23,36 @@ #endif #import "OFNumber.h" #import "OFPair.h" #import "OFString.h" +#import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" @implementation OFMutableURI -@dynamic scheme, percentEncodedScheme, host, percentEncodedHost, port, user; -@dynamic percentEncodedUser, password, percentEncodedPassword, path; -@dynamic percentEncodedPath, pathComponents, query, percentEncodedQuery; -@dynamic queryItems, fragment, percentEncodedFragment; +@dynamic scheme, host, percentEncodedHost, port, user, percentEncodedUser; +@dynamic password, percentEncodedPassword, path, percentEncodedPath; +@dynamic pathComponents, query, percentEncodedQuery, queryItems, fragment; +@dynamic percentEncodedFragment; + (instancetype)URI { return [[[self alloc] init] autorelease]; } - (void)setScheme: (OFString *)scheme { void *pool = objc_autoreleasePoolPush(); - OFString *old = _percentEncodedScheme; + OFString *old = _scheme; if (scheme.length < 1 || !OFASCIIIsAlpha(*scheme.UTF8String)) @throw [OFInvalidFormatException exception]; - _percentEncodedScheme = [[scheme.lowercaseString - stringByAddingPercentEncodingWithAllowedCharacters: - [OFCharacterSet URISchemeAllowedCharacterSet]] copy]; - - [old release]; - - objc_autoreleasePoolPop(pool); -} - -- (void)setPercentEncodedScheme: (OFString *)percentEncodedScheme -{ - void *pool = objc_autoreleasePoolPush(); - OFString *old = _percentEncodedScheme; - - if (percentEncodedScheme.length < 1 || - !OFASCIIIsAlpha(*percentEncodedScheme.UTF8String)) - @throw [OFInvalidFormatException exception]; - - if (percentEncodedScheme != nil) - OFURIVerifyIsEscaped(percentEncodedScheme, - [OFCharacterSet URISchemeAllowedCharacterSet]); - - _percentEncodedScheme = [percentEncodedScheme.lowercaseString copy]; + OFURIVerifyIsEscaped(scheme, + [OFCharacterSet URISchemeAllowedCharacterSet], false); + + _scheme = [scheme.lowercaseString copy]; [old release]; objc_autoreleasePoolPop(pool); } @@ -102,20 +84,24 @@ if (!OFURIIsIPv6Host([percentEncodedHost substringWithRange: OFMakeRange(1, percentEncodedHost.length - 2)])) @throw [OFInvalidFormatException exception]; } else if (percentEncodedHost != nil) OFURIVerifyIsEscaped(percentEncodedHost, - [OFCharacterSet URIHostAllowedCharacterSet]); + [OFCharacterSet URIHostAllowedCharacterSet], true); old = _percentEncodedHost; _percentEncodedHost = [percentEncodedHost copy]; [old release]; } - (void)setPort: (OFNumber *)port { OFNumber *old = _port; + + if (port.longLongValue < 0 || port.longLongValue > 65535) + @throw [OFInvalidArgumentException exception]; + _port = [port copy]; [old release]; } - (void)setUser: (OFString *)user @@ -136,11 +122,11 @@ { OFString *old; if (percentEncodedUser != nil) OFURIVerifyIsEscaped(percentEncodedUser, - [OFCharacterSet URIUserAllowedCharacterSet]); + [OFCharacterSet URIUserAllowedCharacterSet], true); old = _percentEncodedUser; _percentEncodedUser = [percentEncodedUser copy]; [old release]; } @@ -163,11 +149,11 @@ { OFString *old; if (percentEncodedPassword != nil) OFURIVerifyIsEscaped(percentEncodedPassword, - [OFCharacterSet URIPasswordAllowedCharacterSet]); + [OFCharacterSet URIPasswordAllowedCharacterSet], true); old = _percentEncodedPassword; _percentEncodedPassword = [percentEncodedPassword copy]; [old release]; } @@ -190,11 +176,11 @@ { OFString *old; if (percentEncodedPath != nil) OFURIVerifyIsEscaped(percentEncodedPath, - [OFCharacterSet URIPathAllowedCharacterSet]); + [OFCharacterSet URIPathAllowedCharacterSet], true); old = _percentEncodedPath; _percentEncodedPath = [percentEncodedPath copy]; [old release]; } @@ -237,11 +223,11 @@ { OFString *old; if (percentEncodedQuery != nil) OFURIVerifyIsEscaped(percentEncodedQuery, - [OFCharacterSet URIQueryAllowedCharacterSet]); + [OFCharacterSet URIQueryAllowedCharacterSet], true); old = _percentEncodedQuery; _percentEncodedQuery = [percentEncodedQuery copy]; [old release]; } @@ -304,11 +290,11 @@ { OFString *old; if (percentEncodedFragment != nil) OFURIVerifyIsEscaped(percentEncodedFragment, - [OFCharacterSet URIFragmentAllowedCharacterSet]); + [OFCharacterSet URIFragmentAllowedCharacterSet], true); old = _percentEncodedFragment; _percentEncodedFragment = [percentEncodedFragment copy]; [old release]; } @@ -325,11 +311,11 @@ - (void)appendPathComponent: (OFString *)component { [self appendPathComponent: component isDirectory: false]; #ifdef OF_HAVE_FILES - if ([_percentEncodedScheme isEqual: @"file"] && + if ([_scheme isEqual: @"file"] && ![_percentEncodedPath hasSuffix: @"/"] && [[OFFileManager defaultManager] directoryExistsAtURI: self]) { void *pool = objc_autoreleasePoolPush(); OFString *path = [_percentEncodedPath stringByAppendingString: @"/"]; @@ -356,11 +342,11 @@ stringByAddingPercentEncodingWithAllowedCharacters: [OFCharacterSet URIPathAllowedCharacterSet]]; #if defined(OF_WINDOWS) || defined(OF_MSDOS) if ([_percentEncodedPath hasSuffix: @"/"] || - ([_percentEncodedScheme isEqual: @"file"] && + ([_scheme isEqual: @"file"] && [_percentEncodedPath hasSuffix: @":"])) #else if ([_percentEncodedPath hasSuffix: @"/"]) #endif path = [_percentEncodedPath stringByAppendingString: component];