在 go 中比较切片长度与 uint32 的最佳方法(用于对抗上下文)



我正在编写一些内部循环类型的输入解析代码,需要将缓冲区的长度与uint32进行比较。 理想的解决方案是快速、简洁、愚蠢(容易看到其正确性(,并适用于所有可能的输入,包括攻击者恶意操纵值的输入。 在这种情况下,如果整数溢出可以被利用来使程序崩溃,那么它就是一件大事。 这是我到目前为止所拥有的:

// Safely check if len(buf) <= size for all possible values of each
func sizeok(buf []MyType, size uint32) bool {
var n int = len(buf)
return n == int(uint32(n)) && uint32(n) <= size
}

这是一种痛苦,不能抽象到其他切片类型上。

我的问题是:首先,这真的正确吗? (在防御可利用的整数溢出时,您永远不能太小心。 其次,有没有更简单的方法可以通过单一比较做到这一点? 也许uint(len(buf)) <= uint(size)是否可以保证在所有平台和输入上安全地工作? 或者uint64(len(buf)) <= uint64(size)这不会在 32 位平台上生成次优代码?

Go 编程语言规范

长度和容量

内置函数 len 和 cap 接受各种类型的参数和 返回 int 类型的结果。该实施保证了 结果总是适合整数。

Call      Argument type    Result
len(s)    string type      string length in bytes
[n]T, *[n]T      array length (== n)
[]T              slice length
map[K]T          map length (number of defined keys)
chan T           number of elements queued in channel buffer

数值类型

uint32  all unsigned 32-bit integers (0 to 4294967295)
int64   all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

还有一组预先声明的数字类型,具有 特定于实现的大小:


uint     either 32 or 64 bits
int      same size as uint
len(buf)是类型int,根据实现的不同,为 32 或 64 位。例如,对于具有内置len函数的任何 Go 类型,

// Safely check if len(buf) <= size for all possible values of each
var size uint32
if int64(len(buf)) <= int64(size) {
// handle len(buf) <= size
}

最新更新