我已经将运行时从netcoreapp3.1升级到了NET 5,并且将包含LF字符的base64字节转换为字符串而没有错误的代码开始因IndexOutOfRangeException而崩溃。Windows和Linux平台的行为相同。
我已经提交了一份错误报告,但我决定无论如何都要问这个代码是否有错误或容易出错的地方。
目前,我能想到的一个解决方法是添加一个中间件流,它将从输入中删除所有LF字符,因为无论如何,base64中的空白都太多了。值得一提的是,CRLF分隔符不会发生异常。
[TestFixture]
public class Fixture
{
[Test]
public void Crashes_on_runtime_greater_or_equal_to_NET_5()
{
var txt = "YWJjnZGVm"; // abcndef
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_1driveClassLibrary1Class1.cs:line 20
CryptoStream调用:
int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, ...)
对于输入缓冲器,偏移量为0,计数为8(已读取两个完整块,2*4(。
FromBase64Transform保持一些内部状态并返回6(已写入六个字节的输出(,然后接收最后一个调用:
byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
使用('m ', 0, 1)
。这触发了FromBase64Transform中的错误,特别是在激进的内联方法中:
private static int GetOutputSize(int bytesToTransform, Span<byte> tmpBuffer)
{
// ...
if (tmpBuffer[len - 2] == padding)
}
缓冲区的长度为1,继续为-2,运行时对此并不满意。
任一:
- 用多余的
=
字符填充长度为%4(包括空白(的输入 - 使用流包装器更改输入
- 等待错误修复