accounts/abi: fixed unpacking in to already slice interfaces

Previously it was assumed that wheneven type `[]interface{}` was given
that the interface was empty. The abigen rightfully assumed that
interface slices which already have pre-allocated variable sets to be
assigned.

This PR fixes that by checking that the given `[]interface{}` is larger
than zero and assigns each value using the generic `set` function (this
function has also been moved to abi/reflect.go) and checks whether the
assignment was possible.

The generic assignment function `set` now also deals with pointers
(useful for interface slice mentioned above) by dereferencing the
pointer until it finds a setable type.
This commit is contained in:
Jeffrey Wilcke
2016-05-11 13:21:25 +02:00
parent 5782164a35
commit 91a7a4a786
3 changed files with 94 additions and 31 deletions

View File

@ -289,6 +289,37 @@ func TestSimpleMethodUnpack(t *testing.T) {
}
}
func TestUnpackSetInterfaceSlice(t *testing.T) {
var (
var1 = new(uint8)
var2 = new(uint8)
)
out := []interface{}{var1, var2}
abi, err := JSON(strings.NewReader(`[{"type":"function", "name":"ints", "outputs":[{"type":"uint8"}, {"type":"uint8"}]}]`))
if err != nil {
t.Fatal(err)
}
marshalledReturn := append(pad([]byte{1}, 32, true), pad([]byte{2}, 32, true)...)
err = abi.Unpack(&out, "ints", marshalledReturn)
if err != nil {
t.Fatal(err)
}
if *var1 != 1 {
t.Errorf("expected var1 to be 1, got", *var1)
}
if *var2 != 2 {
t.Errorf("expected var2 to be 2, got", *var2)
}
out = []interface{}{var1}
err = abi.Unpack(&out, "ints", marshalledReturn)
expErr := "abi: cannot marshal in to slices of unequal size (require: 2, got: 1)"
if err == nil || err.Error() != expErr {
t.Error("expected err:", expErr, "Got:", err)
}
}
func TestPack(t *testing.T) {
for i, test := range []struct {
typ string