diff --git a/Sources/MCP/Extensions/Data+Extensions.swift b/Sources/MCP/Extensions/Data+Extensions.swift index 745b4a30..be35f91d 100644 --- a/Sources/MCP/Extensions/Data+Extensions.swift +++ b/Sources/MCP/Extensions/Data+Extensions.swift @@ -4,7 +4,7 @@ import RegexBuilder extension Data { /// Regex pattern for data URLs @inline(__always) private static var dataURLRegex: - Regex<(Substring, Substring, Substring?, Substring)> + Regex<(Substring, Substring, Substring?, Substring?, Substring)> { Regex { "data:" @@ -21,7 +21,9 @@ extension Data { } } } - Optionally { ";base64" } + Optionally { + Capture { ";base64" } + } "," Capture { ZeroOrMore { .any } @@ -49,9 +51,9 @@ extension Data { } // Extract components using strongly typed captures - let (_, mediatype, charset, encodedData) = match.output + let (_, mediatype, charset, base64Marker, encodedData) = match.output - let isBase64 = string.contains(";base64,") + let isBase64 = base64Marker != nil // Process MIME type var mimeType = mediatype.isEmpty ? "text/plain" : String(mediatype) diff --git a/Tests/MCPTests/Base64DataTests.swift b/Tests/MCPTests/Base64DataTests.swift index 96025935..a5e04347 100644 --- a/Tests/MCPTests/Base64DataTests.swift +++ b/Tests/MCPTests/Base64DataTests.swift @@ -105,6 +105,39 @@ struct Base64DataTests { } } + @Test("Parse plain-text data URL whose payload contains ;base64,") + func testParseDataURLBase64MarkerInPayload() { + let dataURL = "data:text/plain,hello;base64,world" + #expect(Data.isDataURL(string: dataURL)) + + let result = Data.parseDataURL(dataURL) + #expect(result != nil) + if let (mimeType, data) = result { + #expect(mimeType == "text/plain") + #expect(String(data: data, encoding: .utf8) == "hello;base64,world") + } + } + + @Test("Parse data URL with ;base64, header still decodes base64") + func testParseDataURLBase64HeaderRegression() { + let result = Data.parseDataURL("data:application/octet-stream;base64,/wA=") + #expect(result != nil) + if let (mimeType, data) = result { + #expect(mimeType == "application/octet-stream") + #expect(data == Data([0xFF, 0x00])) + } + } + + @Test("Parse data URL with charset and ;base64,") + func testParseDataURLCharsetAndBase64() { + let result = Data.parseDataURL("data:text/plain;charset=utf-8;base64,SGk=") + #expect(result != nil) + if let (mimeType, data) = result { + #expect(mimeType == "text/plain;charset=utf-8") + #expect(String(data: data, encoding: .utf8) == "Hi") + } + } + @Test("Test data URL encoding") func testDataURLEncoding() { let testData = "Hello, world!".data(using: .utf8)!