.NET 5及以上版本解码含LF的Base64字节触发IndexOutOfRangeException
.NET 5+中FromBase64Transform处理含LF的Base64流触发IndexOutOfRangeException问题分析
问题概述
将运行时从netcoreapp3.1升级到.NET 5后,原本可正常转换含LF字符的Base64字节流的代码开始触发IndexOutOfRangeException,该问题在Windows和Linux平台表现一致。使用CRLF作为分隔符时不会触发异常。已提交官方Bug,但需确认代码是否存在问题或易出错点,目前临时方案是通过中间件流移除输入中的所有LF字符(Base64中的空白字符本就多余)。
复现代码
[TestFixture] public class Fixture { [Test] public void Crashes_on_runtime_greater_or_equal_to_NET_5() { var txt = "YWJj\nZGVm"; // abc\ndef var base64Bytes = Encoding.UTF8.GetBytes(txt); var stream = new MemoryStream(base64Bytes); var base64Transform = new FromBase64Transform(); var cryptoStream = new CryptoStream(stream, base64Transform, CryptoStreamMode.Read); var result = new MemoryStream(); cryptoStream.CopyTo(result); Console.WriteLine(Encoding.UTF8.GetString(result.ToArray())); } }
异常堆栈信息
System.IndexOutOfRangeException : Index was outside the bounds of the array. at System.Security.Cryptography.FromBase64Transform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) at System.Security.Cryptography.CryptoStream.ReadAsyncCore(Memory`1 buffer, CancellationToken cancellationToken, Boolean useAsync) at System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset, Int32 count) at System.Security.Cryptography.CryptoStream.CopyTo(Stream destination, Int32 bufferSize) at System.IO.Stream.CopyTo(Stream destination) at ClassLibrary1.Fixture.Crashes_on_runtime_greater_or_equal_to_NET_5() in E:\cm_1\drive\ClassLibrary1\Class1.cs:line 20
问题分析与解决方案
代码合理性确认
你的代码逻辑本身没有错误:Base64规范允许在编码内容中插入空白字符(包括LF),FromBase64Transform理应正确处理这类场景。该问题仅在.NET 5及以上版本出现,说明这是.NET运行时底层实现变更引入的Bug,与你的代码无关。
临时解决方案
你提到的移除输入中所有空白字符的方案是可靠的,因为Base64解码过程会忽略空白字符,提前清理不会影响最终结果。除了中间件流的方式,也可以用更简洁的字符串处理方式规避问题:
var txt = "YWJj\nZGVm"; // 移除所有Base64空白字符(LF、CR、空格等) var cleanedBase64 = Regex.Replace(txt, @"\s", ""); var bytes = Convert.FromBase64String(cleanedBase64); Console.WriteLine(Encoding.UTF8.GetString(bytes));
或者直接针对性移除LF:
var cleanedBase64 = txt.Replace("\n", "");
结论
该问题属于.NET运行时的官方Bug,你的代码不存在逻辑错误。临时清理Base64输入中的空白字符是有效的规避方案,后续可关注官方Bug修复进度。
内容的提问来源于stack exchange,提问作者idementia
相关产品推荐
相关产品推荐

