From 3743e1d643d72b2ae69c37dd566928fcdf6e9fcf Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Wed, 11 Mar 2020 10:55:10 +0100 Subject: [PATCH 01/39] Added missing NSURLQueryItem implementation. --- Source/NSURL.m | 53 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 5f7cb3bdd..448e05707 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2179,38 +2179,77 @@ static NSUInteger urlAlign; + (instancetype)queryItemWithName:(NSString *)name value:(NSString *)value { - return nil; + NSURLQueryItem *newQueryItem = [[NSURLQueryItem alloc] initWithName: name + value: value]; + return AUTORELEASE(newQueryItem); } -- (instancetype)initWithName:(NSString *)name +- (instancetype)initWithName:(NSString *)name value:(NSString *)value { - return nil; + self = [super init]; + if (self != nil) + { + ASSIGNCOPY(_name, name); + ASSIGNCOPY(_value, value); + } + return self; +} + +- (void) dealloc +{ + RELEASE(_name); + RELEASE(_value); + [super dealloc]; } // Reading a name and value from a query - (NSString *) name { - return nil; + return _name; } - (NSString *) value { - return nil; + return _value; } - (id) initWithCoder: (NSCoder *)acoder { - return nil; + if ((self = [super init]) != nil) + { + if ([acoder allowsKeyedCoding]) + { + _name = [acoder decodeObjectForKey: @"NS.name"]; + _value = [acoder decodeObjectForKey: @"NS.value"]; + } + else + { + _name = [acoder decodeObject]; + _value = [acoder decodeObject]; + } + } + return self; } - (void) encodeWithCoder: (NSCoder *)acoder { + if ([acoder allowsKeyedCoding]) + { + [acoder encodeObject: _name forKey: @"NS.name"]; + [acoder encodeObject: _value forKey: @"NS.value"]; + } + else + { + [acoder encodeObject: _name]; + [acoder encodeObject: _value]; + } } - (id) copyWithZone: (NSZone *)zone { - return nil; + return [[[self class] allocWithZone: zone] initWithName: _name + value: _value]; } @end From a0779f4e621bce4463c2ff139463f3ca6fee864e Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Mon, 23 Mar 2020 11:56:20 +0100 Subject: [PATCH 02/39] Fixed internal ivar usage for NSURLQueryItem. --- Source/NSURL.m | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 448e05707..fe4a4d1dc 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2190,28 +2190,30 @@ static NSUInteger urlAlign; self = [super init]; if (self != nil) { - ASSIGNCOPY(_name, name); - ASSIGNCOPY(_value, value); + GS_CREATE_INTERNAL(NSURLQueryItem); + + ASSIGNCOPY(internal->_name, name); + ASSIGNCOPY(internal->_value, value); } return self; } - (void) dealloc { - RELEASE(_name); - RELEASE(_value); + RELEASE(internal->_name); + RELEASE(internal->_value); [super dealloc]; } // Reading a name and value from a query - (NSString *) name { - return _name; + return internal->_name; } - (NSString *) value { - return _value; + return internal->_value; } - (id) initWithCoder: (NSCoder *)acoder @@ -2220,13 +2222,13 @@ static NSUInteger urlAlign; { if ([acoder allowsKeyedCoding]) { - _name = [acoder decodeObjectForKey: @"NS.name"]; - _value = [acoder decodeObjectForKey: @"NS.value"]; + internal->_name = [acoder decodeObjectForKey: @"NS.name"]; + internal->_value = [acoder decodeObjectForKey: @"NS.value"]; } else { - _name = [acoder decodeObject]; - _value = [acoder decodeObject]; + internal->_name = [acoder decodeObject]; + internal->_value = [acoder decodeObject]; } } return self; @@ -2236,20 +2238,20 @@ static NSUInteger urlAlign; { if ([acoder allowsKeyedCoding]) { - [acoder encodeObject: _name forKey: @"NS.name"]; - [acoder encodeObject: _value forKey: @"NS.value"]; + [acoder encodeObject: internal->_name forKey: @"NS.name"]; + [acoder encodeObject: internal->_value forKey: @"NS.value"]; } else { - [acoder encodeObject: _name]; - [acoder encodeObject: _value]; + [acoder encodeObject: internal->_name]; + [acoder encodeObject: internal->_value]; } } - (id) copyWithZone: (NSZone *)zone { - return [[[self class] allocWithZone: zone] initWithName: _name - value: _value]; + return [[[self class] allocWithZone: zone] initWithName: internal->_name + value: internal->_value]; } @end From 8e093a519e80ac059652ee9c591d9389b4577e8f Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Mon, 23 Mar 2020 13:40:09 +0100 Subject: [PATCH 03/39] Added misssing GSInternal declaration for NSURLQueryItem. --- Source/NSURL.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/NSURL.m b/Source/NSURL.m index fe4a4d1dc..97492fcaf 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2173,6 +2173,13 @@ static NSUInteger urlAlign; } @end + +#undef GSInternal +#define GSInternal NSURLQueryItemInternal +#include "GSInternal.h" +GS_PRIVATE_INTERNAL(NSURLQueryItem) + + @implementation NSURLQueryItem // Creating query items. From 8774e5f55dbf488ac19b0497adbcf77ecebeb7f8 Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Mon, 23 Mar 2020 14:46:45 +0100 Subject: [PATCH 04/39] NSURLComponents fixes - Moved NSURLComponents internal declaration to correct place. - Added GS_DESTROY_INTERNAL() calls for NSURLComponents and NSURLQueryItem. --- Source/NSURL.m | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 97492fcaf..61691e3ee 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -92,10 +92,6 @@ function may be incorrect #import "GNUstepBase/NSURL+GNUstepBase.h" -#define GSInternal NSURLComponentsInternal -#include "GSInternal.h" -GS_PRIVATE_INTERNAL(NSURLComponents) - NSString * const NSURLErrorDomain = @"NSURLErrorDomain"; NSString * const NSErrorFailingURLStringKey = @"NSErrorFailingURLStringKey"; @@ -2174,7 +2170,6 @@ static NSUInteger urlAlign; @end -#undef GSInternal #define GSInternal NSURLQueryItemInternal #include "GSInternal.h" GS_PRIVATE_INTERNAL(NSURLQueryItem) @@ -2209,6 +2204,7 @@ GS_PRIVATE_INTERNAL(NSURLQueryItem) { RELEASE(internal->_name); RELEASE(internal->_value); + GS_DESTROY_INTERNAL(NSURLQueryItem); [super dealloc]; } @@ -2263,6 +2259,13 @@ GS_PRIVATE_INTERNAL(NSURLQueryItem) @end + +#undef GSInternal +#define GSInternal NSURLComponentsInternal +#include "GSInternal.h" +GS_PRIVATE_INTERNAL(NSURLComponents) + + @implementation NSURLComponents // Creating URL components... @@ -2344,7 +2347,7 @@ GS_PRIVATE_INTERNAL(NSURLQueryItem) RELEASE(internal->_percentEncodedQueryItems); RELEASE(internal->_percentEncodedScheme); RELEASE(internal->_percentEncodedUser); - + GS_DESTROY_INTERNAL(NSURLComponents); [super dealloc]; } From ddbd89ce70f24851ab915c872cc7dbade5b3e328 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Thu, 26 Mar 2020 09:27:55 -0400 Subject: [PATCH 05/39] Add minor typedef to NSObjCRuntime.h --- Headers/Foundation/NSObjCRuntime.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Headers/Foundation/NSObjCRuntime.h b/Headers/Foundation/NSObjCRuntime.h index 53fd04ad3..ad43ecc8f 100644 --- a/Headers/Foundation/NSObjCRuntime.h +++ b/Headers/Foundation/NSObjCRuntime.h @@ -283,6 +283,11 @@ DEFINE_BLOCK_TYPE(NSComparator, NSComparisonResult, id, id); } #endif +/** + * Declare NSExceptionName + */ +typedef NSString* NSExceptionName; + /** * Declare Apple availability macros for compatibility purposes as no-ops. */ From 7019e849cce5e2ad8ecb65f0ed27880609920861 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 27 Mar 2020 04:30:13 -0400 Subject: [PATCH 06/39] Add method to update url when any set method is called --- Source/NSURL.m | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Source/NSURL.m b/Source/NSURL.m index c3ac6beeb..a25d671c8 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2433,6 +2433,11 @@ GS_PRIVATE_INTERNAL(NSURLComponents) return nil; } +// Regenerate URL when components are changed... +- (void) _regenerateURL +{ +} + // Accessing Components in Native Format - (NSString *) fragment { @@ -2442,6 +2447,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setFragment: (NSString *)fragment { ASSIGN(internal->_fragment, fragment); + [self _regenerateURL]; } - (NSString *) host @@ -2452,6 +2458,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setHost: (NSString *)host { ASSIGN(internal->_host, host); + [self _regenerateURL]; } - (NSString *) password @@ -2462,6 +2469,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPassword: (NSString *)password { ASSIGN(internal->_password, password); + [self _regenerateURL]; } - (NSString *) path @@ -2472,6 +2480,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPath: (NSString *)path { ASSIGN(internal->_path, path); + [self _regenerateURL]; } - (NSNumber *) port @@ -2482,6 +2491,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPort: (NSNumber *)port { ASSIGN(internal->_port, port); + [self _regenerateURL]; } - (NSString *) query @@ -2509,6 +2519,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) [result addObject: qitem]; } [self setQueryItems: result]; + [self _regenerateURL]; } } @@ -2520,6 +2531,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQueryItems: (NSArray *)queryItems { ASSIGN(internal->_queryItems, queryItems); + [self _regenerateURL]; } - (NSString *) scheme @@ -2530,6 +2542,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { ASSIGN(internal->_scheme, scheme); + [self _regenerateURL]; } - (NSString *) user @@ -2540,6 +2553,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setUser: (NSString *)user { ASSIGN(internal->_user, user); + [self _regenerateURL]; } // Accessing Components in PercentEncoded Format @@ -2551,6 +2565,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedFragment: (NSString *)fragment { ASSIGN(internal->_percentEncodedFragment, fragment); + [self _regenerateURL]; } - (NSString *) percentEncodedHost @@ -2561,6 +2576,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedHost: (NSString *)host { ASSIGN(internal->_percentEncodedHost, host); + [self _regenerateURL]; } - (NSString *) percentEncodedPassword @@ -2571,6 +2587,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPassword: (NSString *)password { ASSIGN(internal->_percentEncodedPassword, password); + [self _regenerateURL]; } - (NSString *) percentEncodedPath @@ -2581,6 +2598,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPath: (NSString *)path { ASSIGN(internal->_percentEncodedPath, path); + [self _regenerateURL]; } - (NSString *) percentEncodedQuery @@ -2591,6 +2609,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQuery: (NSString *)query { ASSIGN(internal->_percentEncodedQuery, query); + [self _regenerateURL]; } - (NSArray *) percentEncodedQueryItems @@ -2601,6 +2620,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { ASSIGN(internal->_percentEncodedQueryItems, queryItems); + [self _regenerateURL]; } - (NSString *) percentEncodedScheme @@ -2611,6 +2631,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedScheme: (NSString *)scheme { ASSIGN(internal->_percentEncodedScheme, scheme); + [self _regenerateURL]; } - (NSString *) percentEncodedUser @@ -2621,6 +2642,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedUser: (NSString *)user { ASSIGN(internal->_percentEncodedUser, user); + [self _regenerateURL]; } // Locating components of the URL string representation From 6fb90273fefda125ca1782f72d7c8096ea565491 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 27 Mar 2020 05:51:07 -0400 Subject: [PATCH 07/39] Update implementation --- Source/NSURL.m | 69 +++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index a25d671c8..f0da95e99 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -69,7 +69,8 @@ function may be incorrect NSRange _rangeOfQuery; \ NSRange _rangeOfQueryItems; \ NSRange _rangeOfScheme; \ - NSRange _rangeOfUser; + NSRange _rangeOfUser; \ + BOOL _regenerating; #import "common.h" #define EXPOSE_NSURL_IVARS 1 @@ -2379,14 +2380,14 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGN(internal->_url, url); // components... - [self setFragment: [url fragment]]; - [self setHost: [url host]]; - [self setPassword: [url password]]; - [self setPath: [url path]]; - [self setPort: [url port]]; - [self setQuery: [url query]]; - [self setScheme: [url scheme]]; - [self setUser: [url user]]; + ASSIGNCOPY(internal->_fragment, [url fragment]); + ASSIGNCOPY(internal->_host, [url host]); + ASSIGNCOPY(internal->_password, [url password]); + ASSIGNCOPY(internal->_path, [url path]); + ASSIGNCOPY(internal->_port, [url port]); + ASSIGNCOPY(internal->_query, [url query]); + ASSIGNCOPY(internal->_scheme, [url scheme]); + ASSIGNCOPY(internal->_user, [url user]); // Percent encoded portions... [self setPercentEncodedFragment: @@ -2436,6 +2437,22 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Regenerate URL when components are changed... - (void) _regenerateURL { + NSString *urlString = (internal->_user != nil && internal->_password != nil) ? + [NSString stringWithFormat: @"%@://%@:%@@%@:%@/%@", + internal->_scheme, + internal->_user, + internal->_password, + internal->_host, + internal->_port, + internal->_path] : + [NSString stringWithFormat: @"%@://%@:%@/%@", + internal->_scheme, + internal->_host, + internal->_port, + internal->_path]; + + NSURL *url = [NSURL URLWithString: urlString]; + [self setURL: url]; } // Accessing Components in Native Format @@ -2446,7 +2463,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setFragment: (NSString *)fragment { - ASSIGN(internal->_fragment, fragment); + ASSIGNCOPY(internal->_fragment, fragment); [self _regenerateURL]; } @@ -2457,7 +2474,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setHost: (NSString *)host { - ASSIGN(internal->_host, host); + ASSIGNCOPY(internal->_host, host); [self _regenerateURL]; } @@ -2468,7 +2485,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPassword: (NSString *)password { - ASSIGN(internal->_password, password); + ASSIGNCOPY(internal->_password, password); [self _regenerateURL]; } @@ -2479,7 +2496,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPath: (NSString *)path { - ASSIGN(internal->_path, path); + ASSIGNCOPY(internal->_path, path); [self _regenerateURL]; } @@ -2490,7 +2507,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPort: (NSNumber *)port { - ASSIGN(internal->_port, port); + ASSIGNCOPY(internal->_port, port); [self _regenerateURL]; } @@ -2501,7 +2518,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQuery: (NSString *)query { - ASSIGN(internal->_query, query); + ASSIGNCOPY(internal->_query, query); if (query != nil) { NSMutableArray *result = [NSMutableArray arrayWithCapacity: 5]; @@ -2530,7 +2547,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQueryItems: (NSArray *)queryItems { - ASSIGN(internal->_queryItems, queryItems); + ASSIGNCOPY(internal->_queryItems, queryItems); [self _regenerateURL]; } @@ -2541,7 +2558,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { - ASSIGN(internal->_scheme, scheme); + ASSIGNCOPY(internal->_scheme, scheme); [self _regenerateURL]; } @@ -2552,7 +2569,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setUser: (NSString *)user { - ASSIGN(internal->_user, user); + ASSIGNCOPY(internal->_user, user); [self _regenerateURL]; } @@ -2564,7 +2581,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedFragment: (NSString *)fragment { - ASSIGN(internal->_percentEncodedFragment, fragment); + ASSIGNCOPY(internal->_percentEncodedFragment, fragment); [self _regenerateURL]; } @@ -2575,7 +2592,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedHost: (NSString *)host { - ASSIGN(internal->_percentEncodedHost, host); + ASSIGNCOPY(internal->_percentEncodedHost, host); [self _regenerateURL]; } @@ -2586,7 +2603,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPassword: (NSString *)password { - ASSIGN(internal->_percentEncodedPassword, password); + ASSIGNCOPY(internal->_percentEncodedPassword, password); [self _regenerateURL]; } @@ -2597,7 +2614,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPath: (NSString *)path { - ASSIGN(internal->_percentEncodedPath, path); + ASSIGNCOPY(internal->_percentEncodedPath, path); [self _regenerateURL]; } @@ -2608,7 +2625,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQuery: (NSString *)query { - ASSIGN(internal->_percentEncodedQuery, query); + ASSIGNCOPY(internal->_percentEncodedQuery, query); [self _regenerateURL]; } @@ -2619,7 +2636,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { - ASSIGN(internal->_percentEncodedQueryItems, queryItems); + ASSIGNCOPY(internal->_percentEncodedQueryItems, queryItems); [self _regenerateURL]; } @@ -2630,7 +2647,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedScheme: (NSString *)scheme { - ASSIGN(internal->_percentEncodedScheme, scheme); + ASSIGNCOPY(internal->_percentEncodedScheme, scheme); [self _regenerateURL]; } @@ -2641,7 +2658,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedUser: (NSString *)user { - ASSIGN(internal->_percentEncodedUser, user); + ASSIGNCOPY(internal->_percentEncodedUser, user); [self _regenerateURL]; } From 5bf97288d0b9f0809a6ac08fb954f21e8ef53001 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 27 Mar 2020 05:58:10 -0400 Subject: [PATCH 08/39] remove variable --- Source/NSURL.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index f0da95e99..8ae1a5f9c 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -69,8 +69,7 @@ function may be incorrect NSRange _rangeOfQuery; \ NSRange _rangeOfQueryItems; \ NSRange _rangeOfScheme; \ - NSRange _rangeOfUser; \ - BOOL _regenerating; + NSRange _rangeOfUser; #import "common.h" #define EXPOSE_NSURL_IVARS 1 From 746d3ea8ae4205dfee5e11a4a25420b1b8cde95c Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 27 Mar 2020 06:18:11 -0400 Subject: [PATCH 09/39] Remove infinite recursion --- Source/NSURL.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 8ae1a5f9c..315307f8d 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2581,7 +2581,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedFragment: (NSString *)fragment { ASSIGNCOPY(internal->_percentEncodedFragment, fragment); - [self _regenerateURL]; } - (NSString *) percentEncodedHost From bda473e9bdffd25f1c130caf0d415278279aa3af Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 27 Mar 2020 07:06:20 -0400 Subject: [PATCH 10/39] Remove set for percent escapes in setURL: --- Source/NSURL.m | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 315307f8d..fa64b3523 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2389,27 +2389,27 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_user, [url user]); // Percent encoded portions... - [self setPercentEncodedFragment: - [[url fragment] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLFragmentAllowedCharacterSet]]]; - [self setPercentEncodedHost: - [[url host] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLHostAllowedCharacterSet]]]; - [self setPercentEncodedPassword: - [[url password] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPasswordAllowedCharacterSet]]];; - [self setPercentEncodedPath: - [[url path] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]]; - [self setPercentEncodedQuery: - [[url query] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLQueryAllowedCharacterSet]]]; - [self setPercentEncodedScheme: - [[url scheme] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]]; - [self setPercentEncodedUser: - [[url user] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLUserAllowedCharacterSet]]]; + ASSIGNCOPY(internal->_percentEncodedFragment, + [[url fragment] stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLFragmentAllowedCharacterSet]]); + ASSIGNCOPY(internal->_percentEncodedHost, + [[url host] stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLHostAllowedCharacterSet]]); + ASSIGNCOPY(internal->_percentEncodedPassword, + [[url password] stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPasswordAllowedCharacterSet]]);; + ASSIGNCOPY(internal->_percentEncodedPath, + [[url path] stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPathAllowedCharacterSet]]); + ASSIGNCOPY(internal->_percentEncodedQuery, + [[url query] stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLQueryAllowedCharacterSet]]); + ASSIGNCOPY(internal->_percentEncodedScheme, + [[url scheme] stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPathAllowedCharacterSet]]); + ASSIGNCOPY(internal->_percentEncodedUser, + [[url user] stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLUserAllowedCharacterSet]]); { // Find ranges From a785456d5fc76db56a5572531fdab7681507ad11 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 28 Mar 2020 03:13:36 -0400 Subject: [PATCH 11/39] Copy URL --- Source/NSURL.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index fa64b3523..90777fc30 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2376,7 +2376,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setURL: (NSURL *)url { - ASSIGN(internal->_url, url); + ASSIGNCOPY(internal->_url, url); // components... ASSIGNCOPY(internal->_fragment, [url fragment]); From 7e75310531b9582efed047ab5a98c19dccb1845d Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Mon, 30 Mar 2020 04:37:36 -0400 Subject: [PATCH 12/39] Build query items, fix rendering of URL when user/password are not specified together. --- Source/NSURL.m | 62 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 90777fc30..07501f195 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -7,6 +7,9 @@ Rewrite by: Richard Frith-Macdonald Date: Jun 2002 + Add'l by: Gregory John Casamento + Date: Jan 2020 + This file is part of the GNUstep Library. This library is free software; you can redistribute it and/or @@ -2436,19 +2439,52 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Regenerate URL when components are changed... - (void) _regenerateURL { - NSString *urlString = (internal->_user != nil && internal->_password != nil) ? - [NSString stringWithFormat: @"%@://%@:%@@%@:%@/%@", - internal->_scheme, - internal->_user, - internal->_password, - internal->_host, - internal->_port, - internal->_path] : - [NSString stringWithFormat: @"%@://%@:%@/%@", - internal->_scheme, - internal->_host, - internal->_port, - internal->_path]; + NSString *urlString = @""; + + // Build up the URL from components... + if (internal->_scheme != nil) + { + urlString = [urlString stringByAppendingFormat: @"%@://", internal->_scheme]; + } + + if (internal->_user != nil && internal->_password) + { + urlString = [urlString stringByAppendingFormat: @"%@:%@@", internal->_user, + internal->_password]; + } + + if (internal->_host != nil) + { + urlString = [urlString stringByAppendingFormat: @"%@", internal->_host]; + } + + if (internal->_port != nil) + { + urlString = [urlString stringByAppendingFormat: @":%@", internal->_port]; + } + + if (internal->_path != nil) + { + urlString = [urlString stringByAppendingFormat: @"/%@", internal->_path]; + } + + if ([internal->_queryItems count] > 0) // if query items is nil, this will also return 0 + { + NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSURLQueryItem *qi = nil; + + urlString = [urlString stringByAppendingString: @"?"]; + while((qi = [en nextObject]) != nil) + { + NSString *n = [qi name]; + NSString *v = [qi value]; + urlString = [urlString stringByAppendingFormat: @"%@=%@", n, v]; + if (qi != [internal->_queryItems lastObject]) + { + urlString = [urlString stringByAppendingString: @"&"]; + } + } + } NSURL *url = [NSURL URLWithString: urlString]; [self setURL: url]; From 7fc9033aa81602a337c4f4bac0b251322860b30b Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Mon, 30 Mar 2020 04:58:51 -0400 Subject: [PATCH 13/39] Fix for case where password is not specified. Conformation to RFC1738. --- Source/NSURL.m | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 07501f195..898318717 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2447,10 +2447,17 @@ GS_PRIVATE_INTERNAL(NSURLComponents) urlString = [urlString stringByAppendingFormat: @"%@://", internal->_scheme]; } - if (internal->_user != nil && internal->_password) + if (internal->_user != nil) { - urlString = [urlString stringByAppendingFormat: @"%@:%@@", internal->_user, - internal->_password]; + if (internal->_password != nil) + { + urlString = [urlString stringByAppendingFormat: @"%@:%@@", internal->_user, + internal->_password]; + } + else + { + urlString = [urlString stringByAppendingFormat: @"%@@", internal->_user]; + } } if (internal->_host != nil) From 21036dd69577b8ec94242fab246977a969f5bc1a Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Mon, 30 Mar 2020 05:16:37 -0400 Subject: [PATCH 14/39] Add change from master for NSObjCRuntime. --- Headers/Foundation/NSObjCRuntime.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Headers/Foundation/NSObjCRuntime.h b/Headers/Foundation/NSObjCRuntime.h index 15d8d7dbc..2bd0b9a2d 100644 --- a/Headers/Foundation/NSObjCRuntime.h +++ b/Headers/Foundation/NSObjCRuntime.h @@ -288,11 +288,6 @@ typedef NSString* NSExceptionName; } #endif -/** - * Declare NSExceptionName - */ -typedef NSString* NSExceptionName; - /** * Declare Apple availability macros for compatibility purposes as no-ops. */ From a92491268b2a7940ab4c6d8a2c3a12d9efdac460 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Mon, 30 Mar 2020 06:52:34 -0400 Subject: [PATCH 15/39] URL percent escape query items. --- Source/NSURL.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 898318717..2da01bf6a 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2485,7 +2485,8 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { NSString *n = [qi name]; NSString *v = [qi value]; - urlString = [urlString stringByAppendingFormat: @"%@=%@", n, v]; + NSString *item = [[NSString stringWithFormat: @"%@=%@", n, v] _stringByAddingPercentEscapes]; + urlString = [urlString stringByAppendingString: item]; if (qi != [internal->_queryItems lastObject]) { urlString = [urlString stringByAppendingString: @"&"]; From 31e7bbb7e673cbf2ff6afb686bb6e9191bea17ed Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Mon, 30 Mar 2020 06:58:10 -0400 Subject: [PATCH 16/39] Get rid of trailing whitespace. --- Source/NSURL.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 2da01bf6a..26c591ac7 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -72,7 +72,7 @@ function may be incorrect NSRange _rangeOfQuery; \ NSRange _rangeOfQueryItems; \ NSRange _rangeOfScheme; \ - NSRange _rangeOfUser; + NSRange _rangeOfUser; #import "common.h" #define EXPOSE_NSURL_IVARS 1 From 7c52cd9f7239f29ad8e254ccab8eb589c8e547ce Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Mon, 30 Mar 2020 08:53:42 -0400 Subject: [PATCH 17/39] Added method to handle query encoding. Theoretically URLQueryAllowedCharacter set should cover this. I'm wondering why I had to do this to get the correct result. --- Source/NSURL.m | 103 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 19 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 26c591ac7..2b8676716 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -100,6 +100,7 @@ NSString * const NSErrorFailingURLStringKey = @"NSErrorFailingURLStringKey"; @interface NSString (NSURLPrivate) - (NSString*) _stringByAddingPercentEscapes; +- (NSString*) _stringByAddingPercentEscapesForQuery; @end @implementation NSString (NSURLPrivate) @@ -128,22 +129,84 @@ NSString * const NSErrorFailingURLStringKey = @"NSErrorFailingURLStringKey"; 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) + || 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; +} + +/* + * Encode query + */ +- (NSString*) _stringByAddingPercentEscapesForQuery +{ + 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 == 38 + || c == 59 + || c == 60 + || c == 61 + || c == 62 + || c == 91 + || c == 92 + || c == 93 + || c == 94 + || c == 96 + || c == 123 + || c == 124 + || c == 125) { dst[dpos++] = '%'; hi = (c & 0xf0) >> 4; @@ -2483,9 +2546,11 @@ GS_PRIVATE_INTERNAL(NSURLComponents) urlString = [urlString stringByAppendingString: @"?"]; while((qi = [en nextObject]) != nil) { - NSString *n = [qi name]; - NSString *v = [qi value]; - NSString *item = [[NSString stringWithFormat: @"%@=%@", n, v] _stringByAddingPercentEscapes]; + NSString *n = [[qi name] _stringByAddingPercentEscapesForQuery]; + // stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; + NSString *v = [[qi value]_stringByAddingPercentEscapesForQuery]; + // stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; + NSString *item = [NSString stringWithFormat: @"%@=%@", n, v]; urlString = [urlString stringByAppendingString: item]; if (qi != [internal->_queryItems lastObject]) { From 2fb63480be7d186a3ec6762d4ee887ee73fdc850 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Mon, 30 Mar 2020 09:24:18 -0400 Subject: [PATCH 18/39] Remove slash --- Source/NSURL.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 2b8676716..568f1d109 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2535,7 +2535,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) if (internal->_path != nil) { - urlString = [urlString stringByAppendingFormat: @"/%@", internal->_path]; + urlString = [urlString stringByAppendingFormat: @"%@", internal->_path]; } if ([internal->_queryItems count] > 0) // if query items is nil, this will also return 0 From f6940daac91f02563b40d6add6ccf96edd707534 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Tue, 31 Mar 2020 05:07:38 -0400 Subject: [PATCH 19/39] Add code to allow percent coded set/get methods to reflect the values set by the non-encoded versions --- Source/NSURL.m | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 568f1d109..a6968c387 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2432,11 +2432,12 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setString: (NSString *)urlString { NSURL *url = [NSURL URLWithString: urlString]; - [self setURL: url]; + [self setURL : url]; } - (NSURL *) URL { + [self _regenerateURL]; return internal->_url; } @@ -2463,7 +2464,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) [NSCharacterSet URLHostAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedPassword, [[url password] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPasswordAllowedCharacterSet]]);; + [NSCharacterSet URLPasswordAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedPath, [[url path] stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLPathAllowedCharacterSet]]); @@ -2547,9 +2548,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) while((qi = [en nextObject]) != nil) { NSString *n = [[qi name] _stringByAddingPercentEscapesForQuery]; - // stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; - NSString *v = [[qi value]_stringByAddingPercentEscapesForQuery]; - // stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; + NSString *v = [[qi value] _stringByAddingPercentEscapesForQuery]; NSString *item = [NSString stringWithFormat: @"%@=%@", n, v]; urlString = [urlString stringByAppendingString: item]; if (qi != [internal->_queryItems lastObject]) @@ -2572,7 +2571,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setFragment: (NSString *)fragment { ASSIGNCOPY(internal->_fragment, fragment); - [self _regenerateURL]; + ASSIGNCOPY(internal->_percentEncodedFragment, + [fragment stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLFragmentAllowedCharacterSet]]); } - (NSString *) host @@ -2583,7 +2584,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setHost: (NSString *)host { ASSIGNCOPY(internal->_host, host); - [self _regenerateURL]; + ASSIGNCOPY(internal->_percentEncodedHost, + [host stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLHostAllowedCharacterSet]]); } - (NSString *) password @@ -2594,7 +2597,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPassword: (NSString *)password { ASSIGNCOPY(internal->_password, password); - [self _regenerateURL]; + ASSIGNCOPY(internal->_percentEncodedPassword, + [password stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPasswordAllowedCharacterSet]]); } - (NSString *) path @@ -2605,7 +2610,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPath: (NSString *)path { ASSIGNCOPY(internal->_path, path); - [self _regenerateURL]; + ASSIGNCOPY(internal->_percentEncodedPath, + [path stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPathAllowedCharacterSet]]); } - (NSNumber *) port @@ -2616,7 +2623,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPort: (NSNumber *)port { ASSIGNCOPY(internal->_port, port); - [self _regenerateURL]; } - (NSString *) query @@ -2627,6 +2633,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQuery: (NSString *)query { ASSIGNCOPY(internal->_query, query); + ASSIGNCOPY(internal->_percentEncodedQuery, + [query stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLQueryAllowedCharacterSet]]); if (query != nil) { NSMutableArray *result = [NSMutableArray arrayWithCapacity: 5]; @@ -2644,7 +2653,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) [result addObject: qitem]; } [self setQueryItems: result]; - [self _regenerateURL]; } } @@ -2656,7 +2664,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQueryItems: (NSArray *)queryItems { ASSIGNCOPY(internal->_queryItems, queryItems); - [self _regenerateURL]; } - (NSString *) scheme @@ -2667,7 +2674,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { ASSIGNCOPY(internal->_scheme, scheme); - [self _regenerateURL]; } - (NSString *) user @@ -2678,7 +2684,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setUser: (NSString *)user { ASSIGNCOPY(internal->_user, user); - [self _regenerateURL]; + ASSIGNCOPY(internal->_percentEncodedUser, + [user stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLUserAllowedCharacterSet]]); } // Accessing Components in PercentEncoded Format @@ -2690,6 +2698,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedFragment: (NSString *)fragment { ASSIGNCOPY(internal->_percentEncodedFragment, fragment); + ASSIGNCOPY(internal->_fragment, [fragment stringByRemovingPercentEncoding]); } - (NSString *) percentEncodedHost @@ -2700,7 +2709,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedHost: (NSString *)host { ASSIGNCOPY(internal->_percentEncodedHost, host); - [self _regenerateURL]; + ASSIGNCOPY(internal->_host, [host stringByRemovingPercentEncoding]); } - (NSString *) percentEncodedPassword @@ -2711,7 +2720,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPassword: (NSString *)password { ASSIGNCOPY(internal->_percentEncodedPassword, password); - [self _regenerateURL]; + ASSIGNCOPY(internal->_password, [password stringByRemovingPercentEncoding]); } - (NSString *) percentEncodedPath @@ -2722,7 +2731,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPath: (NSString *)path { ASSIGNCOPY(internal->_percentEncodedPath, path); - [self _regenerateURL]; + ASSIGNCOPY(internal->_path, [path stringByRemovingPercentEncoding]); } - (NSString *) percentEncodedQuery @@ -2733,7 +2742,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQuery: (NSString *)query { ASSIGNCOPY(internal->_percentEncodedQuery, query); - [self _regenerateURL]; + ASSIGNCOPY(internal->_query, [query stringByRemovingPercentEncoding]); } - (NSArray *) percentEncodedQueryItems @@ -2744,7 +2753,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { ASSIGNCOPY(internal->_percentEncodedQueryItems, queryItems); - [self _regenerateURL]; } - (NSString *) percentEncodedScheme @@ -2755,7 +2763,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedScheme: (NSString *)scheme { ASSIGNCOPY(internal->_percentEncodedScheme, scheme); - [self _regenerateURL]; } - (NSString *) percentEncodedUser @@ -2766,7 +2773,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedUser: (NSString *)user { ASSIGNCOPY(internal->_percentEncodedUser, user); - [self _regenerateURL]; + ASSIGNCOPY(internal->_user, [user stringByRemovingPercentEncoding]); } // Locating components of the URL string representation From 4dff7a76a93a4f1c83df507eb6f8a6fb35eed895 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Wed, 1 Apr 2020 08:00:26 -0400 Subject: [PATCH 20/39] Refactor regeneration of URL. --- Source/NSURL.m | 57 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index a6968c387..7c61d226b 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -72,7 +72,8 @@ function may be incorrect NSRange _rangeOfQuery; \ NSRange _rangeOfQueryItems; \ NSRange _rangeOfScheme; \ - NSRange _rangeOfUser; + NSRange _rangeOfUser; \ + BOOL _update; #import "common.h" #define EXPOSE_NSURL_IVARS 1 @@ -2362,6 +2363,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) internal->_rangeOfQuery = NSMakeRange(NSNotFound, 0); internal->_rangeOfScheme = NSMakeRange(NSNotFound, 0); internal->_rangeOfUser = NSMakeRange(NSNotFound, 0); + internal->_update = NO; } return self; } @@ -2437,7 +2439,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSURL *) URL { - [self _regenerateURL]; return internal->_url; } @@ -2457,27 +2458,27 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Percent encoded portions... ASSIGNCOPY(internal->_percentEncodedFragment, - [[url fragment] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLFragmentAllowedCharacterSet]]); + [internal->_fragment stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLFragmentAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedHost, - [[url host] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLHostAllowedCharacterSet]]); + [internal->_host stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLHostAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedPassword, - [[url password] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPasswordAllowedCharacterSet]]); + [internal->_password stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPasswordAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedPath, - [[url path] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]); + [internal->_path stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPathAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedQuery, - [[url query] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLQueryAllowedCharacterSet]]); + [internal->_query stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLQueryAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedScheme, - [[url scheme] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]); + [internal->_scheme stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPathAllowedCharacterSet]]); ASSIGNCOPY(internal->_percentEncodedUser, - [[url user] stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLUserAllowedCharacterSet]]); - + [internal->_user stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLUserAllowedCharacterSet]]); + { // Find ranges NSString *urlString = [url absoluteString]; @@ -2557,10 +2558,12 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } } } + + NSLog(@"URLSTRING = %@", urlString); NSURL *url = [NSURL URLWithString: urlString]; - [self setURL: url]; -} + ASSIGNCOPY(internal->_url, url); + } // Accessing Components in Native Format - (NSString *) fragment @@ -2574,6 +2577,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_percentEncodedFragment, [fragment stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLFragmentAllowedCharacterSet]]); + [self _regenerateURL]; } - (NSString *) host @@ -2587,6 +2591,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_percentEncodedHost, [host stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLHostAllowedCharacterSet]]); + [self _regenerateURL]; } - (NSString *) password @@ -2600,6 +2605,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_percentEncodedPassword, [password stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLPasswordAllowedCharacterSet]]); + [self _regenerateURL]; } - (NSString *) path @@ -2613,6 +2619,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_percentEncodedPath, [path stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLPathAllowedCharacterSet]]); + [self _regenerateURL]; } - (NSNumber *) port @@ -2623,6 +2630,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPort: (NSNumber *)port { ASSIGNCOPY(internal->_port, port); + [self _regenerateURL]; } - (NSString *) query @@ -2664,6 +2672,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQueryItems: (NSArray *)queryItems { ASSIGNCOPY(internal->_queryItems, queryItems); + [self _regenerateURL]; } - (NSString *) scheme @@ -2674,6 +2683,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { ASSIGNCOPY(internal->_scheme, scheme); + [self _regenerateURL]; } - (NSString *) user @@ -2687,6 +2697,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_percentEncodedUser, [user stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLUserAllowedCharacterSet]]); + [self _regenerateURL]; } // Accessing Components in PercentEncoded Format @@ -2699,6 +2710,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedFragment, fragment); ASSIGNCOPY(internal->_fragment, [fragment stringByRemovingPercentEncoding]); + [self _regenerateURL]; } - (NSString *) percentEncodedHost @@ -2710,6 +2722,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedHost, host); ASSIGNCOPY(internal->_host, [host stringByRemovingPercentEncoding]); + [self _regenerateURL]; } - (NSString *) percentEncodedPassword @@ -2721,6 +2734,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedPassword, password); ASSIGNCOPY(internal->_password, [password stringByRemovingPercentEncoding]); + [self _regenerateURL]; } - (NSString *) percentEncodedPath @@ -2732,6 +2746,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedPath, path); ASSIGNCOPY(internal->_path, [path stringByRemovingPercentEncoding]); + [self _regenerateURL]; } - (NSString *) percentEncodedQuery @@ -2743,6 +2758,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedQuery, query); ASSIGNCOPY(internal->_query, [query stringByRemovingPercentEncoding]); + [self _regenerateURL]; } - (NSArray *) percentEncodedQueryItems @@ -2753,6 +2769,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { ASSIGNCOPY(internal->_percentEncodedQueryItems, queryItems); + [self _regenerateURL]; } - (NSString *) percentEncodedScheme @@ -2763,6 +2780,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedScheme: (NSString *)scheme { ASSIGNCOPY(internal->_percentEncodedScheme, scheme); + [self _regenerateURL]; } - (NSString *) percentEncodedUser @@ -2774,6 +2792,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedUser, user); ASSIGNCOPY(internal->_user, [user stringByRemovingPercentEncoding]); + [self _regenerateURL]; } // Locating components of the URL string representation From b594d047c1c3ffa7b2369076d0945e1c31f11bda Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Wed, 1 Apr 2020 08:46:45 -0400 Subject: [PATCH 21/39] Fix issues with regeneration. --- Source/NSURL.m | 87 ++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 59 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 7c61d226b..6eacaf5d3 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2504,65 +2504,17 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Regenerate URL when components are changed... - (void) _regenerateURL { - NSString *urlString = @""; - - // Build up the URL from components... - if (internal->_scheme != nil) - { - urlString = [urlString stringByAppendingFormat: @"%@://", internal->_scheme]; - } - - if (internal->_user != nil) - { - if (internal->_password != nil) - { - urlString = [urlString stringByAppendingFormat: @"%@:%@@", internal->_user, - internal->_password]; - } - else - { - urlString = [urlString stringByAppendingFormat: @"%@@", internal->_user]; - } - } - - if (internal->_host != nil) - { - urlString = [urlString stringByAppendingFormat: @"%@", internal->_host]; - } - - if (internal->_port != nil) - { - urlString = [urlString stringByAppendingFormat: @":%@", internal->_port]; - } - - if (internal->_path != nil) - { - urlString = [urlString stringByAppendingFormat: @"%@", internal->_path]; - } - - if ([internal->_queryItems count] > 0) // if query items is nil, this will also return 0 - { - NSEnumerator *en = [internal->_queryItems objectEnumerator]; - NSURLQueryItem *qi = nil; - - urlString = [urlString stringByAppendingString: @"?"]; - while((qi = [en nextObject]) != nil) - { - NSString *n = [[qi name] _stringByAddingPercentEscapesForQuery]; - NSString *v = [[qi value] _stringByAddingPercentEscapesForQuery]; - NSString *item = [NSString stringWithFormat: @"%@=%@", n, v]; - urlString = [urlString stringByAppendingString: item]; - if (qi != [internal->_queryItems lastObject]) - { - urlString = [urlString stringByAppendingString: @"&"]; - } - } - } - - NSLog(@"URLSTRING = %@", urlString); - - NSURL *url = [NSURL URLWithString: urlString]; - ASSIGNCOPY(internal->_url, url); + NSURL *u; + u = [[NSURL alloc] initWithScheme: internal->_scheme + user: internal->_user + password: internal->_password + host: internal->_host + port: internal->_port + fullPath: internal->_path + parameterString: nil + query: internal->_query + fragment: internal->_fragment]; + ASSIGNCOPY(internal->_url, u); } // Accessing Components in Native Format @@ -2671,6 +2623,23 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQueryItems: (NSArray *)queryItems { + NSString *query = @""; + NSEnumerator *en = [queryItems objectEnumerator]; + NSURLQueryItem *item = nil; + + while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + { + NSString *name = [item name]; + NSString *value = [item value]; + NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; + query = [query stringByAppendingString: itemString]; + if (item != [queryItems lastObject]) + { + query = [query stringByAppendingString: @"&"]; + } + } + + ASSIGNCOPY(internal->_query, query); // add query string... ASSIGNCOPY(internal->_queryItems, queryItems); [self _regenerateURL]; } From bc614d4bd877d6b2f3b2078c62a5fe881f357e65 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Wed, 1 Apr 2020 08:48:51 -0400 Subject: [PATCH 22/39] Regenerate in one place. --- Source/NSURL.m | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 6eacaf5d3..c043c07bb 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2428,6 +2428,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Getting the URL - (NSString *) string { + [self _regenerateURL]; return [internal->_url absoluteString]; } @@ -2439,6 +2440,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSURL *) URL { + [self _regenerateURL]; return internal->_url; } @@ -2641,7 +2643,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_query, query); // add query string... ASSIGNCOPY(internal->_queryItems, queryItems); - [self _regenerateURL]; } - (NSString *) scheme @@ -2652,7 +2653,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { ASSIGNCOPY(internal->_scheme, scheme); - [self _regenerateURL]; } - (NSString *) user @@ -2666,7 +2666,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_percentEncodedUser, [user stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLUserAllowedCharacterSet]]); - [self _regenerateURL]; } // Accessing Components in PercentEncoded Format @@ -2679,7 +2678,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedFragment, fragment); ASSIGNCOPY(internal->_fragment, [fragment stringByRemovingPercentEncoding]); - [self _regenerateURL]; } - (NSString *) percentEncodedHost @@ -2691,7 +2689,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedHost, host); ASSIGNCOPY(internal->_host, [host stringByRemovingPercentEncoding]); - [self _regenerateURL]; } - (NSString *) percentEncodedPassword @@ -2703,7 +2700,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedPassword, password); ASSIGNCOPY(internal->_password, [password stringByRemovingPercentEncoding]); - [self _regenerateURL]; } - (NSString *) percentEncodedPath @@ -2715,7 +2711,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedPath, path); ASSIGNCOPY(internal->_path, [path stringByRemovingPercentEncoding]); - [self _regenerateURL]; } - (NSString *) percentEncodedQuery @@ -2727,7 +2722,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedQuery, query); ASSIGNCOPY(internal->_query, [query stringByRemovingPercentEncoding]); - [self _regenerateURL]; } - (NSArray *) percentEncodedQueryItems @@ -2738,7 +2732,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { ASSIGNCOPY(internal->_percentEncodedQueryItems, queryItems); - [self _regenerateURL]; } - (NSString *) percentEncodedScheme @@ -2749,7 +2742,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedScheme: (NSString *)scheme { ASSIGNCOPY(internal->_percentEncodedScheme, scheme); - [self _regenerateURL]; } - (NSString *) percentEncodedUser @@ -2761,7 +2753,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { ASSIGNCOPY(internal->_percentEncodedUser, user); ASSIGNCOPY(internal->_user, [user stringByRemovingPercentEncoding]); - [self _regenerateURL]; } // Locating components of the URL string representation From fd354f4167053afadd63f8f3776961bb4b0ebe3c Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Wed, 1 Apr 2020 10:08:44 -0400 Subject: [PATCH 23/39] Changes to fix issues pointed out by Fred and RFM --- Source/NSURL.m | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index c043c07bb..5dd3e083b 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -72,8 +72,7 @@ function may be incorrect NSRange _rangeOfQuery; \ NSRange _rangeOfQueryItems; \ NSRange _rangeOfScheme; \ - NSRange _rangeOfUser; \ - BOOL _update; + NSRange _rangeOfUser; #import "common.h" #define EXPOSE_NSURL_IVARS 1 @@ -2363,7 +2362,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) internal->_rangeOfQuery = NSMakeRange(NSNotFound, 0); internal->_rangeOfScheme = NSMakeRange(NSNotFound, 0); internal->_rangeOfUser = NSMakeRange(NSNotFound, 0); - internal->_update = NO; } return self; } @@ -2595,9 +2593,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQuery: (NSString *)query { ASSIGNCOPY(internal->_query, query); - ASSIGNCOPY(internal->_percentEncodedQuery, - [query stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLQueryAllowedCharacterSet]]); if (query != nil) { NSMutableArray *result = [NSMutableArray arrayWithCapacity: 5]; @@ -2632,7 +2627,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) while ((item = (NSURLQueryItem *)[en nextObject]) != nil) { NSString *name = [item name]; - NSString *value = [item value]; + NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; query = [query stringByAppendingString: itemString]; if (item != [queryItems lastObject]) @@ -2642,6 +2637,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } ASSIGNCOPY(internal->_query, query); // add query string... + ASSIGNCOPY(internal->_percentEncodedQuery, query); ASSIGNCOPY(internal->_queryItems, queryItems); } From 14274bffd2abd848a84737c3fa47a184cb2b35dd Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Thu, 2 Apr 2020 06:08:17 -0400 Subject: [PATCH 24/39] Fix issues pointed out by fred k. --- Source/NSURL.m | 182 +++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 105 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 5dd3e083b..7e68f9c33 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -55,15 +55,6 @@ function may be incorrect NSArray *_queryItems; \ NSString *_scheme; \ NSString *_user; \ - NSString *_percentEncodedFragment; \ - NSString *_percentEncodedHost; \ - NSString *_percentEncodedPassword; \ - NSString *_percentEncodedPath; \ - NSNumber *_percentEncodedPort; \ - NSString *_percentEncodedQuery; \ - NSArray *_percentEncodedQueryItems; \ - NSString *_percentEncodedScheme; \ - NSString *_percentEncodedUser; \ NSRange _rangeOfFragment; \ NSRange _rangeOfHost; \ NSRange _rangeOfPassword; \ @@ -72,7 +63,8 @@ function may be incorrect NSRange _rangeOfQuery; \ NSRange _rangeOfQueryItems; \ NSRange _rangeOfScheme; \ - NSRange _rangeOfUser; + NSRange _rangeOfUser; \ + BOOL _dirty; #import "common.h" #define EXPOSE_NSURL_IVARS 1 @@ -2404,15 +2396,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) RELEASE(internal->_queryItems); RELEASE(internal->_scheme); RELEASE(internal->_user); - RELEASE(internal->_percentEncodedFragment); - RELEASE(internal->_percentEncodedHost); - RELEASE(internal->_percentEncodedPassword); - RELEASE(internal->_percentEncodedPath); - RELEASE(internal->_percentEncodedPort); - RELEASE(internal->_percentEncodedQuery); - RELEASE(internal->_percentEncodedQueryItems); - RELEASE(internal->_percentEncodedScheme); - RELEASE(internal->_percentEncodedUser); GS_DESTROY_INTERNAL(NSURLComponents); [super dealloc]; } @@ -2456,44 +2439,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) ASSIGNCOPY(internal->_scheme, [url scheme]); ASSIGNCOPY(internal->_user, [url user]); - // Percent encoded portions... - ASSIGNCOPY(internal->_percentEncodedFragment, - [internal->_fragment stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLFragmentAllowedCharacterSet]]); - ASSIGNCOPY(internal->_percentEncodedHost, - [internal->_host stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLHostAllowedCharacterSet]]); - ASSIGNCOPY(internal->_percentEncodedPassword, - [internal->_password stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPasswordAllowedCharacterSet]]); - ASSIGNCOPY(internal->_percentEncodedPath, - [internal->_path stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]); - ASSIGNCOPY(internal->_percentEncodedQuery, - [internal->_query stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLQueryAllowedCharacterSet]]); - ASSIGNCOPY(internal->_percentEncodedScheme, - [internal->_scheme stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]); - ASSIGNCOPY(internal->_percentEncodedUser, - [internal->_user stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLUserAllowedCharacterSet]]); - - { - // Find ranges - NSString *urlString = [url absoluteString]; -#define URL_COMPONENT_RANGE(part) \ - (part ? [urlString rangeOfString:part] : NSMakeRange(NSNotFound, 0)) - internal->_rangeOfFragment = URL_COMPONENT_RANGE(internal->_fragment); - internal->_rangeOfHost = URL_COMPONENT_RANGE(internal->_host); - internal->_rangeOfPassword = URL_COMPONENT_RANGE(internal->_password); - internal->_rangeOfPath = URL_COMPONENT_RANGE(internal->_path); - internal->_rangeOfPort = URL_COMPONENT_RANGE([internal->_port stringValue]); - internal->_rangeOfQuery = URL_COMPONENT_RANGE(internal->_query); - internal->_rangeOfScheme = URL_COMPONENT_RANGE(internal->_scheme); - internal->_rangeOfUser = URL_COMPONENT_RANGE(internal->_user); -#undef URL_COMPONENT_RANGE - } + _dirty = YES; } - (NSURL *)URLRelativeToURL: (NSURL *)baseURL @@ -2504,17 +2450,41 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Regenerate URL when components are changed... - (void) _regenerateURL { - NSURL *u; - u = [[NSURL alloc] initWithScheme: internal->_scheme - user: internal->_user - password: internal->_password - host: internal->_host - port: internal->_port - fullPath: internal->_path - parameterString: nil - query: internal->_query - fragment: internal->_fragment]; - ASSIGNCOPY(internal->_url, u); + if (_dirty == NO) + { + return; + } + else + { + NSURL *u; + u = [[NSURL alloc] initWithScheme: internal->_scheme + user: internal->_user + password: internal->_password + host: internal->_host + port: internal->_port + fullPath: internal->_path + parameterString: nil + query: internal->_query + fragment: internal->_fragment]; + ASSIGNCOPY(internal->_url, u); + + { + // Find ranges + NSString *urlString = [u absoluteString]; +#define URL_COMPONENT_RANGE(part) \ + (part ? [urlString rangeOfString:part] : NSMakeRange(NSNotFound, 0)) + internal->_rangeOfFragment = URL_COMPONENT_RANGE(internal->_fragment); + internal->_rangeOfHost = URL_COMPONENT_RANGE(internal->_host); + internal->_rangeOfPassword = URL_COMPONENT_RANGE(internal->_password); + internal->_rangeOfPath = URL_COMPONENT_RANGE(internal->_path); + internal->_rangeOfPort = URL_COMPONENT_RANGE([internal->_port stringValue]); + internal->_rangeOfQuery = URL_COMPONENT_RANGE(internal->_query); + internal->_rangeOfScheme = URL_COMPONENT_RANGE(internal->_scheme); + internal->_rangeOfUser = URL_COMPONENT_RANGE(internal->_user); +#undef URL_COMPONENT_RANGE + } + _dirty = NO; + } } // Accessing Components in Native Format @@ -2526,10 +2496,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setFragment: (NSString *)fragment { ASSIGNCOPY(internal->_fragment, fragment); - ASSIGNCOPY(internal->_percentEncodedFragment, - [fragment stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLFragmentAllowedCharacterSet]]); - [self _regenerateURL]; + _dirty = YES; } - (NSString *) host @@ -2540,10 +2507,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setHost: (NSString *)host { ASSIGNCOPY(internal->_host, host); - ASSIGNCOPY(internal->_percentEncodedHost, - [host stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLHostAllowedCharacterSet]]); - [self _regenerateURL]; + _dirty = YES; } - (NSString *) password @@ -2554,10 +2518,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPassword: (NSString *)password { ASSIGNCOPY(internal->_password, password); - ASSIGNCOPY(internal->_percentEncodedPassword, - [password stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPasswordAllowedCharacterSet]]); - [self _regenerateURL]; + _dirty = YES; } - (NSString *) path @@ -2568,10 +2529,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPath: (NSString *)path { ASSIGNCOPY(internal->_path, path); - ASSIGNCOPY(internal->_percentEncodedPath, - [path stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]); - [self _regenerateURL]; + _dirty = YES; } - (NSNumber *) port @@ -2582,7 +2540,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPort: (NSNumber *)port { ASSIGNCOPY(internal->_port, port); - [self _regenerateURL]; + _dirty = YES; } - (NSString *) query @@ -2637,8 +2595,8 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } ASSIGNCOPY(internal->_query, query); // add query string... - ASSIGNCOPY(internal->_percentEncodedQuery, query); ASSIGNCOPY(internal->_queryItems, queryItems); + _dirty = YES; } - (NSString *) scheme @@ -2649,6 +2607,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { ASSIGNCOPY(internal->_scheme, scheme); + _dirty = YES; } - (NSString *) user @@ -2659,136 +2618,149 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setUser: (NSString *)user { ASSIGNCOPY(internal->_user, user); - ASSIGNCOPY(internal->_percentEncodedUser, - [user stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLUserAllowedCharacterSet]]); + _dirty = YES; } // Accessing Components in PercentEncoded Format - (NSString *) percentEncodedFragment { - return internal->_percentEncodedFragment; + return [internal->_fragment stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLFragmentAllowedCharacterSet]]; } - (void) setPercentEncodedFragment: (NSString *)fragment { - ASSIGNCOPY(internal->_percentEncodedFragment, fragment); ASSIGNCOPY(internal->_fragment, [fragment stringByRemovingPercentEncoding]); + _dirty = YES; } - (NSString *) percentEncodedHost { - return internal->_percentEncodedHost; + return [internal->_host stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLHostAllowedCharacterSet]]; } - (void) setPercentEncodedHost: (NSString *)host { - ASSIGNCOPY(internal->_percentEncodedHost, host); ASSIGNCOPY(internal->_host, [host stringByRemovingPercentEncoding]); + _dirty = YES; } - (NSString *) percentEncodedPassword { - return internal->_percentEncodedPassword; + return [internal->_password stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPasswordAllowedCharacterSet]]; } - (void) setPercentEncodedPassword: (NSString *)password { - ASSIGNCOPY(internal->_percentEncodedPassword, password); ASSIGNCOPY(internal->_password, [password stringByRemovingPercentEncoding]); + _dirty = YES; } - (NSString *) percentEncodedPath { - return internal->_percentEncodedPath; + return [internal->_path stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPathAllowedCharacterSet]]; } - (void) setPercentEncodedPath: (NSString *)path { - ASSIGNCOPY(internal->_percentEncodedPath, path); ASSIGNCOPY(internal->_path, [path stringByRemovingPercentEncoding]); + _dirty = YES; } - (NSString *) percentEncodedQuery { - return internal->_percentEncodedQuery; + return internal->_query; } - (void) setPercentEncodedQuery: (NSString *)query { - ASSIGNCOPY(internal->_percentEncodedQuery, query); ASSIGNCOPY(internal->_query, [query stringByRemovingPercentEncoding]); + _dirty = YES; } - (NSArray *) percentEncodedQueryItems { - return internal->_percentEncodedQueryItems; + return internal->_queryItems; } - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { - ASSIGNCOPY(internal->_percentEncodedQueryItems, queryItems); + [self setQueryItems: queryItems]; } - (NSString *) percentEncodedScheme { - return internal->_percentEncodedScheme; + return [internal->_path stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLPathAllowedCharacterSet]]; } - (void) setPercentEncodedScheme: (NSString *)scheme { - ASSIGNCOPY(internal->_percentEncodedScheme, scheme); + ASSIGNCOPY(internal->_scheme, scheme); + _dirty = YES; } - (NSString *) percentEncodedUser { - return internal->_percentEncodedUser;; + return [internal->_user stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLUserAllowedCharacterSet]]; } - (void) setPercentEncodedUser: (NSString *)user { - ASSIGNCOPY(internal->_percentEncodedUser, user); ASSIGNCOPY(internal->_user, [user stringByRemovingPercentEncoding]); + _dirty = YES; } // Locating components of the URL string representation - (NSRange) rangeOfFragment { + [self _regenerateURL]; return internal->_rangeOfFragment; } - (NSRange) rangeOfHost { + [self _regenerateURL]; return internal->_rangeOfHost; } - (NSRange) rangeOfPassword { + [self _regenerateURL]; return internal->_rangeOfPassword; } - (NSRange) rangeOfPath { + [self _regenerateURL]; return internal->_rangeOfPath; } - (NSRange) rangeOfPort { + [self _regenerateURL]; return internal->_rangeOfPort; } - (NSRange) rangeOfQuery { + [self _regenerateURL]; return internal->_rangeOfQuery; } - (NSRange) rangeOfScheme { + [self _regenerateURL]; return internal->_rangeOfScheme; } - (NSRange) rangeOfUser { + [self _regenerateURL]; return internal->_rangeOfUser; } From 181346c56802d47be4b0101ebf0576d9c268bd7c Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Fri, 3 Apr 2020 17:53:34 +0200 Subject: [PATCH 25/39] Get too compile with gcc. Address some pull request comments. --- Source/NSURL.m | 189 ++++++++++++++++++++++++------------------------- 1 file changed, 94 insertions(+), 95 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 7e68f9c33..a35cebc27 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2327,13 +2327,13 @@ GS_PRIVATE_INTERNAL(NSURLComponents) @implementation NSURLComponents // Creating URL components... -+ (instancetype) componentsWithString:(NSString *)urlString ++ (instancetype) componentsWithString: (NSString *)urlString { return [[NSURLComponents alloc] initWithString: urlString]; } -+ (instancetype) componentsWithURL:(NSURL *)url - resolvingAgainstBaseURL:(BOOL)resolve ++ (instancetype) componentsWithURL: (NSURL *)url + resolvingAgainstBaseURL: (BOOL)resolve { return [[NSURLComponents alloc] initWithURL: url resolvingAgainstBaseURL: resolve]; @@ -2358,7 +2358,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) return self; } -- (instancetype)initWithString:(NSString *)URLString +- (instancetype) initWithString: (NSString *)URLString { self = [self init]; if (self != nil) @@ -2368,13 +2368,14 @@ GS_PRIVATE_INTERNAL(NSURLComponents) return self; } -- (instancetype)initWithURL:(NSURL *)url - resolvingAgainstBaseURL:(BOOL)resolve +- (instancetype) initWithURL: (NSURL *)url + resolvingAgainstBaseURL: (BOOL)resolve { - NSURL *tempURL = url; self = [self init]; if (self != nil) { + NSURL *tempURL = url; + if (resolve) { tempURL = [url absoluteURL]; @@ -2406,6 +2407,46 @@ GS_PRIVATE_INTERNAL(NSURLComponents) resolvingAgainstBaseURL: NO]; } +// Regenerate URL when components are changed... +- (void) _regenerateURL +{ + if (internal->_dirty == NO) + { + return; + } + else + { + NSURL *u; + u = [[NSURL alloc] initWithScheme: internal->_scheme + user: internal->_user + password: internal->_password + host: internal->_host + port: internal->_port + fullPath: internal->_path + parameterString: nil + query: [self query] + fragment: internal->_fragment]; + ASSIGNCOPY(internal->_url, u); + + { + // Find ranges + NSString *urlString = [u absoluteString]; +#define URL_COMPONENT_RANGE(part) \ + (part ? [urlString rangeOfString:part] : NSMakeRange(NSNotFound, 0)) + internal->_rangeOfFragment = URL_COMPONENT_RANGE(internal->_fragment); + internal->_rangeOfHost = URL_COMPONENT_RANGE(internal->_host); + internal->_rangeOfPassword = URL_COMPONENT_RANGE(internal->_password); + internal->_rangeOfPath = URL_COMPONENT_RANGE(internal->_path); + internal->_rangeOfPort = URL_COMPONENT_RANGE([internal->_port stringValue]); + internal->_rangeOfQuery = URL_COMPONENT_RANGE([self query]); + internal->_rangeOfScheme = URL_COMPONENT_RANGE(internal->_scheme); + internal->_rangeOfUser = URL_COMPONENT_RANGE(internal->_user); +#undef URL_COMPONENT_RANGE + } + internal->_dirty = NO; + } + } + // Getting the URL - (NSString *) string { @@ -2427,66 +2468,22 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setURL: (NSURL *)url { - ASSIGNCOPY(internal->_url, url); - - // components... - ASSIGNCOPY(internal->_fragment, [url fragment]); - ASSIGNCOPY(internal->_host, [url host]); - ASSIGNCOPY(internal->_password, [url password]); - ASSIGNCOPY(internal->_path, [url path]); - ASSIGNCOPY(internal->_port, [url port]); - ASSIGNCOPY(internal->_query, [url query]); - ASSIGNCOPY(internal->_scheme, [url scheme]); - ASSIGNCOPY(internal->_user, [url user]); - - _dirty = YES; + // Set all the components... + [self setScheme: [url scheme]]; + [self setHost: [url host]]; + [self setPort: [url port]]; + [self setUser: [url user]]; + [self setPassword: [url password]]; + [self setPath: [url path]]; + [self setQuery: [url query]]; + [self setFragment: [url fragment]]; } -- (NSURL *)URLRelativeToURL: (NSURL *)baseURL +- (NSURL *) URLRelativeToURL: (NSURL *)baseURL { return nil; } -// Regenerate URL when components are changed... -- (void) _regenerateURL -{ - if (_dirty == NO) - { - return; - } - else - { - NSURL *u; - u = [[NSURL alloc] initWithScheme: internal->_scheme - user: internal->_user - password: internal->_password - host: internal->_host - port: internal->_port - fullPath: internal->_path - parameterString: nil - query: internal->_query - fragment: internal->_fragment]; - ASSIGNCOPY(internal->_url, u); - - { - // Find ranges - NSString *urlString = [u absoluteString]; -#define URL_COMPONENT_RANGE(part) \ - (part ? [urlString rangeOfString:part] : NSMakeRange(NSNotFound, 0)) - internal->_rangeOfFragment = URL_COMPONENT_RANGE(internal->_fragment); - internal->_rangeOfHost = URL_COMPONENT_RANGE(internal->_host); - internal->_rangeOfPassword = URL_COMPONENT_RANGE(internal->_password); - internal->_rangeOfPath = URL_COMPONENT_RANGE(internal->_path); - internal->_rangeOfPort = URL_COMPONENT_RANGE([internal->_port stringValue]); - internal->_rangeOfQuery = URL_COMPONENT_RANGE(internal->_query); - internal->_rangeOfScheme = URL_COMPONENT_RANGE(internal->_scheme); - internal->_rangeOfUser = URL_COMPONENT_RANGE(internal->_user); -#undef URL_COMPONENT_RANGE - } - _dirty = NO; - } - } - // Accessing Components in Native Format - (NSString *) fragment { @@ -2496,7 +2493,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setFragment: (NSString *)fragment { ASSIGNCOPY(internal->_fragment, fragment); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) host @@ -2507,7 +2504,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setHost: (NSString *)host { ASSIGNCOPY(internal->_host, host); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) password @@ -2518,7 +2515,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPassword: (NSString *)password { ASSIGNCOPY(internal->_password, password); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) path @@ -2529,7 +2526,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPath: (NSString *)path { ASSIGNCOPY(internal->_path, path); - _dirty = YES; + internal->_dirty = YES; } - (NSNumber *) port @@ -2540,17 +2537,31 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPort: (NSNumber *)port { ASSIGNCOPY(internal->_port, port); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) query { - return internal->_query; + NSString *query = @""; + NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSURLQueryItem *item = nil; + + while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + { + NSString *name = [item name]; + NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; + NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; + query = [query stringByAppendingString: itemString]; + if (item != [internal->_queryItems lastObject]) + { + query = [query stringByAppendingString: @"&"]; + } + } + return query; } - (void) setQuery: (NSString *)query { - ASSIGNCOPY(internal->_query, query); if (query != nil) { NSMutableArray *result = [NSMutableArray arrayWithCapacity: 5]; @@ -2569,6 +2580,10 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } [self setQueryItems: result]; } + else + { + [self setQueryItems: nil]; + } } - (NSArray *) queryItems @@ -2578,25 +2593,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQueryItems: (NSArray *)queryItems { - NSString *query = @""; - NSEnumerator *en = [queryItems objectEnumerator]; - NSURLQueryItem *item = nil; - - while ((item = (NSURLQueryItem *)[en nextObject]) != nil) - { - NSString *name = [item name]; - NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; - NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; - query = [query stringByAppendingString: itemString]; - if (item != [queryItems lastObject]) - { - query = [query stringByAppendingString: @"&"]; - } - } - - ASSIGNCOPY(internal->_query, query); // add query string... + ASSIGNCOPY(internal->_queryItems, queryItems); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) scheme @@ -2607,7 +2606,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { ASSIGNCOPY(internal->_scheme, scheme); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) user @@ -2618,7 +2617,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setUser: (NSString *)user { ASSIGNCOPY(internal->_user, user); - _dirty = YES; + internal->_dirty = YES; } // Accessing Components in PercentEncoded Format @@ -2631,7 +2630,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedFragment: (NSString *)fragment { ASSIGNCOPY(internal->_fragment, [fragment stringByRemovingPercentEncoding]); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) percentEncodedHost @@ -2643,7 +2642,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedHost: (NSString *)host { ASSIGNCOPY(internal->_host, [host stringByRemovingPercentEncoding]); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) percentEncodedPassword @@ -2655,7 +2654,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPassword: (NSString *)password { ASSIGNCOPY(internal->_password, [password stringByRemovingPercentEncoding]); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) percentEncodedPath @@ -2667,7 +2666,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPath: (NSString *)path { ASSIGNCOPY(internal->_path, [path stringByRemovingPercentEncoding]); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) percentEncodedQuery @@ -2678,7 +2677,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedQuery: (NSString *)query { ASSIGNCOPY(internal->_query, [query stringByRemovingPercentEncoding]); - _dirty = YES; + internal->_dirty = YES; } - (NSArray *) percentEncodedQueryItems @@ -2700,7 +2699,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedScheme: (NSString *)scheme { ASSIGNCOPY(internal->_scheme, scheme); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) percentEncodedUser @@ -2712,7 +2711,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedUser: (NSString *)user { ASSIGNCOPY(internal->_user, [user stringByRemovingPercentEncoding]); - _dirty = YES; + internal->_dirty = YES; } // Locating components of the URL string representation From c170c8c1e7d12fe5bef01fc4aedfb4d9eca873a6 Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Fri, 3 Apr 2020 18:15:07 +0200 Subject: [PATCH 26/39] Correct more issues and flag the remaining ones with "FIXME". --- Source/NSURL.m | 56 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index a35cebc27..7c1c4e891 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -51,7 +51,6 @@ function may be incorrect NSString *_password; \ NSString *_path; \ NSNumber *_port; \ - NSString *_query; \ NSArray *_queryItems; \ NSString *_scheme; \ NSString *_user; \ @@ -2393,7 +2392,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) RELEASE(internal->_password); RELEASE(internal->_path); RELEASE(internal->_port); - RELEASE(internal->_query); RELEASE(internal->_queryItems); RELEASE(internal->_scheme); RELEASE(internal->_user); @@ -2416,6 +2414,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } else { + // FIXME NSURL *u; u = [[NSURL alloc] initWithScheme: internal->_scheme user: internal->_user @@ -2450,14 +2449,13 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Getting the URL - (NSString *) string { - [self _regenerateURL]; - return [internal->_url absoluteString]; + return [[self url] absoluteString]; } - (void) setString: (NSString *)urlString { NSURL *url = [NSURL URLWithString: urlString]; - [self setURL : url]; + [self setURL: url]; } - (NSURL *) URL @@ -2549,13 +2547,13 @@ GS_PRIVATE_INTERNAL(NSURLComponents) while ((item = (NSURLQueryItem *)[en nextObject]) != nil) { NSString *name = [item name]; - NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; + NSString *value = [item value]; NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; - query = [query stringByAppendingString: itemString]; - if (item != [internal->_queryItems lastObject]) + if ([query length] > 0) { query = [query stringByAppendingString: @"&"]; } + query = [query stringByAppendingString: itemString]; } return query; } @@ -2629,8 +2627,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedFragment: (NSString *)fragment { - ASSIGNCOPY(internal->_fragment, [fragment stringByRemovingPercentEncoding]); - internal->_dirty = YES; + [self setFragment: [fragment stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedHost @@ -2641,8 +2638,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedHost: (NSString *)host { - ASSIGNCOPY(internal->_host, [host stringByRemovingPercentEncoding]); - internal->_dirty = YES; + [self setHost: [host stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedPassword @@ -2653,8 +2649,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPassword: (NSString *)password { - ASSIGNCOPY(internal->_password, [password stringByRemovingPercentEncoding]); - internal->_dirty = YES; + [self setPassword: [password stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedPath @@ -2665,41 +2660,55 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPath: (NSString *)path { - ASSIGNCOPY(internal->_path, [path stringByRemovingPercentEncoding]); - internal->_dirty = YES; + [self setPath: [path stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedQuery { - return internal->_query; + NSString *query = @""; + NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSURLQueryItem *item = nil; + + while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + { + NSString *name = [[item name] _stringByAddingPercentEscapesForQuery]; + NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; + NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; + if ([query length] > 0) + { + query = [query stringByAppendingString: @"&"]; + } + query = [query stringByAppendingString: itemString]; + } + return query; } - (void) setPercentEncodedQuery: (NSString *)query { - ASSIGNCOPY(internal->_query, [query stringByRemovingPercentEncoding]); - internal->_dirty = YES; + [self setQuery: [query stringByRemovingPercentEncoding]]; } - (NSArray *) percentEncodedQueryItems { + // FIXME return internal->_queryItems; } - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { + // FIXME [self setQueryItems: queryItems]; } - (NSString *) percentEncodedScheme { - return [internal->_path stringByAddingPercentEncodingWithAllowedCharacters: + return [internal->_scheme stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLPathAllowedCharacterSet]]; } - (void) setPercentEncodedScheme: (NSString *)scheme { - ASSIGNCOPY(internal->_scheme, scheme); - internal->_dirty = YES; + [self setScheme: [scheme stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedUser @@ -2710,8 +2719,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedUser: (NSString *)user { - ASSIGNCOPY(internal->_user, [user stringByRemovingPercentEncoding]); - internal->_dirty = YES; + [self setUser: [user stringByRemovingPercentEncoding]]; } // Locating components of the URL string representation From 0bc1052bd60f1f713b235dee5299107bf2812045 Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Fri, 3 Apr 2020 18:37:55 +0200 Subject: [PATCH 27/39] Fix typo in last commit. --- Source/NSURL.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 7c1c4e891..ff8ae03cb 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2449,7 +2449,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Getting the URL - (NSString *) string { - return [[self url] absoluteString]; + return [[self URL] absoluteString]; } - (void) setString: (NSString *)urlString From 2d135069fbaa0d3b7d56e2db4ceada60fec6b212 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 3 Apr 2020 15:48:27 -0400 Subject: [PATCH 28/39] Remove query --- Source/NSURL.m | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 7e68f9c33..f8ebaaaf2 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -45,7 +45,6 @@ function may be incorrect NSString *_value; #define GS_NSURLComponents_IVARS \ - NSURL *_url; \ NSString *_fragment; \ NSString *_host; \ NSString *_password; \ @@ -2392,7 +2391,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) RELEASE(internal->_password); RELEASE(internal->_path); RELEASE(internal->_port); - RELEASE(internal->_query); RELEASE(internal->_queryItems); RELEASE(internal->_scheme); RELEASE(internal->_user); @@ -2409,8 +2407,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Getting the URL - (NSString *) string { - [self _regenerateURL]; - return [internal->_url absoluteString]; + return [[self _regenerateURL] absoluteString]; } - (void) setString: (NSString *)urlString @@ -2421,14 +2418,11 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSURL *) URL { - [self _regenerateURL]; - return internal->_url; + return [self _regenerateURL]; } - (void) setURL: (NSURL *)url { - ASSIGNCOPY(internal->_url, url); - // components... ASSIGNCOPY(internal->_fragment, [url fragment]); ASSIGNCOPY(internal->_host, [url host]); @@ -2448,11 +2442,11 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } // Regenerate URL when components are changed... -- (void) _regenerateURL +- (NSURL *) _regenerateURL { if (_dirty == NO) { - return; + return nil; } else { @@ -2464,9 +2458,8 @@ GS_PRIVATE_INTERNAL(NSURLComponents) port: internal->_port fullPath: internal->_path parameterString: nil - query: internal->_query + query: [self query] fragment: internal->_fragment]; - ASSIGNCOPY(internal->_url, u); { // Find ranges @@ -2484,6 +2477,8 @@ GS_PRIVATE_INTERNAL(NSURLComponents) #undef URL_COMPONENT_RANGE } _dirty = NO; + + return u; } } From b71f65f4788315b692ecc1528533d316150acca7 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 4 Apr 2020 06:38:19 -0400 Subject: [PATCH 29/39] Fixes for FIXME's --- Source/NSURL.m | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 99f295e20..7075608c3 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2542,7 +2542,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) while ((item = (NSURLQueryItem *)[en nextObject]) != nil) { NSString *name = [item name]; - NSString *value = [item value]; + NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; if ([query length] > 0) { @@ -2585,8 +2585,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } - (void) setQueryItems: (NSArray *)queryItems -{ - +{ ASSIGNCOPY(internal->_queryItems, queryItems); internal->_dirty = YES; } @@ -2685,14 +2684,34 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSArray *) percentEncodedQueryItems { - // FIXME - return internal->_queryItems; + NSMutableArray *items = [NSMutableArray arrayWithCapacity: [internal->_queryItems count]]; + NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSURLQueryItem *i = nil; + + while((i = [en nextObject]) != nil) + { + NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [i name] + value: [[i value] _stringByAddingPercentEscapesForQuery]]; + [items addObject: ni]; + } + + return items; } - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { - // FIXME - [self setQueryItems: queryItems]; + NSMutableArray *items = [NSMutableArray arrayWithCapacity: [queryItems count]]; + NSEnumerator *en = [queryItems objectEnumerator]; + NSURLQueryItem *i = nil; + + while((i = [en nextObject]) != nil) + { + NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [i name] + value: [[i value] stringByRemovingPercentEncoding]]; + [items addObject: ni]; + } + + [self setQueryItems: items]; } - (NSString *) percentEncodedScheme From 5f1541d154679643f5cb14488bd97d27ccf3c790 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 4 Apr 2020 06:48:02 -0400 Subject: [PATCH 30/39] Always regenerate when we call [NSURLComponents URL] otherwise subsequent calls will return nil --- Source/NSURL.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/NSURL.m b/Source/NSURL.m index 7075608c3..e1278e63c 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2456,6 +2456,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSURL *) URL { + internal->_dirty = YES; return [self _regenerateURL]; } From ca6e48910a69b0fdca5f849c2b9cfde46ef1d0b1 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 4 Apr 2020 07:04:06 -0400 Subject: [PATCH 31/39] Minor fix to remove/add percent encoding to name portion of query item --- Source/NSURL.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index e1278e63c..2d453f744 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2691,7 +2691,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) while((i = [en nextObject]) != nil) { - NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [i name] + NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [[i name] _stringByAddingPercentEscapesForQuery] value: [[i value] _stringByAddingPercentEscapesForQuery]]; [items addObject: ni]; } @@ -2707,7 +2707,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) while((i = [en nextObject]) != nil) { - NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [i name] + NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [[i name] stringByRemovingPercentEncoding] value: [[i value] stringByRemovingPercentEncoding]]; [items addObject: ni]; } From d05b799740b49e6d3d964b0a4ff40ff14920d5de Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Sat, 4 Apr 2020 13:36:51 +0200 Subject: [PATCH 32/39] Restore caching of URL. Rewrite URL building to get the ranges correct. Build URL with escaped components. Build query from percentEncodedQueryItems. --- Source/NSURL.m | 132 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 98 insertions(+), 34 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 2d453f744..983f97097 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -45,6 +45,7 @@ function may be incorrect NSString *_value; #define GS_NSURLComponents_IVARS \ + NSURL *_url; \ NSString *_fragment; \ NSString *_host; \ NSString *_password; \ @@ -2385,6 +2386,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) dealloc { + RELEASE(internal->_url); RELEASE(internal->_fragment); RELEASE(internal->_host); RELEASE(internal->_password); @@ -2404,42 +2406,104 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } // Regenerate URL when components are changed... -- (NSURL *) _regenerateURL +- (void) _regenerateURL { - NSURL *u = nil; + NSString *urlString = @""; + NSInteger location = 0; + if (internal->_dirty == NO) { - return nil; + return; } - u = [[NSURL alloc] initWithScheme: internal->_scheme - user: internal->_user - password: internal->_password - host: internal->_host - port: internal->_port - fullPath: internal->_path - parameterString: nil - query: [self query] - fragment: internal->_fragment]; - - { - // Find ranges - NSString *urlString = [u absoluteString]; -#define URL_COMPONENT_RANGE(part) \ - (part ? [urlString rangeOfString:part] : NSMakeRange(NSNotFound, 0)) - internal->_rangeOfFragment = URL_COMPONENT_RANGE(internal->_fragment); - internal->_rangeOfHost = URL_COMPONENT_RANGE(internal->_host); - internal->_rangeOfPassword = URL_COMPONENT_RANGE(internal->_password); - internal->_rangeOfPath = URL_COMPONENT_RANGE(internal->_path); - internal->_rangeOfPort = URL_COMPONENT_RANGE([internal->_port stringValue]); - internal->_rangeOfQuery = URL_COMPONENT_RANGE([self query]); - internal->_rangeOfScheme = URL_COMPONENT_RANGE(internal->_scheme); - internal->_rangeOfUser = URL_COMPONENT_RANGE(internal->_user); -#undef URL_COMPONENT_RANGE - } + // Build up the URL from components... + if (internal->_scheme != nil) + { + NSString *comp = [self percentEncodedScheme]; + NSInteger len = [comp length]; + urlString = [urlString stringByAppendingFormat: @"%@://", comp]; + internal->_rangeOfScheme = NSMakeRange(location, len); + location += len + 3; + } + else + { + internal->_rangeOfScheme = NSMakeRange(NSNotFound, 0); + } + if (internal->_user != nil) + { + if (internal->_password != nil) + { + NSString *comp1 = [self percentEncodedUser]; + NSInteger len1 = [comp1 length]; + NSString *comp2 = [self percentEncodedPassword]; + NSInteger len2 = [comp2 length]; + urlString = [urlString stringByAppendingFormat: @"%@:%@@", comp1, comp2]; + internal->_rangeOfUser = NSMakeRange(location, len1); + location += len1 + 1; + internal->_rangeOfPassword = NSMakeRange(location, len2); + location += len2 + 1; + } + else + { + NSString *comp = [self percentEncodedUser]; + NSInteger len = [comp length]; + urlString = [urlString stringByAppendingFormat: @"%@@", comp]; + internal->_rangeOfUser = NSMakeRange(location, len); + location += len + 1; + } + } + + if (internal->_host != nil) + { + NSString *comp = [self percentEncodedHost]; + NSInteger len = [comp length]; + urlString = [urlString stringByAppendingFormat: @"%@", comp]; + internal->_rangeOfHost = NSMakeRange(location, len); + location += len; + } + + if (internal->_port != nil) + { + NSString *comp = [[self port] stringValue]; + NSInteger len = [comp length]; + urlString = [urlString stringByAppendingFormat: @":%@", comp]; + location += 1; + internal->_rangeOfPort = NSMakeRange(location, len); + location += len; + } + + if (internal->_path != nil) + { + NSString *comp = [self percentEncodedPath]; + NSInteger len = [comp length]; + urlString = [urlString stringByAppendingFormat: @"%@", comp]; + internal->_rangeOfPath = NSMakeRange(location, len); + location += len; + } + + if ([internal->_queryItems count] > 0) // if query items is nil, this will also return 0 + { + NSString *comp = [self percentEncodedQuery]; + NSInteger len = [comp length]; + urlString = [urlString stringByAppendingFormat: @"?%@", comp]; + location += 1; + internal->_rangeOfQuery = NSMakeRange(location, len); + location += len; + } + + if (internal->_fragment != nil) + { + NSString *comp = [self percentEncodedFragment]; + NSInteger len = [comp length]; + urlString = [urlString stringByAppendingFormat: @"#%@", comp]; + location += 1; + internal->_rangeOfFragment = NSMakeRange(location, len); + location += len; + } + + ASSIGNCOPY(internal->_url, [NSURL URLWithString: urlString]); internal->_dirty = NO; - return u; } // Getting the URL @@ -2456,8 +2520,8 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSURL *) URL { - internal->_dirty = YES; - return [self _regenerateURL]; + [self _regenerateURL]; + return internal->_url; } - (void) setURL: (NSURL *)url @@ -2661,13 +2725,13 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSString *) percentEncodedQuery { NSString *query = @""; - NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSEnumerator *en = [[self percentEncodedQueryItems] objectEnumerator]; NSURLQueryItem *item = nil; while ((item = (NSURLQueryItem *)[en nextObject]) != nil) { - NSString *name = [[item name] _stringByAddingPercentEscapesForQuery]; - NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; + NSString *name = [item name]; + NSString *value = [item value]; NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; if ([query length] > 0) { From 4ffce48b04141c0f81a752ce1c0ea3c286f6ef93 Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Sat, 4 Apr 2020 14:22:25 +0100 Subject: [PATCH 33/39] I suggest when we regenerate we build the URL by appending to a mutable string sas this would be hugely more efficient. --- Source/NSURL.m | 83 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 983f97097..a534115af 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2408,21 +2408,26 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Regenerate URL when components are changed... - (void) _regenerateURL { - NSString *urlString = @""; - NSInteger location = 0; + NSMutableString *urlString; + NSString *component; + NSUInteger location; + NSUInteger len; if (internal->_dirty == NO) { return; } + urlString = [[NSMutableString alloc] initWithCapacity: 1000]; + location = 0; // Build up the URL from components... if (internal->_scheme != nil) { - NSString *comp = [self percentEncodedScheme]; - NSInteger len = [comp length]; - urlString = [urlString stringByAppendingFormat: @"%@://", comp]; + component = [self percentEncodedScheme]; + [urlString appendString: component]; + len = [component length]; internal->_rangeOfScheme = NSMakeRange(location, len); + [urlString appendString: @"://"]; location += len + 3; } else @@ -2434,76 +2439,87 @@ GS_PRIVATE_INTERNAL(NSURLComponents) { if (internal->_password != nil) { - NSString *comp1 = [self percentEncodedUser]; - NSInteger len1 = [comp1 length]; - NSString *comp2 = [self percentEncodedPassword]; - NSInteger len2 = [comp2 length]; - urlString = [urlString stringByAppendingFormat: @"%@:%@@", comp1, comp2]; - internal->_rangeOfUser = NSMakeRange(location, len1); - location += len1 + 1; - internal->_rangeOfPassword = NSMakeRange(location, len2); - location += len2 + 1; + component = [self percentEncodedUser]; + len = [component length]; + [urlString appendString: component]; + internal->_rangeOfUser = NSMakeRange(location, len); + [urlString appendString: @":"]; + location += len + 1; + + component = [self percentEncodedPassword]; + len = [component length]; + [urlString appendString: component]; + internal->_rangeOfUser = NSMakeRange(location, len); + [urlString appendString: @"@"]; + location += len + 1; } else { - NSString *comp = [self percentEncodedUser]; - NSInteger len = [comp length]; - urlString = [urlString stringByAppendingFormat: @"%@@", comp]; + component = [self percentEncodedUser]; + len = [component length]; + [urlString appendString: component]; internal->_rangeOfUser = NSMakeRange(location, len); + [urlString appendString: @"@"]; location += len + 1; } } if (internal->_host != nil) { - NSString *comp = [self percentEncodedHost]; - NSInteger len = [comp length]; - urlString = [urlString stringByAppendingFormat: @"%@", comp]; + component = [self percentEncodedHost]; + len = [component length]; + [urlString appendString: component]; internal->_rangeOfHost = NSMakeRange(location, len); location += len; } if (internal->_port != nil) { - NSString *comp = [[self port] stringValue]; - NSInteger len = [comp length]; - urlString = [urlString stringByAppendingFormat: @":%@", comp]; + component = [[self port] stringValue]; + len = [component length]; + [urlString appendString: @":"]; location += 1; + [urlString appendString: component]; internal->_rangeOfPort = NSMakeRange(location, len); location += len; } + /* FIXME ... if the path is empty we still need a '/' do we not? + */ if (internal->_path != nil) { - NSString *comp = [self percentEncodedPath]; - NSInteger len = [comp length]; - urlString = [urlString stringByAppendingFormat: @"%@", comp]; + component = [self percentEncodedPath]; + len = [component length]; + [urlString appendString: component]; internal->_rangeOfPath = NSMakeRange(location, len); location += len; } - if ([internal->_queryItems count] > 0) // if query items is nil, this will also return 0 + if ([internal->_queryItems count] > 0) { - NSString *comp = [self percentEncodedQuery]; - NSInteger len = [comp length]; - urlString = [urlString stringByAppendingFormat: @"?%@", comp]; + component = [self percentEncodedQuery]; + len = [component length]; + [urlString appendString: @"?"]; location += 1; + [urlString appendString: component]; internal->_rangeOfQuery = NSMakeRange(location, len); location += len; } if (internal->_fragment != nil) { - NSString *comp = [self percentEncodedFragment]; - NSInteger len = [comp length]; - urlString = [urlString stringByAppendingFormat: @"#%@", comp]; + component = [self percentEncodedFragment]; + len = [component length]; + [urlString appendString: @"#"]; location += 1; + [urlString appendString: component]; internal->_rangeOfFragment = NSMakeRange(location, len); location += len; } ASSIGNCOPY(internal->_url, [NSURL URLWithString: urlString]); internal->_dirty = NO; + RELEASE(urlString); } // Getting the URL @@ -2609,6 +2625,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) NSString *name = [item name]; NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; + if ([query length] > 0) { query = [query stringByAppendingString: @"&"]; From 564f61d572b500873f0808349d0b8113fd7e4fe8 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 4 Apr 2020 09:44:22 -0400 Subject: [PATCH 34/39] Add tests for NSURLComponents --- Headers/Foundation/NSURL.h | 2 -- Source/NSURL.m | 13 +------- Tests/base/NSURL/components.m | 58 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 Tests/base/NSURL/components.m diff --git a/Headers/Foundation/NSURL.h b/Headers/Foundation/NSURL.h index d79fddfd3..7ca110839 100644 --- a/Headers/Foundation/NSURL.h +++ b/Headers/Foundation/NSURL.h @@ -700,8 +700,6 @@ GS_NSURLComponents_IVARS; - (NSArray *) percentEncodedQueryItems; - (void) setPercentEncodedQueryItems: (NSArray *)queryItems; #endif -- (NSString *) percentEncodedScheme; -- (void) setPercentEncodedScheme: (NSString *)scheme; - (NSString *) percentEncodedUser; - (void) setPercentEncodedUser: (NSString *)user; diff --git a/Source/NSURL.m b/Source/NSURL.m index 983f97097..94afe4b3f 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2419,7 +2419,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Build up the URL from components... if (internal->_scheme != nil) { - NSString *comp = [self percentEncodedScheme]; + NSString *comp = [self scheme]; NSInteger len = [comp length]; urlString = [urlString stringByAppendingFormat: @"%@://", comp]; internal->_rangeOfScheme = NSMakeRange(location, len); @@ -2779,17 +2779,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) [self setQueryItems: items]; } -- (NSString *) percentEncodedScheme -{ - return [internal->_scheme stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLPathAllowedCharacterSet]]; -} - -- (void) setPercentEncodedScheme: (NSString *)scheme -{ - [self setScheme: [scheme stringByRemovingPercentEncoding]]; -} - - (NSString *) percentEncodedUser { return [internal->_user stringByAddingPercentEncodingWithAllowedCharacters: diff --git a/Tests/base/NSURL/components.m b/Tests/base/NSURL/components.m new file mode 100644 index 000000000..82072ce80 --- /dev/null +++ b/Tests/base/NSURL/components.m @@ -0,0 +1,58 @@ +#import +#import "Testing.h" +#import "ObjectTesting.h" + + +int main() +{ + START_SET("components"); + + NSURLComponents *components = [NSURLComponents componentsWithURL:[NSURL URLWithString:@"https://user:password@some.host.com"] resolvingAgainstBaseURL:NO]; + + PASS([[[components URL] absoluteString] isEqualToString: @"https://user:password@some.host.com"], + "Absolute URL string is correct"); + + + [components setQueryItems: [NSArray arrayWithObjects: + [NSURLQueryItem queryItemWithName:@"lang" value:@"en"], + [NSURLQueryItem queryItemWithName:@"response_type" value:@"code"], + [NSURLQueryItem queryItemWithName:@"uri" value:[NSURL URLWithString:@"https://some.url.com/path?param1=one¶m2=two"].absoluteString], + nil]]; + // URL + PASS([[components string] isEqualToString: + @"https://user:password@some.host.com?lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], + "URL string is correct"); + + // encoded... + PASS([[components percentEncodedQuery] isEqualToString: + @"lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], + "percentEncodedQuery is correct"); + PASS([[components percentEncodedHost] isEqualToString: + @"some.host.com"], + "percentEncodedHost is correct"); + PASS([[components percentEncodedUser] isEqualToString: + @"user"], + "percentEncodedUser is correct"); + PASS([[components percentEncodedPassword] isEqualToString: + @"password"], + "percentEncodedPassword is correct"); + + // unencoded... + PASS([[components query] isEqualToString: + @"lang=en&response_type=code&uri=https://some.url.com/path?param1=one¶m2=two"], + "query is correct"); + PASS([[components host] isEqualToString: + @"some.host.com"], + "host is correct"); + PASS([[components user] isEqualToString: + @"user"], + "user is correct"); + PASS([[components password] isEqualToString: + @"password"], + "password is correct"); + + + END_SET("components") + + return 0; +} From 8eff23e780a54b71a221607c926ee19d84409851 Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Sat, 4 Apr 2020 15:13:14 +0100 Subject: [PATCH 35/39] Rewrite query handling code to try to mimic OSX documentation with regards to the differences between setting nil/empty query strings/items and also in the handling of query items with nothing before the '=', nothing after the '=', and the case where there is no '=' character (also the totally empty case where the query string contains a double ampersand (&&) sequence). --- Source/NSURL.m | 166 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 120 insertions(+), 46 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index a534115af..437f695aa 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2635,35 +2635,68 @@ GS_PRIVATE_INTERNAL(NSURLComponents) return query; } -- (void) setQuery: (NSString *)query +- (void) _setQuery: (NSString *)query fromPercentEncodedString: (BOOL)encoded { - if (query != nil) + /* Parse according to https://developer.apple.com/documentation/foundation/nsurlcomponents/1407752-queryitems?language=objc + */ + if (nil == query) { - NSMutableArray *result = [NSMutableArray arrayWithCapacity: 5]; - NSArray *items = [query componentsSeparatedByString: @"&"]; - NSEnumerator *en = [items objectEnumerator]; - id item = nil; + [self setQueryItems: nil]; + } + else + { + NSMutableArray *result = [NSMutableArray arrayWithCapacity: 5]; + NSArray *items = [query componentsSeparatedByString: @"&"]; + NSEnumerator *en = [items objectEnumerator]; + id item = nil; while ((item = [en nextObject]) != nil) { - NSArray *query = [item componentsSeparatedByString: @"="]; - NSString *name = [query objectAtIndex: 0]; - NSString *value = [query objectAtIndex: 1]; - NSURLQueryItem *qitem = [NSURLQueryItem queryItemWithName: name - value: value]; + NSURLQueryItem *qitem; + NSString *name; + NSString *value; + + if ([item length] == 0) + { + name = @""; + value = nil; + } + else + { + NSRange r = [item rangeOfString: @"="]; + + if (0 == r.length) + { + /* No '=' found in query item. */ + name = item; + value = nil; + } + else + { + name = [item substringToIndex: r.location]; + value = [item substringFromIndex: NSMaxRange(r)]; + } + } + if (encoded) + { + name = [name stringByRemovingPercentEncoding]; + value = [value stringByRemovingPercentEncoding]; + } + qitem = [NSURLQueryItem queryItemWithName: name value: value]; [result addObject: qitem]; } [self setQueryItems: result]; } - else - { - [self setQueryItems: nil]; - } +} + +- (void) setQuery: (NSString *)query +{ + [self _setQuery: query fromPercentEncodedString: NO]; } - (NSArray *) queryItems { - return internal->_queryItems; + return AUTORELEASE(RETAIN(internal->_queryItems)); } - (void) setQueryItems: (NSArray *)queryItems @@ -2741,56 +2774,97 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSString *) percentEncodedQuery { - NSString *query = @""; - NSEnumerator *en = [[self percentEncodedQueryItems] objectEnumerator]; - NSURLQueryItem *item = nil; + NSString *result = nil; - while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + if (internal->_queryItems != nil) { - NSString *name = [item name]; - NSString *value = [item value]; - NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; - if ([query length] > 0) - { - query = [query stringByAppendingString: @"&"]; - } - query = [query stringByAppendingString: itemString]; + NSMutableString *query = nil; + NSURLQueryItem *item = nil; + NSEnumerator *en; + + en = [[self percentEncodedQueryItems] objectEnumerator]; + while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + { + NSString *name = [item name]; + NSString *value = [item value]; + + if (nil == query) + { + query = [[NSMutableString alloc] initWithCapacity: 1000]; + } + else + { + [query appendString: @"&"]; + } + [query appendString: name]; + if (value != nil) + { + [query appendString: @"="]; + [query appendString: value]; + } + } + result = AUTORELEASE([query copy]); + RELEASE(query); } - return query; + return result; } - (void) setPercentEncodedQuery: (NSString *)query { - [self setQuery: [query stringByRemovingPercentEncoding]]; + [self _setQuery: query fromPercentEncodedString: YES]; } - (NSArray *) percentEncodedQueryItems { - NSMutableArray *items = [NSMutableArray arrayWithCapacity: [internal->_queryItems count]]; - NSEnumerator *en = [internal->_queryItems objectEnumerator]; - NSURLQueryItem *i = nil; + NSArray *result = nil; - while((i = [en nextObject]) != nil) + if (internal->_queryItems != nil) { - NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [[i name] _stringByAddingPercentEscapesForQuery] - value: [[i value] _stringByAddingPercentEscapesForQuery]]; - [items addObject: ni]; - } + NSMutableArray *items; + NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSURLQueryItem *i = nil; - return items; + items = [[NSMutableArray alloc] + initWithCapacity: [internal->_queryItems count]]; + while ((i = [en nextObject]) != nil) + { + NSURLQueryItem *ni; + NSString *name = [i name]; + NSString *value = [i value]; + + name = [name _stringByAddingPercentEscapesForQuery]; + value = [value _stringByAddingPercentEscapesForQuery]; + ni = [NSURLQueryItem queryItemWithName: name + value: name]; + [items addObject: ni]; + } + result = AUTORELEASE([items copy]); + RELEASE(items); + } + return result; } - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { - NSMutableArray *items = [NSMutableArray arrayWithCapacity: [queryItems count]]; - NSEnumerator *en = [queryItems objectEnumerator]; - NSURLQueryItem *i = nil; + NSMutableArray *items = nil; - while((i = [en nextObject]) != nil) + if (queryItems != nil) { - NSURLQueryItem *ni = [NSURLQueryItem queryItemWithName: [[i name] stringByRemovingPercentEncoding] - value: [[i value] stringByRemovingPercentEncoding]]; - [items addObject: ni]; + NSEnumerator *en = [queryItems objectEnumerator]; + NSURLQueryItem *i = nil; + + items = [NSMutableArray arrayWithCapacity: [queryItems count]]; + while ((i = [en nextObject]) != nil) + { + NSString *name; + NSString *value; + NSURLQueryItem *ni; + + name = [[i name] stringByRemovingPercentEncoding]; + value = [[i value] stringByRemovingPercentEncoding]; + ni = [NSURLQueryItem queryItemWithName: name value: value]; + [items addObject: ni]; + } } [self setQueryItems: items]; From 213344d8626baffe26cc259923b90f1df9dd6dec Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 4 Apr 2020 12:15:17 -0400 Subject: [PATCH 36/39] Add tests and modifications to pass them --- Source/NSURL.m | 17 +++++++++++++++-- Tests/base/NSURL/components.m | 8 +++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index f1ca2d38e..e212ba2f1 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2408,6 +2408,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Regenerate URL when components are changed... - (void) _regenerateURL { + NSURL *u; NSMutableString *urlString; NSString *component; NSUInteger location; @@ -2516,8 +2517,20 @@ GS_PRIVATE_INTERNAL(NSURLComponents) internal->_rangeOfFragment = NSMakeRange(location, len); location += len; } + + u = [[NSURL alloc] initWithScheme: [self scheme] + user: [self user] + password: [self password] + host: [self host] + port: [self port] + fullPath: [self path] + parameterString: nil + query: [self percentEncodedQuery] + fragment: [self fragment]]; + ASSIGNCOPY(internal->_url, u); + RELEASE(u); - ASSIGNCOPY(internal->_url, [NSURL URLWithString: urlString]); + // ASSIGNCOPY(internal->_url, [NSURL URLWithString: urlString]); internal->_dirty = NO; RELEASE(urlString); } @@ -2623,7 +2636,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) while ((item = (NSURLQueryItem *)[en nextObject]) != nil) { NSString *name = [item name]; - NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; + NSString *value = [item value]; NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; if ([query length] > 0) diff --git a/Tests/base/NSURL/components.m b/Tests/base/NSURL/components.m index 82072ce80..e10cdbc5b 100644 --- a/Tests/base/NSURL/components.m +++ b/Tests/base/NSURL/components.m @@ -9,10 +9,6 @@ int main() NSURLComponents *components = [NSURLComponents componentsWithURL:[NSURL URLWithString:@"https://user:password@some.host.com"] resolvingAgainstBaseURL:NO]; - PASS([[[components URL] absoluteString] isEqualToString: @"https://user:password@some.host.com"], - "Absolute URL string is correct"); - - [components setQueryItems: [NSArray arrayWithObjects: [NSURLQueryItem queryItemWithName:@"lang" value:@"en"], [NSURLQueryItem queryItemWithName:@"response_type" value:@"code"], @@ -20,8 +16,10 @@ int main() nil]]; // URL PASS([[components string] isEqualToString: - @"https://user:password@some.host.com?lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], + @"https://user:password@some.host.com/?lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], "URL string is correct"); + // NOTE: The slash behind the .com is strictly legal, but this is NOT what is produced by macOS. I would like to correct this in a + // future release. // encoded... PASS([[components percentEncodedQuery] isEqualToString: From ac45beb4c1cc307f288e36388083e6cb586eabfc Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Sat, 4 Apr 2020 17:32:27 +0100 Subject: [PATCH 37/39] fix error in refactoring query (storing name twice rather than name/value) --- Source/NSURL.m | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index 45c965fca..d5ccc8427 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -2629,23 +2629,39 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSString *) query { - NSString *query = @""; - NSEnumerator *en = [internal->_queryItems objectEnumerator]; - NSURLQueryItem *item = nil; + NSString *result = nil; - while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + if (internal->_queryItems != nil) { - NSString *name = [item name]; - NSString *value = [item value]; - NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; + NSMutableString *query = nil; + NSURLQueryItem *item = nil; + NSEnumerator *en; - if ([query length] > 0) - { - query = [query stringByAppendingString: @"&"]; - } - query = [query stringByAppendingString: itemString]; + en = [internal->_queryItems objectEnumerator]; + while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + { + NSString *name = [item name]; + NSString *value = [item value]; + + if (nil == query) + { + query = [[NSMutableString alloc] initWithCapacity: 1000]; + } + else + { + [query appendString: @"&"]; + } + [query appendString: name]; + if (value != nil) + { + [query appendString: @"="]; + [query appendString: value]; + } + } + result = AUTORELEASE([query copy]); + RELEASE(query); } - return query; + return result; } - (void) _setQuery: (NSString *)query fromPercentEncodedString: (BOOL)encoded @@ -2848,7 +2864,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) name = [name _stringByAddingPercentEscapesForQuery]; value = [value _stringByAddingPercentEscapesForQuery]; ni = [NSURLQueryItem queryItemWithName: name - value: name]; + value: value]; [items addObject: ni]; } result = AUTORELEASE([items copy]); From d691df9cbfd121f5020c0c223ea23ce31659b34d Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 4 Apr 2020 12:34:15 -0400 Subject: [PATCH 38/39] Fix error in test compilation --- Tests/base/NSURL/components.m | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Tests/base/NSURL/components.m b/Tests/base/NSURL/components.m index e10cdbc5b..3d683f4da 100644 --- a/Tests/base/NSURL/components.m +++ b/Tests/base/NSURL/components.m @@ -5,18 +5,19 @@ int main() { + NSURLComponents *components = nil; + START_SET("components"); - NSURLComponents *components = [NSURLComponents componentsWithURL:[NSURL URLWithString:@"https://user:password@some.host.com"] resolvingAgainstBaseURL:NO]; + components = [NSURLComponents componentsWithURL:[NSURL URLWithString:@"https://user:password@some.host.com"] resolvingAgainstBaseURL:NO]; [components setQueryItems: [NSArray arrayWithObjects: - [NSURLQueryItem queryItemWithName:@"lang" value:@"en"], - [NSURLQueryItem queryItemWithName:@"response_type" value:@"code"], - [NSURLQueryItem queryItemWithName:@"uri" value:[NSURL URLWithString:@"https://some.url.com/path?param1=one¶m2=two"].absoluteString], - nil]]; + [NSURLQueryItem queryItemWithName:@"lang" value:@"en"], + [NSURLQueryItem queryItemWithName:@"response_type" value:@"code"], + [NSURLQueryItem queryItemWithName:@"uri" value:[[NSURL URLWithString:@"https://some.url.com/path?param1=one¶m2=two"] absoluteString]], nil]]; // URL PASS([[components string] isEqualToString: - @"https://user:password@some.host.com/?lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], + @"https://user:password@some.host.com/?lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], "URL string is correct"); // NOTE: The slash behind the .com is strictly legal, but this is NOT what is produced by macOS. I would like to correct this in a // future release. From b0c763de36cf75861933e604daf0d0790e74538b Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Sat, 4 Apr 2020 20:33:55 +0200 Subject: [PATCH 39/39] Build the string instead of the URL. Build the URL on the fly. --- Source/NSURL.m | 35 +++++++++++++++-------------------- Tests/base/NSURL/components.m | 4 +--- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/Source/NSURL.m b/Source/NSURL.m index d5ccc8427..ddf4c4ba1 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -45,7 +45,7 @@ function may be incorrect NSString *_value; #define GS_NSURLComponents_IVARS \ - NSURL *_url; \ + NSString *_string; \ NSString *_fragment; \ NSString *_host; \ NSString *_password; \ @@ -2386,7 +2386,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) dealloc { - RELEASE(internal->_url); + RELEASE(internal->_string); RELEASE(internal->_fragment); RELEASE(internal->_host); RELEASE(internal->_password); @@ -2408,7 +2408,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) // Regenerate URL when components are changed... - (void) _regenerateURL { - NSURL *u; NSMutableString *urlString; NSString *component; NSUInteger location; @@ -2518,27 +2517,16 @@ GS_PRIVATE_INTERNAL(NSURLComponents) location += len; } - u = [[NSURL alloc] initWithScheme: [self scheme] - user: [self user] - password: [self password] - host: [self host] - port: [self port] - fullPath: [self path] - parameterString: nil - query: [self percentEncodedQuery] - fragment: [self fragment]]; - ASSIGNCOPY(internal->_url, u); - RELEASE(u); - - // ASSIGNCOPY(internal->_url, [NSURL URLWithString: urlString]); - internal->_dirty = NO; + ASSIGNCOPY(internal->_string, urlString); RELEASE(urlString); + internal->_dirty = NO; } // Getting the URL - (NSString *) string { - return [[self URL] absoluteString]; + [self _regenerateURL]; + return internal->_string; } - (void) setString: (NSString *)urlString @@ -2549,8 +2537,15 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (NSURL *) URL { - [self _regenerateURL]; - return internal->_url; + return AUTORELEASE([[NSURL alloc] initWithScheme: [self scheme] + user: [self user] + password: [self password] + host: [self host] + port: [self port] + fullPath: [self path] + parameterString: nil + query: [self percentEncodedQuery] + fragment: [self fragment]]); } - (void) setURL: (NSURL *)url diff --git a/Tests/base/NSURL/components.m b/Tests/base/NSURL/components.m index 3d683f4da..69a7dbadd 100644 --- a/Tests/base/NSURL/components.m +++ b/Tests/base/NSURL/components.m @@ -17,10 +17,8 @@ int main() [NSURLQueryItem queryItemWithName:@"uri" value:[[NSURL URLWithString:@"https://some.url.com/path?param1=one¶m2=two"] absoluteString]], nil]]; // URL PASS([[components string] isEqualToString: - @"https://user:password@some.host.com/?lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], + @"https://user:password@some.host.com?lang=en&response_type=code&uri=https://some.url.com/path?param1%3Done%26param2%3Dtwo"], "URL string is correct"); - // NOTE: The slash behind the .com is strictly legal, but this is NOT what is produced by macOS. I would like to correct this in a - // future release. // encoded... PASS([[components percentEncodedQuery] isEqualToString: