github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/vm/fuzz_test.go (about) 1 package vm 2 3 import ( 4 "testing" 5 6 "github.com/nspcc-dev/neo-go/pkg/crypto/keys" 7 "github.com/nspcc-dev/neo-go/pkg/smartcontract" 8 "github.com/nspcc-dev/neo-go/pkg/vm/opcode" 9 "github.com/stretchr/testify/require" 10 ) 11 12 var fuzzSeedValidScripts = [][]byte{ 13 makeProgram(opcode.PUSH1, opcode.PUSH10, opcode.ADD), 14 makeProgram(opcode.PUSH10, opcode.JMP, 3, opcode.ABORT, opcode.RET), 15 makeProgram(opcode.PUSHINT16, 1, 2, opcode.PUSHINT32, 3, 4, opcode.DROP), 16 makeProgram(opcode.PUSH2, opcode.NEWARRAY, opcode.DUP, opcode.PUSH0, opcode.PUSH1, opcode.SETITEM, opcode.VALUES), 17 append([]byte{byte(opcode.PUSHDATA1), 10}, randomBytes(10)...), 18 append([]byte{byte(opcode.PUSHDATA1), 100}, randomBytes(100)...), 19 // Simplified version of fuzzer output from #2659. 20 {byte(opcode.CALL), 3, byte(opcode.ASSERT), 21 byte(opcode.CALL), 3, byte(opcode.ASSERT), 22 byte(opcode.DEPTH), byte(opcode.PACKSTRUCT), byte(opcode.DUP), 23 byte(opcode.UNPACK), byte(opcode.PACKSTRUCT), byte(opcode.POPITEM), 24 byte(opcode.DEPTH)}, 25 } 26 27 func FuzzIsScriptCorrect(f *testing.F) { 28 for _, s := range fuzzSeedValidScripts { 29 f.Add(s) 30 } 31 f.Fuzz(func(t *testing.T, script []byte) { 32 require.NotPanics(t, func() { 33 _ = IsScriptCorrect(script, nil) 34 }) 35 }) 36 } 37 38 func FuzzParseMultiSigContract(f *testing.F) { 39 pubs := make(keys.PublicKeys, 10) 40 for i := range pubs { 41 p, _ := keys.NewPrivateKey() 42 pubs[i] = p.PublicKey() 43 } 44 45 s, _ := smartcontract.CreateMultiSigRedeemScript(1, pubs[:1]) 46 f.Add(s) 47 48 s, _ = smartcontract.CreateMultiSigRedeemScript(3, pubs[:6]) 49 f.Add(s) 50 51 s, _ = smartcontract.CreateMultiSigRedeemScript(1, pubs) 52 f.Add(s) 53 54 f.Fuzz(func(t *testing.T, script []byte) { 55 var b [][]byte 56 var ok bool 57 var n int 58 require.NotPanics(t, func() { 59 n, b, ok = ParseMultiSigContract(script) 60 }) 61 if ok { 62 require.True(t, n <= len(b)) 63 } 64 }) 65 } 66 67 func FuzzVMDontPanic(f *testing.F) { 68 for _, s := range fuzzSeedValidScripts { 69 f.Add(s) 70 } 71 f.Fuzz(func(t *testing.T, script []byte) { 72 if IsScriptCorrect(script, nil) != nil { 73 return 74 } 75 76 v := load(script) 77 78 // Prevent infinite loops from being reported as fail. 79 v.GasLimit = 1000 80 v.getPrice = func(opcode.Opcode, []byte) int64 { 81 return 1 82 } 83 84 require.NotPanics(t, func() { 85 _ = v.Run() 86 }) 87 }) 88 }