accounts/abi: support nested nested array args

Previously, the code only considered the outer-size of the array,
ignoring the size of the contents. This was fine for most types,
but nested arrays are packed directly into it, and count towards
the total size. This resulted in arguments following a nested
array to replicate some of the binary contents of the array.

The fix: for arrays, calculate their complete contents size:
 count the arg.Type.Elem.Size when Elem is an Array, and
 repeat when their child is an array too, etc.
The count is the number of 32 byte elements, similar to how it
 previously counted, but nested.
This commit is contained in:
protolambda 2018-01-25 16:24:51 +01:00 committed by Martin Holst Swende
parent 6f664898d3
commit 2c60912b28
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -85,7 +85,6 @@ func (arguments Arguments) isTuple() bool {
// Unpack performs the operation hexdata -> Go format
func (arguments Arguments) Unpack(v interface{}, data []byte) error {
// make sure the passed value is arguments pointer
if reflect.Ptr != reflect.ValueOf(v).Kind() {
return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
@ -100,6 +99,21 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error {
return arguments.unpackAtomic(v, marshalledValues)
}
// Computes the full size of an array;
// i.e. counting nested arrays, which count towards size for unpacking.
func getArraySize(arr *Type) int {
size := arr.Size
//arrays can be nested, with each element being the same size
arr = arr.Elem
for arr.T == ArrayTy {
//keep multiplying by elem.Size while the elem is an array.
size *= arr.Size
arr = arr.Elem
}
//Now we have the full array size, including its children.
return size
}
func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
var (