From 3858378d86c4adfb6a4d2f21f3ba2c4f7b5c4db2 Mon Sep 17 00:00:00 2001 From: William Denniss Date: Mon, 17 Sep 2018 13:37:57 -0700 Subject: [PATCH] Implement the application/x-www-form-urlencoded format for URL query components Previously only percent encoding was used, which misses space being encoded as '+'. We're still percent encoding space during encoding (as this appears to still be valid application/x-www-form-urlencoded encoded data, since percent encoding is permitted), but it will now correctly decode '+' as space. --- Source/OIDURLQueryComponent.h | 10 +++++++++- Source/OIDURLQueryComponent.m | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Source/OIDURLQueryComponent.h b/Source/OIDURLQueryComponent.h index 2a87d4f81..b01dfff14 100644 --- a/Source/OIDURLQueryComponent.h +++ b/Source/OIDURLQueryComponent.h @@ -28,7 +28,15 @@ NS_ASSUME_NONNULL_BEGIN */ extern BOOL gOIDURLQueryComponentForceIOS7Handling; -/*! @brief A utility class for creating and parsing URL query components. +/*! @brief A utility class for creating and parsing URL query components encoded with the + application/x-www-form-urlencoded format. + @description Supports application/x-www-form-urlencoded encoding and decoding, specifically + '+' is replaced with space before percent decoding. For encoding, simply percent encodes + space, as this is valid application/x-www-form-urlencoded. + @see https://tools.ietf.org/html/rfc6749#section-4.1.2 + @see https://tools.ietf.org/html/rfc6749#section-4.1.3 + @see https://tools.ietf.org/html/rfc6749#appendix-B + @see https://url.spec.whatwg.org/#urlencoded-parsing */ @interface OIDURLQueryComponent : NSObject { // private variables diff --git a/Source/OIDURLQueryComponent.m b/Source/OIDURLQueryComponent.m index 97fb1e295..2421be4ed 100644 --- a/Source/OIDURLQueryComponent.m +++ b/Source/OIDURLQueryComponent.m @@ -44,6 +44,12 @@ - (nullable instancetype)initWithURL:(NSURL *)URL { if (!gOIDURLQueryComponentForceIOS7Handling) { NSURLComponents *components = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO]; + // As OAuth uses application/x-www-form-urlencoded encoding, interprets '+' as a space + // in addition to regular percent decoding. https://url.spec.whatwg.org/#urlencoded-parsing + components.percentEncodedQuery = + [components.percentEncodedQuery stringByReplacingOccurrencesOfString:@"+" + withString:@"%20"]; + // NB. @c queryItems are already percent decoded NSArray *queryItems = components.queryItems; for (NSURLQueryItem *queryItem in queryItems) { [self addParameter:queryItem.name value:queryItem.value]; @@ -54,6 +60,10 @@ - (nullable instancetype)initWithURL:(NSURL *)URL { // Fallback for iOS 7 NSString *query = URL.query; + // As OAuth uses application/x-www-form-urlencoded encoding, interprets '+' as a space + // in addition to regular percent decoding. https://url.spec.whatwg.org/#urlencoded-parsing + query = [query stringByReplacingOccurrencesOfString:@"+" withString:@"%20"]; + NSArray *queryParts = [query componentsSeparatedByString:@"&"]; for (NSString *queryPart in queryParts) { NSRange equalsRange = [queryPart rangeOfString:@"="];