mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-08 14:21:14 +00:00
test/fuzz: add test to reproduce found fuzz errors (#6757)
This change does two things: 1. It fixes the json fuzzer to account for receiving array results. Arrays are returned by the rpc server when the input data is an array. 2. Adds a `fuzz_test.go` file and corresponding `testdata` directory containing the failing test case. This seems like a reasonable way to add and track previous crash issues in our fuzz test cases. The upcoming stdlib go fuzz tool does effectively this automatically.
This commit is contained in:
33
test/fuzz/rpc/jsonrpc/server/fuzz_test.go
Normal file
33
test/fuzz/rpc/jsonrpc/server/fuzz_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package server_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/test/fuzz/rpc/jsonrpc/server"
|
||||
)
|
||||
|
||||
const testdataDir = "testdata"
|
||||
|
||||
func TestServerOnTestData(t *testing.T) {
|
||||
entries, err := os.ReadDir(testdataDir)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, e := range entries {
|
||||
entry := e
|
||||
t.Run(entry.Name(), func(t *testing.T) {
|
||||
defer func() {
|
||||
r := recover()
|
||||
require.Nilf(t, r, "testdata test panic")
|
||||
}()
|
||||
f, err := os.Open(filepath.Join(testdataDir, entry.Name()))
|
||||
require.NoError(t, err)
|
||||
input, err := ioutil.ReadAll(f)
|
||||
require.NoError(t, err)
|
||||
server.Fuzz(input)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package handler
|
||||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -39,11 +39,26 @@ func Fuzz(data []byte) int {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(blob) > 0 {
|
||||
recv := new(types.RPCResponse)
|
||||
if err := json.Unmarshal(blob, recv); err != nil {
|
||||
if len(blob) == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
if inputJSONIsMultiElementSlice(data) {
|
||||
recv := []types.RPCResponse{}
|
||||
if err := json.Unmarshal(blob, &recv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return 1
|
||||
}
|
||||
recv := &types.RPCResponse{}
|
||||
if err := json.Unmarshal(blob, recv); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func inputJSONIsMultiElementSlice(input []byte) bool {
|
||||
slice := []interface{}{}
|
||||
err := json.Unmarshal(input, &slice)
|
||||
return err == nil && len(slice) > 1
|
||||
}
|
||||
|
||||
1
test/fuzz/rpc/jsonrpc/server/testdata/1184f5b8d4b6dd08709cf1513f26744167065e0d
vendored
Normal file
1
test/fuzz/rpc/jsonrpc/server/testdata/1184f5b8d4b6dd08709cf1513f26744167065e0d
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[0]
|
||||
@@ -0,0 +1 @@
|
||||
[{"iD":7},{"iD":7}]
|
||||
Reference in New Issue
Block a user