diff --git a/Sources/OpenAPIRuntime/Conversion/Converter+Server.swift b/Sources/OpenAPIRuntime/Conversion/Converter+Server.swift index 7d36cb2f..e4ed747f 100644 --- a/Sources/OpenAPIRuntime/Conversion/Converter+Server.swift +++ b/Sources/OpenAPIRuntime/Conversion/Converter+Server.swift @@ -56,10 +56,13 @@ extension Converter { guard let acceptHeader = headerFields[.accept] else { return } // Split with commas to get the individual values - let acceptValues = acceptHeader.split(separator: ",") - .map { value in - // Drop everything after the optional semicolon (q, extensions, ...) - value.split(separator: ";")[0].trimmingLeadingAndTrailingSpaces.lowercased() + let acceptValues = try acceptHeader.split(separator: ",") + .map { value -> String in + // Drop everything after the optional semicolon (q, extensions, ...), reject malformed. + guard let mediaRange = value.split(separator: ";").first else { + throw RuntimeError.malformedAcceptHeader(String(value)) + } + return mediaRange.trimmingLeadingAndTrailingSpaces.lowercased() } if acceptValues.isEmpty { return } guard let parsedSubstring = OpenAPIMIMEType(substring) else { diff --git a/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift b/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift index 3d956bb2..bf1b948a 100644 --- a/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift +++ b/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift @@ -40,6 +40,11 @@ final class Test_ServerConverterExtensions: Test_Runtime { ] let multiple: HTTPFields = [.accept: "text/plain, application/json"] let params: HTTPFields = [.accept: "application/json; foo=bar"] + let semicolon: HTTPFields = [.accept: ";"] + let semicolons: HTTPFields = [.accept: ";;;;"] + let spacedSemicolon: HTTPFields = [.accept: " ; "] + let leadingSemicolon: HTTPFields = [.accept: "application/json,;"] + let garbage: HTTPFields = [.accept: "txet"] let cases: [(HTTPFields, String, Bool)] = [ // No Accept header, any string validates successfully (emptyHeaders, "foobar", true), @@ -64,6 +69,12 @@ final class Test_ServerConverterExtensions: Test_Runtime { // Params (params, "application/json; foo=bar", true), (params, "application/json; charset=utf-8; foo=bar", true), (params, "application/json", true), (params, "text/plain", false), + // Rejects malformed headers + (semicolon, "application/json", false), (semicolons, "application/json", false), + (spacedSemicolon, "application/json", false), (leadingSemicolon, "application/json", false), + (garbage, "application/json", false), + // Rejects malformed expected content type + (wildcard, "txet", false), ] for (headers, contentType, success) in cases { if success {