From eefea86600b0e72a9d73a3f355810a314cc569b1 Mon Sep 17 00:00:00 2001 From: Vladimir Kukushkin Date: Wed, 17 Jun 2026 11:56:14 +0100 Subject: [PATCH 1/2] handle malformed accept headers gracefully --- .../Conversion/Converter+Server.swift | 11 +++++++---- .../Conversion/Test_Converter+Server.swift | 13 +++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) 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..2e5536e8 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,14 @@ 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 expected content type + (wildcard, "txet", false), + + // Rejects malformed headers + (semicolon, "application/json", false), (semicolons, "application/json", false), + (spacedSemicolon, "application/json", false), (leadingSemicolon, "application/json", false), + (garbage, "application/json", false), ] for (headers, contentType, success) in cases { if success { From b12e87e4930bede0656f34a9193c07641a0b19bd Mon Sep 17 00:00:00 2001 From: Vladimir Kukushkin Date: Wed, 17 Jun 2026 13:50:31 +0100 Subject: [PATCH 2/2] fixup! handle malformed accept headers gracefully --- .../Conversion/Test_Converter+Server.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift b/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift index 2e5536e8..bf1b948a 100644 --- a/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift +++ b/Tests/OpenAPIRuntimeTests/Conversion/Test_Converter+Server.swift @@ -69,14 +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 expected content type - (wildcard, "txet", 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 {