Skip to content

Commit

Permalink
Add test for header field name characters
Browse files Browse the repository at this point in the history
  • Loading branch information
siemensikkema committed Apr 4, 2021
1 parent 56e811d commit 55c26ba
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
30 changes: 16 additions & 14 deletions Sources/MultipartKit/MultipartParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public final class MultipartParser {
return .headerValue(name: name)
case .cr where name.isEmpty:
return .postHeaders
case _ where byte.isValidHeaderCharacter:
case _ where byte.isAllowedHeaderFieldNameCharacter:
name.append(byte)
default:
throw Error.syntax
Expand Down Expand Up @@ -272,18 +272,20 @@ private extension UInt8 {
static let tab: UInt8 = 32

/*
* field-name = token
* token = 1*<any CHAR except CTLs or tspecials>
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
* tspecials = "(" | ")" | "<" | ">" | "@"
* | "," | ";" | ":" | "\" | DQUOTE
* | "/" | "[" | "]" | "?" | "="
* | "{" | "}" | SP | HT
* DQUOTE = <US-ASCII double-quote mark (34)>
* SP = <US-ASCII SP, space (32)>
* HT = <US-ASCII HT, horizontal-tab (9)>
See https://tools.ietf.org/html/rfc1341#page-6 and https://tools.ietf.org/html/rfc822#section-3.2

field-name = token
token = 1*<any CHAR except CTLs or tspecials>
CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
tspecials = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "\" | DQUOTE
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
DQUOTE = <US-ASCII double-quote mark (34)>
SP = <US-ASCII SP, space (32)>
HT = <US-ASCII HT, horizontal-tab (9)>
*/
private static let validHeaderCharacters: [Bool] = [
private static let allowedHeaderFieldNameCharacterFlags: [Bool] = [
// 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel
false, false, false, false, false, false, false, false,
// 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si
Expand Down Expand Up @@ -318,7 +320,7 @@ private extension UInt8 {
true, true, true, false, true, false, true, false
]

var isValidHeaderCharacter: Bool {
Self.validHeaderCharacters[Int(self)]
var isAllowedHeaderFieldNameCharacter: Bool {
Self.allowedHeaderFieldNameCharacterFlags[Int(self)]
}
}
21 changes: 21 additions & 0 deletions Tests/MultipartKitTests/MultipartKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,27 @@ class MultipartTests: XCTestCase {
XCTAssertEqual(array, "relative")
}
}

func testAllowedHeaderFieldNameCharacters() {
let disallowedASCIICodes: [Int] = (0...127).compactMap {
let parser = MultipartParser(boundary: "-")
let body: String = """
---\r\n\
a\(Unicode.Scalar($0)!): b\r\n\
\r\n\
c\r\n\
---\r\n
"""
do {
try parser.execute(body)
return nil
} catch {
return $0
}
}
let expectedDisallowedASCIICodes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 40, 41, 44, 47, 59, 60, 61, 62, 63, 64, 91, 92, 93, 123, 125, 127]
XCTAssertEqual(disallowedASCIICodes, expectedDisallowedASCIICodes)
}
}

// https://stackoverflow.com/a/54524110/1041105
Expand Down

0 comments on commit 55c26ba

Please sign in to comment.