From 8197f3b309577c4de56aa560cb092376632f64a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 29 Dec 2017 16:16:57 +0200 Subject: [PATCH] accounts: handle purely underscore output names --- accounts/abi/argument.go | 6 ++++++ accounts/abi/bind/bind.go | 8 ++++++-- accounts/abi/bind/bind_test.go | 35 ++++++++++++++++++++-------------- accounts/abi/unpack_test.go | 9 +++++++++ 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 5cfce61482..4540c342f6 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -101,6 +101,9 @@ func (arguments Arguments) unpackTuple(v interface{}, output []byte) error { exists := make(map[string]bool) for _, arg := range arguments { field := capitalise(arg.Name) + if field == "" { + return fmt.Errorf("abi: purely underscored output cannot unpack to struct") + } if exists[field] { return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field) } @@ -240,5 +243,8 @@ func capitalise(input string) string { for len(input) > 0 && input[0] == '_' { input = input[1:] } + if len(input) == 0 { + return "" + } return strings.ToUpper(input[:1]) + input[1:] } diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 366c983263..8175e3cb9b 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -310,6 +310,9 @@ func capitalise(input string) string { for len(input) > 0 && input[0] == '_' { input = input[1:] } + if len(input) == 0 { + return "" + } return strings.ToUpper(input[:1]) + input[1:] } @@ -330,9 +333,10 @@ func structured(method abi.Method) bool { if out.Name == "" { return false } - // If the field name collides (var, Var, _var, _Var), we can't organize into a struct + // If the field name is empty when normalized or collides (var, Var, _var, _Var), + // we can't organize into a struct field := capitalise(out.Name) - if exists[field] { + if field == "" || exists[field] { return false } exists[field] = true diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 4099476223..896441d79c 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -453,25 +453,30 @@ var bindTests = []struct { `Underscorer`, ` contract Underscorer { - function UnderscoredOutput() constant returns (int _int, string _string) { - return (314, "pi"); + function UnderscoredOutput() constant returns (int _int, string _string) { + return (314, "pi"); } - function LowerLowerCollision() constant returns (int _res, int res) { - return (1, 2); + function LowerLowerCollision() constant returns (int _res, int res) { + return (1, 2); } - function LowerUpperCollision() constant returns (int _res, int Res) { - return (1, 2); + function LowerUpperCollision() constant returns (int _res, int Res) { + return (1, 2); + } + function UpperLowerCollision() constant returns (int _Res, int res) { + return (1, 2); } - function UpperLowerCollision() constant returns (int _Res, int res) { - return (1, 2); + function UpperUpperCollision() constant returns (int _Res, int Res) { + return (1, 2); } - function UpperUpperCollision() constant returns (int _Res, int Res) { - return (1, 2); + function PurelyUnderscoredOutput() constant returns (int _, int res) { + return (1, 2); + } + function AllPurelyUnderscoredOutput() constant returns (int _, int __) { + return (1, 2); } } - - `, `6060604052341561000f57600080fd5b6102a98061001e6000396000f30060606040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461007257806367e6633d146100a2578063af7486ab14610137578063e02ab24d14610167578063e409ca4514610197575b600080fd5b341561007d57600080fd5b6100856101c7565b604051808381526020018281526020019250505060405180910390f35b34156100ad57600080fd5b6100b56101dc565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156100fb5780820151818401526020810190506100e0565b50505050905090810190601f1680156101285780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561014257600080fd5b61014a61022a565b604051808381526020018281526020019250505060405180910390f35b341561017257600080fd5b61017a61023f565b604051808381526020018281526020019250505060405180910390f35b34156101a257600080fd5b6101aa610254565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b60006101e6610269565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a723058204b430a23ef5e12ced00d09d546fdc343d181a3229300c3dd1b6fabc0816d8ade0029`, - `[{"constant":true,"inputs":[],"name":"UpperUpperCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UnderscoredOutput","outputs":[{"name":"_int","type":"int256"},{"name":"_string","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperLowerCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerLowerCollision","outputs":[{"name":"_res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"}]`, + `, `6060604052341561000f57600080fd5b6103498061001e6000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303a592131461008857806367e6633d146100b85780639df484851461014d578063af7486ab1461017d578063b564b34d146101ad578063e02ab24d146101dd578063e409ca451461020d575b600080fd5b341561009357600080fd5b61009b61023d565b604051808381526020018281526020019250505060405180910390f35b34156100c357600080fd5b6100cb610252565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156101115780820151818401526020810190506100f6565b50505050905090810190601f16801561013e5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561015857600080fd5b6101606102a0565b604051808381526020018281526020019250505060405180910390f35b341561018857600080fd5b6101906102b5565b604051808381526020018281526020019250505060405180910390f35b34156101b857600080fd5b6101c06102ca565b604051808381526020018281526020019250505060405180910390f35b34156101e857600080fd5b6101f06102df565b604051808381526020018281526020019250505060405180910390f35b341561021857600080fd5b6102206102f4565b604051808381526020018281526020019250505060405180910390f35b60008060016002819150809050915091509091565b600061025c610309565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b60008060016002819150809050915091509091565b6020604051908101604052806000815250905600a165627a7a72305820c11dcfa136fc7d182ee4d34f0b12d988496228f7e2d02d2b5376d996ca1743d00029`, + `[{"constant":true,"inputs":[],"name":"LowerUpperCollision","outputs":[{"name":"_res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UnderscoredOutput","outputs":[{"name":"_int","type":"int256"},{"name":"_string","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperLowerCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"AllPurelyUnderscoredOutput","outputs":[{"name":"_","type":"int256"},{"name":"__","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"UpperUpperCollision","outputs":[{"name":"_Res","type":"int256"},{"name":"Res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LowerLowerCollision","outputs":[{"name":"_res","type":"int256"},{"name":"res","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"}]`, ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() @@ -485,7 +490,7 @@ var bindTests = []struct { } sim.Commit() - // Verify that underscored return values correclty parse into structs + // Verify that underscored return values correctly parse into structs if res, err := underscorer.UnderscoredOutput(nil); err != nil { t.Errorf("Failed to call constant function: %v", err) } else if res.Int.Cmp(big.NewInt(314)) != 0 || res.String != "pi" { @@ -498,6 +503,8 @@ var bindTests = []struct { a, b, _ = underscorer.LowerUpperCollision(nil) a, b, _ = underscorer.UpperLowerCollision(nil) a, b, _ = underscorer.UpperUpperCollision(nil) + a, b, _ = underscorer.PurelyUnderscoredOutput(nil) + a, b, _ = underscorer.AllPurelyUnderscoredOutput(nil) fmt.Println(a, b, err) `, diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 194d06586d..4d7fe638c4 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -295,6 +295,15 @@ var unpackTests = []unpackTest{ }{}, err: "abi: multiple outputs mapping to the same struct field 'Int'", }, + { + def: `[{"name":"Int","type":"int256"},{"name":"_","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + Int1 *big.Int + Int2 *big.Int + }{}, + err: "abi: purely underscored output cannot unpack to struct", + }, } func TestUnpack(t *testing.T) {