core/signer: add fuzzer testcases + crashfixes

This commit is contained in:
Martin Holst Swende 2019-05-17 11:45:22 +02:00
parent 9579c717e9
commit aa46894dd5
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
9 changed files with 314 additions and 7 deletions

View file

@ -96,6 +96,9 @@ func (t *Type) typeName() string {
} }
func (t *Type) isReferenceType() bool { func (t *Type) isReferenceType() bool {
if len(t.Type) == 0 {
return false
}
// Reference types must have a leading uppercase characer // Reference types must have a leading uppercase characer
return unicode.IsUpper([]rune(t.Type)[0]) return unicode.IsUpper([]rune(t.Type)[0])
} }
@ -378,9 +381,11 @@ func (typedData *TypedData) Dependencies(primaryType string, found []string) []s
func (typedData *TypedData) EncodeType(primaryType string) hexutil.Bytes { func (typedData *TypedData) EncodeType(primaryType string) hexutil.Bytes {
// Get dependencies primary first, then alphabetical // Get dependencies primary first, then alphabetical
deps := typedData.Dependencies(primaryType, []string{}) deps := typedData.Dependencies(primaryType, []string{})
if len(deps) > 0 {
slicedDeps := deps[1:] slicedDeps := deps[1:]
sort.Strings(slicedDeps) sort.Strings(slicedDeps)
deps = append([]string{primaryType}, slicedDeps...) deps = append([]string{primaryType}, slicedDeps...)
}
// Format as a string with fields // Format as a string with fields
var buffer bytes.Buffer var buffer bytes.Buffer
@ -728,9 +733,12 @@ func (typedData *TypedData) formatData(primaryType string, data map[string]inter
} }
} }
} else if typedData.Types[field.Type] != nil { } else if typedData.Types[field.Type] != nil {
mapValue, _ := encValue.(map[string]interface{}) if mapValue, ok := encValue.(map[string]interface{}); ok {
mapOutput := typedData.formatData(field.Type, mapValue) mapOutput := typedData.formatData(field.Type, mapValue)
item.Value = mapOutput item.Value = mapOutput
} else {
item.Value = "<nil>"
}
} else { } else {
primitiveOutput := formatPrimitiveValue(field.Type, encValue) primitiveOutput := formatPrimitiveValue(field.Type, encValue)
item.Value = primitiveOutput item.Value = primitiveOutput
@ -791,7 +799,16 @@ func (nvt *NameValueType) Pprint(depth int) string {
// Validate checks if the types object is conformant to the specs // Validate checks if the types object is conformant to the specs
func (t Types) validate() error { func (t Types) validate() error {
for typeKey, typeArr := range t { for typeKey, typeArr := range t {
for _, typeObj := range typeArr { if len(typeKey) == 0 {
return fmt.Errorf("empty type key")
}
for i, typeObj := range typeArr {
if len(typeObj.Type) == 0 {
return fmt.Errorf("type %v:%d: empty Type", typeKey, i)
}
if len(typeObj.Name) == 0 {
return fmt.Errorf("type %v:%d: empty Name", typeKey, i)
}
if typeKey == typeObj.Type { if typeKey == typeObj.Type {
return fmt.Errorf("type '%s' cannot reference itself", typeObj.Type) return fmt.Errorf("type '%s' cannot reference itself", typeObj.Type)
} }

View file

@ -373,3 +373,37 @@ func TestJsonFiles(t *testing.T) {
} }
} }
} }
// TestFuzzerFiles tests some files that have been found by fuzzing to cause
// crashes or hangs.
func TestFuzzerFiles(t *testing.T) {
corpusdir := path.Join("testdata", "fuzzing")
testfiles, err := ioutil.ReadDir(corpusdir)
if err != nil {
t.Fatalf("failed reading files: %v", err)
}
verbose := false
for i, fInfo := range testfiles {
data, err := ioutil.ReadFile(path.Join(corpusdir, fInfo.Name()))
if err != nil {
t.Errorf("Failed to read file %v: %v", fInfo.Name(), err)
continue
}
var typedData core.TypedData
err = json.Unmarshal([]byte(data), &typedData)
if err != nil {
t.Errorf("Test %d, file %v, json unmarshalling failed: %v", i, fInfo.Name(), err)
continue
}
_, err = typedData.EncodeData("EIP712Domain", typedData.Domain.Map(), 1)
if verbose && err != nil {
fmt.Printf("%d, EncodeData[1] err: %v\n", i, err)
}
_, err = typedData.EncodeData(typedData.PrimaryType, typedData.Message, 1)
if verbose && err != nil {
fmt.Printf("%d, EncodeData[2] err: %v\n", i, err)
}
typedData.PrettyPrint()
typedData.Format()
}
}

View file

@ -0,0 +1,38 @@
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "version",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"Mail": [
{
"name": "test",
"type": "uint8"
}
]
},
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": "1",
"verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"test":"255.3"
}
}

View file

@ -0,0 +1,60 @@
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "version",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"Foo": [
{
"name": "addys",
"type": "address[]"
},
{
"name": "stringies",
"type": "string[]"
},
{
"name": "inties",
"type": "uint[]"
}
]
},
"primaryType": "Foo",
"domain": {
"name": "Lorem",
"version": "1",
"chainId": "1",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"addys": [
"0x0000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000003"
],
"stringies": [
"lorem",
"ipsum",
"dolores"
],
"inties": [
"0x0000000000000000000000000000000000000001",
"3",
4.0
]
}
}

View file

@ -0,0 +1,38 @@
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "version",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"Mail": [
{
"name": "test",
"type": "uint8"
}
]
},
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": "1",
"verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"test":257
}
}

View file

@ -0,0 +1 @@
{"domain":{"version":"0","chainId":""}}

View file

@ -0,0 +1,54 @@
{ "types": { "":[ {
"name": "name",
"type":"string" },
{
"name":"version",
"type": "string" }, {
"name": "chaiI",
"type":"uint256 . ad nowretig omeedifere" }, {
"ae": "eifinC",
"ty":"dess"
}
],
"Person":[
{
"name":"name",
"type": "string"
}, {
"name":"tes", "type":"it8"
},
{ "name":"t", "tye":"uit8"
},
{
"a":"ale",
"type": "ress"
}
],
"Mail": [
{
"name":"from", "type":"Person" },
{
"name": "to", "type": "Person"
},
{
"name": "contents",
"type": "string"
}
]
}, "primaryType": "Mail",
"domain": {
"name":"theMail", "version": "1",
"chainId": "1",
"verifyingntract": "0xCcccCCCcCCCCCCCcCCcCCCcCcccccC"
},
"message": { "from": {
"name": "Cow",
"test": "3",
"est2":5.0,
"llt": "0xcD2a3938E13D947E0bE734DfDD86" }, "to": { "name": "Bob",
"ts":"",
"tet2": 5,
"allet": "0bBBBBbbBBbbbbBbbBbbbbBBBbB"
},
"contents": "Hello, Bob!" }
}

View file

@ -0,0 +1,64 @@
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "version",
"type": "string"
},
{
"name": "chainId",
"type": "int"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"Person": [
{
"name": "name",
"type": "string"
},
{
"name": "wallet",
"type": "address"
}
],
"Mail": [
{
"name": "from",
"type": "Person"
},
{
"name": "to",
"type": "Mail"
},
{
"name": "s",
"type": "Person"
}
]
},
"primaryType": "Mail",
"domain": {
"name": "l",
"version": "1",
"chainId": "",
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"": ""
}
}

View file

@ -0,0 +1 @@
{"types":{"0":[{}]}}