【问题标题】:IndexOutOfRangeException on decoding base64 bytes with LF characters included (>= .NET 5 only)解码包含 LF 字符的 base64 字节时出现 IndexOutOfRangeException(仅限 >= .NET 5)
【发布时间】:2023-02-14 16:20:22
【问题描述】:

我已将运行时从 netcoreapp3.1 升级到 NET 5,将包含 LF 字符的 base64 字节无错误地转换为字符串的代码开始因 IndexOutOfRangeException 而崩溃。 Windows 和 Linux 平台的行为相同。

我已经submitted a bug report 但还是决定询问这段代码是否有问题或容易出错。

目前,我能想到的一个解决方法是添加一个中间件流,这将从输入中删除所有 LF 字符,因为无论如何 base64 中的空格过多。 值得一提的是,CRLF 定界符不会发生异常。

[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

【问题讨论】:

  • 这是错误的!!!!您缺少 base64Str = Convert.ToBase64String(base64Bytes)
  • @jdweng 不,这没有错,你在说什么?
  • @CodeCaster 我认为他们是真心想提供帮助,但这种帮助的糟糕程度令人震惊。
  • 为了显示最小的重现性,这个例子被简化了。在实际服务中,我有很多字节的 base64 输入,是从流中读取的,所以,我不能就地转换它们。我有一个高负载服务,所以如果我不以流方式解码 base64,内存就会耗尽。
  • 是的,问题是我不控制生产方,所以唯一的选择是以不包含 LF 分隔符的方式修改输入。或者等待一些运行时补丁或任何其他更简单的解决方法。

标签: c# .net base64 lf


【解决方案1】:

CryptoStream 调用:

int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, ...)

使用输入缓冲区,偏移量 0,计数 8(已读取两个完整块,2*4)。

FromBase64Transform 保持一些内部状态并返回 6(已写入 6 个字节的输出),然后接收最终调用:

byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)

与('m

猜你喜欢
  • 2019-03-08
  • 1970-01-01
  • 2011-04-04
  • 2021-11-21
  • 1970-01-01
  • 2019-10-12
  • 2017-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多