diff --git a/x86/x86asm/avx.go b/x86/x86asm/avx.go index 148f72b..82c3472 100644 --- a/x86/x86asm/avx.go +++ b/x86/x86asm/avx.go @@ -76,6 +76,9 @@ func decodeAVX(src []byte, pos int, vex Prefix, vexIndex int, inst Inst, mode in _ = evex_z // TODO: use zeroing mask if needed for output + if pos >= len(src) { + return inst, errors.New("truncated") + } opbyte := src[pos] pos++ diff --git a/x86/x86asm/decode_test.go b/x86/x86asm/decode_test.go index 4543cd2..e409a2f 100644 --- a/x86/x86asm/decode_test.go +++ b/x86/x86asm/decode_test.go @@ -75,6 +75,11 @@ func TestDecodeDoesNotCrash(t *testing.T) { []byte{}, []byte{0xc5}, []byte{0xc4}, + // Streams ending exactly at the end of a VEX or EVEX prefix, + // leaving no opcode byte. + []byte{0xc5, 0xfc}, + []byte{0xc4, 0xe2, 0x7d}, + []byte{0x62, 0xf1, 0x7c, 0x48}, } for _, test := range cases { _, err := Decode([]byte(test), 64) // the only goal is that this line does not panic