Skip to content

Commit 39213fb

Browse files
Copilotericstj
andcommitted
Use Base64.DecodeFromUtf8 to avoid string intermediate during decoding
Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com>
1 parent 1d76c11 commit 39213fb

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

src/ModelContextProtocol.Core/Protocol/BlobResourceContents.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Buffers.Text;
12
using System.Runtime.InteropServices;
23
using System.Text.Json.Serialization;
34

@@ -58,7 +59,17 @@ public ReadOnlyMemory<byte> Data
5859
if (_decodedData is null)
5960
{
6061
#if NET
61-
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Blob.Span));
62+
// Decode directly from UTF-8 base64 bytes without string intermediate
63+
int maxLength = Base64.GetMaxDecodedFromUtf8Length(Blob.Length);
64+
byte[] buffer = new byte[maxLength];
65+
if (Base64.DecodeFromUtf8(Blob.Span, buffer, out _, out int bytesWritten) == System.Buffers.OperationStatus.Done)
66+
{
67+
_decodedData = bytesWritten == maxLength ? buffer : buffer.AsMemory(0, bytesWritten).ToArray();
68+
}
69+
else
70+
{
71+
throw new FormatException("Invalid base64 data");
72+
}
6273
#else
6374
byte[] array = MemoryMarshal.TryGetArray(Blob, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Blob.ToArray();
6475
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));

src/ModelContextProtocol.Core/Protocol/ContentBlock.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Buffers;
2+
using System.Buffers.Text;
23
using System.ComponentModel;
34
using System.Diagnostics;
45
using System.Diagnostics.CodeAnalysis;
@@ -421,7 +422,17 @@ public ReadOnlyMemory<byte> DecodedData
421422
if (_decodedData is null)
422423
{
423424
#if NET
424-
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.Span));
425+
// Decode directly from UTF-8 base64 bytes without string intermediate
426+
int maxLength = Base64.GetMaxDecodedFromUtf8Length(Data.Length);
427+
byte[] buffer = new byte[maxLength];
428+
if (Base64.DecodeFromUtf8(Data.Span, buffer, out _, out int bytesWritten) == System.Buffers.OperationStatus.Done)
429+
{
430+
_decodedData = bytesWritten == maxLength ? buffer : buffer.AsMemory(0, bytesWritten).ToArray();
431+
}
432+
else
433+
{
434+
throw new FormatException("Invalid base64 data");
435+
}
425436
#else
426437
byte[] array = MemoryMarshal.TryGetArray(Data, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Data.ToArray();
427438
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));
@@ -482,7 +493,17 @@ public ReadOnlyMemory<byte> DecodedData
482493
if (_decodedData is null)
483494
{
484495
#if NET
485-
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.Span));
496+
// Decode directly from UTF-8 base64 bytes without string intermediate
497+
int maxLength = Base64.GetMaxDecodedFromUtf8Length(Data.Length);
498+
byte[] buffer = new byte[maxLength];
499+
if (Base64.DecodeFromUtf8(Data.Span, buffer, out _, out int bytesWritten) == System.Buffers.OperationStatus.Done)
500+
{
501+
_decodedData = bytesWritten == maxLength ? buffer : buffer.AsMemory(0, bytesWritten).ToArray();
502+
}
503+
else
504+
{
505+
throw new FormatException("Invalid base64 data");
506+
}
486507
#else
487508
byte[] array = MemoryMarshal.TryGetArray(Data, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Data.ToArray();
488509
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));

0 commit comments

Comments
 (0)