Skip to content

Commit 94820ea

Browse files
authored
1.x.x - HBParser harden (#411)
1 parent b67a8db commit 94820ea

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

.github/workflows/ci.yml

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@ on:
44
push:
55
branches:
66
- main
7+
- 1.x.x
78
paths:
89
- '**.swift'
910
- '**.yml'
1011
pull_request:
11-
branches:
12-
- main
13-
paths:
14-
- '**.swift'
15-
- '**.yml'
1612
workflow_dispatch:
1713

1814
jobs:
@@ -39,9 +35,9 @@ jobs:
3935
strategy:
4036
matrix:
4137
image:
42-
- 'swift:5.7'
4338
- 'swift:5.8'
4439
- 'swift:5.9'
40+
- 'swift:5.10'
4541

4642
container:
4743
image: ${{ matrix.image }}

.github/workflows/validate.yml

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ name: Validity Check
22

33
on:
44
pull_request:
5-
branches:
6-
- main
75

86
jobs:
97
validate:

Sources/Hummingbird/Utils/HBParser.swift

+6-3
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,7 @@ extension HBParser {
596596
func _percentDecode(_ original: ArraySlice<UInt8>, _ bytes: UnsafeMutableBufferPointer<UInt8>) throws -> Int {
597597
var newIndex = 0
598598
var index = original.startIndex
599-
600-
while index < original.endIndex {
599+
while index < (original.endIndex - 2) {
601600
// if we have found a percent sign
602601
if original[index] == 0x25 {
603602
let high = Self.asciiHexValues[Int(original[index + 1])]
@@ -614,9 +613,13 @@ extension HBParser {
614613
index += 1
615614
}
616615
}
616+
while index < original.endIndex {
617+
bytes[newIndex] = original[index]
618+
newIndex += 1
619+
index += 1
620+
}
617621
return newIndex
618622
}
619-
620623
guard self.index != self.range.endIndex else { return "" }
621624
do {
622625
if #available(macOS 11, macCatalyst 14.0, iOS 14.0, tvOS 14.0, *) {

Tests/HummingbirdTests/RouterTests.swift

+24
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,30 @@ final class RouterTests: XCTestCase {
393393
XCTAssertEqual(response.status, .seeOther)
394394
}
395395
}
396+
397+
/// 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.
398+
func testQueryParameterOverflow() throws {
399+
let app = HBApplication(testing: .embedded)
400+
app.router.get("overflow") { req in
401+
let currentQP = req.uri.queryParameters["query"]
402+
return String("\(currentQP ?? "")")
403+
}
404+
try app.XCTStart()
405+
defer { app.XCTStop() }
406+
407+
try app.XCTExecute(uri: "/overflow?query=value%", method: .GET) { response in
408+
let body = try XCTUnwrap(response.body)
409+
XCTAssertEqual(String(buffer: body), "value%")
410+
}
411+
try app.XCTExecute(uri: "/overflow?query%=value%", method: .GET) { response in
412+
let body = try XCTUnwrap(response.body)
413+
XCTAssertEqual(String(buffer: body), "")
414+
}
415+
try app.XCTExecute(uri: "/overflow?%&", method: .GET) { response in
416+
let body = try XCTUnwrap(response.body)
417+
XCTAssertEqual(String(buffer: body), "")
418+
}
419+
}
396420
}
397421

398422
extension HBRequest {

0 commit comments

Comments
 (0)