diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 403900f9f..e1073b587 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,15 +4,11 @@ on: push: branches: - main + - 1.x.x paths: - '**.swift' - '**.yml' pull_request: - branches: - - main - paths: - - '**.swift' - - '**.yml' workflow_dispatch: jobs: @@ -39,9 +35,9 @@ jobs: strategy: matrix: image: - - 'swift:5.7' - 'swift:5.8' - 'swift:5.9' + - 'swift:5.10' container: image: ${{ matrix.image }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index e8dfe32fb..d2a4e7f74 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -2,8 +2,6 @@ name: Validity Check on: pull_request: - branches: - - main jobs: validate: diff --git a/Sources/Hummingbird/Utils/HBParser.swift b/Sources/Hummingbird/Utils/HBParser.swift index ca7e98338..4a9496c73 100644 --- a/Sources/Hummingbird/Utils/HBParser.swift +++ b/Sources/Hummingbird/Utils/HBParser.swift @@ -596,8 +596,7 @@ extension HBParser { func _percentDecode(_ original: ArraySlice, _ bytes: UnsafeMutableBufferPointer) throws -> Int { var newIndex = 0 var index = original.startIndex - - while index < original.endIndex { + while index < (original.endIndex - 2) { // if we have found a percent sign if original[index] == 0x25 { let high = Self.asciiHexValues[Int(original[index + 1])] @@ -614,9 +613,13 @@ extension HBParser { index += 1 } } + while index < original.endIndex { + bytes[newIndex] = original[index] + newIndex += 1 + index += 1 + } return newIndex } - guard self.index != self.range.endIndex else { return "" } do { if #available(macOS 11, macCatalyst 14.0, iOS 14.0, tvOS 14.0, *) { diff --git a/Tests/HummingbirdTests/RouterTests.swift b/Tests/HummingbirdTests/RouterTests.swift index 0cecf0706..d63004039 100644 --- a/Tests/HummingbirdTests/RouterTests.swift +++ b/Tests/HummingbirdTests/RouterTests.swift @@ -393,6 +393,30 @@ final class RouterTests: XCTestCase { XCTAssertEqual(response.status, .seeOther) } } + + /// Test the hummingbird core parser against possible overflows of the percent encoder. this issue was introduced in pr #404 in the context of query parameters but I've thrown in some other random overflow scenarios in here too for good measure. if it doesn't crash, its a win. + func testQueryParameterOverflow() throws { + let app = HBApplication(testing: .embedded) + app.router.get("overflow") { req in + let currentQP = req.uri.queryParameters["query"] + return String("\(currentQP ?? "")") + } + try app.XCTStart() + defer { app.XCTStop() } + + try app.XCTExecute(uri: "/overflow?query=value%", method: .GET) { response in + let body = try XCTUnwrap(response.body) + XCTAssertEqual(String(buffer: body), "value%") + } + try app.XCTExecute(uri: "/overflow?query%=value%", method: .GET) { response in + let body = try XCTUnwrap(response.body) + XCTAssertEqual(String(buffer: body), "") + } + try app.XCTExecute(uri: "/overflow?%&", method: .GET) { response in + let body = try XCTUnwrap(response.body) + XCTAssertEqual(String(buffer: body), "") + } + } } extension HBRequest {