假设我有以下结构
type Hdr struct{
Src uint16
Dst uint16
Priotity byte
Pktcnt byte
Opcode byte
Ver byte
}
Run Code Online (Sandbox Code Playgroud)
我有两个函数Marshal,可以对以下二进制格式Unmarshal进行编码:Hdr
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Src |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Dst |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Prio | Cnt | Opcode| Ver |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)
我想使用 Go Fuzz 来生成随机、有效的Hdr实例,Marshal然后转换为二进制,Unmarshal并确保输出与原始输入匹配。
我遇到的主要问题是我不知道如何告诉 Go Fuzz 这样的字段Priotity不能大于 15,否则它们在编组时会被截断(只有 4 位)。我如何设置这个约束?
这只是一个玩具盒。很多时候,像上面这样的协议opcode会触发二次更复杂的解析/审查。模糊测试仍然可以在约束内发现非常有用的问题(即:如果 Prio0x00和 Cnt0x2F辅助解析器将出错,因为分隔符是\)。
编辑
我不确定模糊测试是否适合这里。模糊测试旨在查找意外输入:多字节 UTF8 输入(有效和无效);负值;巨大的值、较长的长度等。这些将尝试捕获“边缘”情况。
就您的情况而言,您知道:
Unmarshal输入负载必须是 6 个字节(否则会出错)所以普通testing.T测试可能更适合这里。
把事情简单化。
如果您不想“浪费”Fuzz 输入并且您知道代码的输入约束,您可以尝试如下操作:
func coerce(h *Hdr) (skip bool) {
h.Priotity &= 0x0f // ensure priority is 0-15
h.OpCode %= 20 // ensure opcode is 0-19
return false // optionally skip this test
}
Run Code Online (Sandbox Code Playgroud)
在您的测试中 - 可以测试强制值 - 或跳过(如 @jch 所示):
import "github.com/google/go-cmp/cmp"
f.Fuzz(func(t *testing.T, src, dst uint16, pri, count, op, ver byte) {
h := Hdr{src, dst, pri, count, op, ver}
if coerce(&h) {
t.Skip()
return
}
bs, err := Marshal(h) // check err
h2, err := Unmarhsal(bs) // check err
if !cmp.Equal(h, h2) {
t.Errorf("Marshal/Unmarshal validation failed for: %+v", h)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
702 次 |
| 最近记录: |