go 如果(Encoding).解码参数可能重叠

pu82cl6c  于 24天前  发布在  Go
关注(0)|答案(7)|浏览(15)

base64.Decoding.Decode接受两个字节切片。由于编码后的base64数据永远不会小于解码后的数据,因此可以通过将相同的参数传递给两者来节省分配空间 - 即将解码后的数据存储在与原始base64数据相同的切片中。如果编码无效,这当然可能导致缓冲区中的垃圾数据。但通常情况下这是可以的。
文档没有明确说明这是允许的。Empirically, it seems to work ,但如果有文档说明,我会觉得更舒服。我们能否记录这是允许的,以及如果用户这样做会发生什么?如果我们想保留不允许它的灵活性,我们是否应该记录它是不允许的?
对于以下问题也会出现类似的情况:

  • base64.(*Encoding).Encode ,尽管在这种情况下似乎不太有用,因为编码后的数据可能比输入数据要大
  • encoding/{ascii85,base32.(*Encoding),hex}.{Decode,Encode}
svmlkihl

svmlkihl1#

我宁愿记录下它们不应该重叠,以便给实施带来更多的自由。

2mbi3lxu

2mbi3lxu2#

@robpike 你考虑的是哪种自由?如果我们谈论未来性能改进的空间,允许重叠的现有代码可以节省分配,它们处于同一阵营。也许你正在考虑类似向量指令的东西?

cbjzeqam

cbjzeqam3#

作为潜在的妥协方案,cipher.BlockMode.CryptBlocks文档中指出:
Dst和src必须完全重叠或者根本不重叠。
这允许我们高效地检查参数是否重叠。然后实现可以回退到较慢的路径或分配临时缓冲区,视情况而定。也就是说,如果我们不允许参数重叠,用户总是需要分配一个临时缓冲区,但是有了这个限制,他们可以让实现选择是否需要那个缓冲区。

wvt8vs2t

wvt8vs2t5#

在编码和解码方面,我在某些性能敏感的代码路径中多次依赖当前的实现。如果这被正式记录为不允许,是否可以附带一个相应的 vet 检查来允许检查和修复受影响的代码库?

z18hc3ub

z18hc3ub6#

@twmb,这可能无法满足"frequency" criteria of vet的要求,除非我们能证明许多Go用户确实依赖这种未记录的行为。

68de4m5k

68de4m5k7#

为了上下文,我只在看到其他代码中的模式后才开始使用它。我发现这相当巧妙,从那以后就一直重复使用它。

我的担忧是文档被更改了,但实现没有。几年过去了,也许只有到那时,向量化指令才会被引入。这会意外地破坏多少代码?我怀疑人们真的会重新阅读base64的Encode / Decode函数的文档,我也怀疑所有代码都在测试base64编码/解码是否按照用户期望的方式工作。为什么要测试标准库已经在自己测试的东西,而且我多久一次(作为维护者)查看我编写了两年以上代码的代码?

我非常确定至少有一个我过去使用当前代码的领域已经被测试过,因为结果被用于另一个计算中,然后我进行了单元测试。我不确定我使用当前代码的所有领域是否都完全测试了base64改变行为的情况。我不再能访问所有的代码库,而且我怀疑一些前代码库的领域正在被重新审视,因为它们当时(在那个时候)被测试得足够好并且完全稳定。我担心悄悄升级Go会在未被测试且很可能不会被注意到的意外领域中改变行为,直到为时已晚。

相关问题