From cc3910ea106bdba5d3e5c32e6aab1116c11267b8 Mon Sep 17 00:00:00 2001 From: latent-9 <296084221+latent-9@users.noreply.github.com> Date: Sun, 9 Aug 2026 21:21:55 +1200 Subject: [PATCH] Fix McpHeaderEncoder.DecodeValue throwing on the degenerate base64 wrapper --- .../Protocol/McpHeaderEncoder.cs | 3 ++- .../Client/McpHeaderEncoderTests.cs | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs b/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs index 9366063e4..904f4db00 100644 --- a/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs +++ b/src/ModelContextProtocol.Core/Protocol/McpHeaderEncoder.cs @@ -126,7 +126,8 @@ public static class McpHeaderEncoder // Check for Base64 wrapper. The spec requires the sentinel markers to be // case-sensitive and exactly lowercase per SEP-2243. - if (headerValue.StartsWith(Base64Prefix, StringComparison.Ordinal) && + if (headerValue.Length >= Base64Prefix.Length + Base64Suffix.Length && + headerValue.StartsWith(Base64Prefix, StringComparison.Ordinal) && headerValue.EndsWith(Base64Suffix, StringComparison.Ordinal)) { var base64Content = headerValue.Substring( diff --git a/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs b/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs index 26de71b45..1e4fc00ef 100644 --- a/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs +++ b/tests/ModelContextProtocol.Tests/Client/McpHeaderEncoderTests.cs @@ -104,6 +104,16 @@ public void DecodeValue_ValidBase64_Decodes() Assert.Equal("Hello", result); } + [Fact] + public void DecodeValue_DegenerateWrapper_ReturnsLiteralValue() + { + // "=?base64?=" matches both the prefix "=?base64?" and the suffix "?=" because they + // overlap on the shared '?', but it is too short to contain any base64 content. It must be + // returned as-is rather than throwing when the wrapper is stripped. + var result = McpHeaderEncoder.DecodeValue("=?base64?="); + Assert.Equal("=?base64?=", result); + } + [Fact] public void DecodeValue_CaseSensitivePrefix_ReturnsLiteralValue() {