accounts/abi: Fix unpacking of nested arrays

Removed the temporary workaround of packing to calculate size, which was
incorrect for slice-like types anyway.
Full size of nested arrays is used now.
This commit is contained in:
protolambda 2017-12-30 17:22:58 +01:00 committed by Martin Holst Swende
parent f428ef3e5d
commit 0e69ad846e
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -93,6 +93,17 @@ func readFixedBytes(t Type, word []byte) (interface{}, error) {
}
func getDeepSizeForType(t *Type) int {
//all other should be counted as 32 (slices have pointers to respective elements)
size := 32
//arrays wrap it, each element being the same size
for t.T == ArrayTy {
size *= t.Size
t = t.Elem
}
return size
}
// iteratively unpack elements
func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) {
if size < 0 {
@ -115,25 +126,20 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error)
return nil, fmt.Errorf("abi: invalid type in array/slice unpacking stage")
}
for i, j := start, 0; j < size; j++ {
elemSize := 32
if t.T == ArrayTy {
elemSize = getDeepSizeForType(t.Elem)
}
for i, j := start, 0; j < size; i, j = i+elemSize, j+1 {
inter, err := toGoType(i, *t.Elem, output)
if err != nil {
return nil, err
}
reflectedInter := reflect.ValueOf(inter)
//Although we just did the reverse, pack it, to get the length of the actual element.
//Getting the length directly from the "toGoType" would be way better,
// but it requires some refactoring to get it return the *consumed* length.
interPacked, err := t.Elem.pack(reflectedInter)
if err != nil {
return nil, err
}
i += len(interPacked)
// append the item to our reflect slice
refSlice.Index(j).Set(reflectedInter)
refSlice.Index(j).Set(reflect.ValueOf(inter))
}
// return the interface