Skip to content

Commit

Permalink
Backport #23331 to SDK 49
Browse files Browse the repository at this point in the history
  • Loading branch information
tsapeta committed Jul 7, 2023
1 parent e7d88a5 commit c7f1b5d
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ extension URL: Convertible {
throw Conversions.ConvertingException<URL>(value)
}

// Try to construct the URL object from the string as it came in.
if let url = URL(string: value) {
// If it has no scheme, we assume it was the file path which needs to be recreated to be recognized as the file url.
return url.scheme != nil ? url : URL(fileURLWithPath: value)
// First we try to create a URL without extra encoding, as it came.
if let url = convertToUrl(string: value) {
return url
}

// File path doesn't need to be percent-encoded.
Expand All @@ -29,8 +28,8 @@ extension URL: Convertible {
}

// If we get here, the string is not the file url and may require percent-encoding characters that are not URL-safe according to RFC 3986.
if let encodedValue = percentEncodeUrlString(value), let url = URL(string: encodedValue) {
return url.scheme != nil ? url : URL(fileURLWithPath: value)
if let encodedValue = percentEncodeUrlString(value), let url = convertToUrl(string: encodedValue) {
return url
}

// If it still fails to create the URL object, the string possibly contains characters that must be explicitly percent-encoded beforehand.
Expand Down
10 changes: 10 additions & 0 deletions ios/versioned/sdk49/ExpoModulesCore/ios/Swift/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,13 @@ internal func isFileUrlPath(_ path: String) -> Bool {
}
return URL(string: encodedPath)?.scheme == nil
}

internal func convertToUrl(string value: String) -> URL? {
// URLComponents parses and constructs URLs according to RFC 3986.
// For some unusual urls URL(string:) will fail incorrectly
guard let url = URLComponents(string: value)?.url ?? URL(string: value) else {
return nil
}
// If it has no scheme, we assume it was the file path which needs to be recreated to be recognized as the file url.
return url.scheme != nil ? url : URL(fileURLWithPath: value)
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,6 @@ class ConvertiblesSpec: ExpoSpec {
}
}

it("throws when url contains percent alone") {
// The percent character alone must be percent-encoded to `%25` beforehand, otherwise it should throw an exception.
let urlString = "https://expo.dev/?param=%"

expect({ try URL.convert(from: urlString, appContext: appContext) }).to(throwError(errorType: UrlContainsInvalidCharactersException.self))
}

it("converts from url containing the anchor") {
// The hash is not allowed in the query (requires percent-encoding),
// but we want it to be recognized as the beginning of the fragment,
Expand Down

0 comments on commit c7f1b5d

Please sign in to comment.