From 9841bd81852d59608fe3566b17831d6d42eb7dcf Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Fri, 8 Sep 2023 14:12:37 -0700 Subject: [PATCH] decode urls before reencoding with NSURL (#39344) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39344 ## Changelog: [iOS][General] - URLs parsed by RCTConvert should be encoded respecting RFC 3986, 1738/1808 in ios 17, NSURLs are encoded respecting RFC 3986 (https://www.ietf.org/rfc/rfc3986.txt) as opposed to RFC 1738/1808 before. following this, `NSURL`'s parsing algorithm has changed such that if they encounter a reserved character, such as `[`, the parser will percent encode all possible characters in the url, including `%`. this causes trouble for urls that already have some encoding. for the string `%22[]`, the new parsing algorithm will return the following: RFC 1738/1808 -> `%22%5B%5D` RFC 3986 -> `%2522%5B%5D` (invalid encoding) the solution here is to decode all the percentified encodings in the input string, completely stripping it of the percent encodings, and then re-encoding it. thus, the string will transform as follows: `%22[]` -> `"[]` -> `%22%5B%5D` we probably don't need the OS check, but including it just to be safe. Reviewed By: yungsters Differential Revision: D49082077 fbshipit-source-id: 21ac1e37c957db3217746f9385f9d7947261794d --- packages/react-native/React/Base/RCTConvert.m | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/react-native/React/Base/RCTConvert.m b/packages/react-native/React/Base/RCTConvert.m index 600ff3fff47335..04247093fd9bc1 100644 --- a/packages/react-native/React/Base/RCTConvert.m +++ b/packages/react-native/React/Base/RCTConvert.m @@ -84,8 +84,16 @@ + (NSURL *)NSURL:(id)json } @try { // NSURL has a history of crashing with bad input, so let's be safe + NSURL *URL = nil; - NSURL *URL = [NSURL URLWithString:path]; +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 170000 + if (@available(iOS 17.0, *)) { + NSString *decodedPercentPath = [path stringByRemovingPercentEncoding]; + URL = [NSURL URLWithString:decodedPercentPath encodingInvalidCharacters:YES]; + } +#endif + + URL = URL ?: [NSURL URLWithString:path]; if (URL.scheme) { // Was a well-formed absolute URL return URL; }