Skip to content

Commit 35899ab

Browse files
authored
Merge pull request #1658 from ahoppen/revert-uri-hack
Revert "Add an extra percent encoding layer when encoding DocumentURIs to LSP requests"
2 parents cf47f2c + 5d1eb73 commit 35899ab

File tree

3 files changed

+5
-72
lines changed

3 files changed

+5
-72
lines changed

Sources/LanguageServerProtocol/SupportTypes/DocumentURI.swift

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,7 @@ public struct DocumentURI: Codable, Hashable, Sendable {
8484
}
8585

8686
public init(from decoder: Decoder) throws {
87-
let string = try decoder.singleValueContainer().decode(String.self)
88-
guard let url = URL(string: string) else {
89-
throw FailedToConstructDocumentURIFromStringError(string: string)
90-
}
91-
if url.query() != nil, var urlComponents = URLComponents(string: url.absoluteString) {
92-
// See comment in `encode(to:)`
93-
urlComponents.percentEncodedQuery = urlComponents.percentEncodedQuery!.removingPercentEncoding
94-
if let rewrittenQuery = urlComponents.url {
95-
self.init(rewrittenQuery)
96-
return
97-
}
98-
}
99-
self.init(url)
87+
try self.init(string: decoder.singleValueContainer().decode(String.self))
10088
}
10189

10290
/// Equality check to handle escape sequences in file URLs.
@@ -109,36 +97,7 @@ public struct DocumentURI: Codable, Hashable, Sendable {
10997
hasher.combine(self.pseudoPath)
11098
}
11199

112-
private static let additionalQueryEncodingCharacterSet = CharacterSet(charactersIn: "?=&%").inverted
113-
114100
public func encode(to encoder: Encoder) throws {
115-
let urlToEncode: URL
116-
if let query = storage.query(percentEncoded: true), var components = URLComponents(string: storage.absoluteString) {
117-
// The URI standard RFC 3986 is ambiguous about whether percent encoding and their represented characters are
118-
// considered equivalent. VS Code considers them equivalent and treats them the same:
119-
//
120-
// vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString() -> 'x://a?b%3Dxxxx%3Dyyyy'
121-
// vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString(/*skipEncoding=*/true) -> 'x://a?b=xxxx=yyyy'
122-
//
123-
// This causes issues because SourceKit-LSP's macro expansion URLs encoded by URLComponents use `=` to denote the
124-
// separation of a key and a value in the outer query. The value of the `parent` key may itself contain query
125-
// items, which use the escaped form '%3D'. Simplified, such a URL may look like
126-
// scheme://host?parent=scheme://host?line%3D2
127-
// But after running this through VS Code's URI type `=` and `%3D` get canonicalized and are indistinguishable.
128-
// To avoid this ambiguity, always percent escape the characters we use to distinguish URL query parameters,
129-
// producing the following URL.
130-
// scheme://host?parent%3Dscheme://host%3Fline%253D2
131-
components.percentEncodedQuery =
132-
query
133-
.addingPercentEncoding(withAllowedCharacters: Self.additionalQueryEncodingCharacterSet)
134-
if let componentsUrl = components.url {
135-
urlToEncode = componentsUrl
136-
} else {
137-
urlToEncode = self.storage
138-
}
139-
} else {
140-
urlToEncode = self.storage
141-
}
142-
try urlToEncode.absoluteString.encode(to: encoder)
101+
try storage.absoluteString.encode(to: encoder)
143102
}
144103
}

Sources/SKTestSupport/CheckCoding.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,9 @@ package func checkCoding<T: Codable & Equatable>(
4343
XCTAssertEqual(json, str, file: file, line: line)
4444

4545
let decoder = JSONDecoder()
46-
XCTAssertNoThrow(
47-
try {
48-
let decodedValue = try decoder.decode(WrapFragment<T>.self, from: data).value
49-
XCTAssertEqual(value, decodedValue, file: file, line: line)
50-
}()
51-
)
46+
let decodedValue = try! decoder.decode(WrapFragment<T>.self, from: data).value
47+
48+
XCTAssertEqual(value, decodedValue, file: file, line: line)
5249
}
5350

5451
/// JSONEncoder requires the top-level value to be encoded as a JSON container (array or object). Give it one.

Tests/LanguageServerProtocolTests/CodingTests.swift

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,29 +1343,6 @@ final class CodingTests: XCTestCase {
13431343
"""
13441344
)
13451345
}
1346-
1347-
func testDocumentUriQueryParameterCoding() throws {
1348-
checkCoding(
1349-
try DocumentURI(string: "scheme://host?parent=scheme://host?line%3D2"),
1350-
json: #"""
1351-
"scheme:\/\/host?parent%3Dscheme:\/\/host%3Fline%253D2"
1352-
"""#
1353-
)
1354-
1355-
checkCoding(
1356-
try DocumentURI(string: "scheme://host?parent=scheme://host?parent%3Dscheme://host%3Fkey%253Dvalue"),
1357-
json: #"""
1358-
"scheme:\/\/host?parent%3Dscheme:\/\/host%3Fparent%253Dscheme:\/\/host%253Fkey%25253Dvalue"
1359-
"""#
1360-
)
1361-
1362-
checkCoding(
1363-
try DocumentURI(string: "scheme://host?parent=with%23hash"),
1364-
json: #"""
1365-
"scheme:\/\/host?parent%3Dwith%2523hash"
1366-
"""#
1367-
)
1368-
}
13691346
}
13701347

13711348
func with<T>(_ value: T, mutate: (inout T) -> Void) -> T {

0 commit comments

Comments
 (0)