Skip to content

Commit eaeac57

Browse files
SolaWing王孝华
authored andcommitted
fix: only escaping invalid data, keep valid escaping untouched
1 parent eea4bb1 commit eaeac57

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ All notable changes to this project will be documented in this file. Changes not
3232
- Fix misspell `serialise`. ([#473](https://github.com/httpswift/swifter/pull/473)) by [@mtgto](https://github.com/mtgto)
3333
- Fix an issue causing Danger was not working properly. ([#486](https://github.com/httpswift/swifter/pull/486)) by [@Vkt0r](https://github.com/Vkt0r)
3434
- Set Swift version to 5.0 in podspec. ([#475](https://github.com/httpswift/swifter/pull/475)) by [@p-krasnobrovkin-tcs](https://github.com/p-krasnobrovkin-tcs)
35+
- only escaping invalid data, keep valid escaping untouched ([#484](https://github.com/httpswift/swifter/pull/484)) by [@SolaWing](https://github.com/SolaWing)
36+
3537

3638
## Changed
3739

Xcode/Sources/HttpParser.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class HttpParser {
2424
}
2525
let request = HttpRequest()
2626
request.method = statusLineTokens[0]
27-
let encodedPath = statusLineTokens[1].addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? statusLineTokens[1]
27+
let encodedPath = Self.escapingInvalidURL(statusLineTokens[1])
2828
let urlComponents = URLComponents(string: encodedPath)
2929
request.path = urlComponents?.path ?? ""
3030
request.queryParams = urlComponents?.queryItems?.map { ($0.name, $0.value ?? "") } ?? []
@@ -38,7 +38,17 @@ public class HttpParser {
3838
request.body = try readBody(socket, size: contentLengthValue)
3939
}
4040
return request
41+
}
42+
43+
/// only escaping invalid chars,valid encodedPath keep untouched
44+
static func escapingInvalidURL(_ url: String) -> String {
45+
var urlAllowed: CharacterSet {
46+
var v = CharacterSet.urlQueryAllowed
47+
v.insert(charactersIn: "?#%")
48+
return v
4149
}
50+
return url.addingPercentEncoding(withAllowedCharacters: urlAllowed) ?? url
51+
}
4252

4353
private func readBody(_ socket: Socket, size: Int) throws -> [UInt8] {
4454
return try socket.read(length: size)

Xcode/Tests/SwifterTestsHttpParser.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class SwifterTestsHttpParser: XCTestCase {
175175
XCTAssertEqual(resp?.headers["header2"], "2", "Parser should extract multiple headers from the request.")
176176

177177
resp = try? parser.readHttpRequest(TestSocket("GET /some/path?subscript_query[]=1&subscript_query[]=2 HTTP/1.0\nContent-Length: 10\n\n1234567890"))
178-
let queryPairs = resp?.queryParams ?? []
178+
var queryPairs = resp?.queryParams ?? []
179179
XCTAssertEqual(queryPairs.count, 2)
180180
XCTAssertEqual(queryPairs.first?.0, "subscript_query[]")
181181
XCTAssertEqual(queryPairs.first?.1, "1")
@@ -185,5 +185,19 @@ class SwifterTestsHttpParser: XCTestCase {
185185
XCTAssertEqual(resp?.path, "/some/path", "Parser should extract HTTP path value from the status line.")
186186
XCTAssertEqual(resp?.headers["content-length"], "10", "Parser should extract Content-Length header value.")
187187

188+
resp = try? parser.readHttpRequest(TestSocket("GET /path[]/param?a[]=1&a[]=2&b=%20 HTTP/1.0\r\nContent-Length: 0\r\n\r\n"))
189+
queryPairs = resp?.queryParams ?? []
190+
191+
XCTAssertEqual(resp?.path, "/path[]/param")
192+
if queryPairs.count == 3 {
193+
XCTAssertEqual(queryPairs[0].0, "a[]")
194+
XCTAssertEqual(queryPairs[0].1, "1")
195+
XCTAssertEqual(queryPairs[1].0, "a[]")
196+
XCTAssertEqual(queryPairs[1].1, "2")
197+
XCTAssertEqual(queryPairs[2].0, "b")
198+
XCTAssertEqual(queryPairs[2].1, " ")
199+
} else {
200+
XCTFail("queryPairs count should be 3")
201+
}
188202
}
189203
}

0 commit comments

Comments
 (0)