Skip to content

Commit

Permalink
fix: manually percent encode query items to allow values with + sign (#…
Browse files Browse the repository at this point in the history
…402)

* fix: manually percent encode query items to allow values with + sign

* ci: fix ci not running when tests changes
  • Loading branch information
grdsdev committed May 23, 2024
1 parent 35ac278 commit a0ecb70
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 14 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/auth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ on:
pull_request:
paths:
- "Sources/Auth/**"
- "Tests/Auth/**"
- "Tests/AuthTests/**"
- ".github/workflows/auth.yml"
push:
branches:
- main
paths:
- "Sources/Auth/**"
- "Tests/Auth/**"
- "Tests/AuthTests/**"
- ".github/workflows/auth.yml"

concurrency:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/functions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ on:
pull_request:
paths:
- "Sources/Functions/**"
- "Tests/Functions/**"
- "Tests/FunctionsTests/**"
- ".github/workflows/functions.yml"
push:
branches:
- main
paths:
- "Sources/Functions/**"
- "Tests/Functions/**"
- "Tests/FunctionsTests/**"
- ".github/workflows/functions.yml"

concurrency:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/postgrest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ on:
pull_request:
paths:
- "Sources/PostgREST/**"
- "Tests/PostgREST/**"
- "Tests/PostgRESTTests/**"
- ".github/workflows/postgrest.yml"
push:
branches:
- main
paths:
- "Sources/PostgREST/**"
- "Tests/PostgREST/**"
- "Tests/PostgRESTTests/**"
- ".github/workflows/postgrest.yml"

concurrency:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/realtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ on:
pull_request:
paths:
- "Sources/Realtime/**"
- "Tests/Realtime/**"
- "Tests/RealtimeTests/**"
- ".github/workflows/realtime.yml"
push:
branches:
- main
paths:
- "Sources/Realtime/**"
- "Tests/Realtime/**"
- "Tests/RealtimeTests/**"
- ".github/workflows/realtime.yml"

concurrency:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/storage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ on:
pull_request:
paths:
- "Sources/Storage/**"
- "Tests/Storage/**"
- "Tests/StorageTests/**"
- ".github/workflows/storage.yml"
push:
branches:
- main
paths:
- "Sources/Storage/**"
- "Tests/Storage/**"
- "Tests/StorageTests/**"
- ".github/workflows/storage.yml"

concurrency:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/supabase.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ on:
pull_request:
paths:
- "Sources/Supabase/**"
- "Tests/Supabase/**"
- "Tests/SupabaseTests/**"
- ".github/workflows/supabase.yml"
push:
branches:
- main
paths:
- "Sources/Supabase/**"
- "Tests/Supabase/**"
- "Tests/SupabaseTests/**"
- ".github/workflows/supabase.yml"

concurrency:
Expand Down
34 changes: 32 additions & 2 deletions Sources/_Helpers/FoundationExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,14 @@ extension URL {
return
}

let currentQueryItems = components.queryItems ?? []
components.queryItems = currentQueryItems + queryItems
let currentQueryItems = components.percentEncodedQueryItems ?? []

components.percentEncodedQueryItems = currentQueryItems + queryItems.map {
URLQueryItem(
name: escape($0.name),
value: $0.value.map(escape)
)
}

if let newURL = components.url {
self = newURL
Expand All @@ -56,3 +62,27 @@ extension URL {
return url
}
}

func escape(_ string: String) -> String {
string.addingPercentEncoding(withAllowedCharacters: .sbURLQueryAllowed) ?? string
}

extension CharacterSet {
/// Creates a CharacterSet from RFC 3986 allowed characters.
///
/// RFC 3986 states that the following characters are "reserved" characters.
///
/// - General Delimiters: ":", "#", "[", "]", "@", "?", "/"
/// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
///
/// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
/// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
/// should be percent-escaped in the query string.
static let sbURLQueryAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
let encodableDelimiters = CharacterSet(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")

return CharacterSet.urlQueryAllowed.subtracting(encodableDelimiters)
}()
}
5 changes: 5 additions & 0 deletions Tests/PostgRESTTests/BuildURLRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ final class BuildURLRequestTests: XCTestCase {
.select()
.containedBy("userMetadata", value: ["age": 18])
},
TestCase(name: "filter starting with non-alphanumeric") { client in
client.from("users")
.select()
.eq("to", value: "+16505555555")
},
]

for testCase in testCases {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
curl \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Client-Info: postgrest-swift/x.y.z" \
"https://example.supabase.co/users?select=*&to=eq.+16505555555"

0 comments on commit a0ecb70

Please sign in to comment.