diff options
author | RJ <rj@erisindustries.com> | 2016-11-04 06:25:19 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2016-11-04 06:25:19 +0800 |
commit | 2ad5dba50a65e7471d24da7a258087ff97e00f36 (patch) | |
tree | 2e9895224048875544eaa922b924b97257ba72e8 /accounts/abi/abi.go | |
parent | ed2bc7fbe9a30c1861cffdd7d0fd570847a2ae0c (diff) | |
download | dexon-2ad5dba50a65e7471d24da7a258087ff97e00f36.tar dexon-2ad5dba50a65e7471d24da7a258087ff97e00f36.tar.gz dexon-2ad5dba50a65e7471d24da7a258087ff97e00f36.tar.bz2 dexon-2ad5dba50a65e7471d24da7a258087ff97e00f36.tar.lz dexon-2ad5dba50a65e7471d24da7a258087ff97e00f36.tar.xz dexon-2ad5dba50a65e7471d24da7a258087ff97e00f36.tar.zst dexon-2ad5dba50a65e7471d24da7a258087ff97e00f36.zip |
accounts/abi: differentiate between static and dynamic arrays (#3121)
solves #3119
Signed-off-by: VoR0220 <rj@erisindustries.com>
Diffstat (limited to 'accounts/abi/abi.go')
-rw-r--r-- | accounts/abi/abi.go | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index c127cd7a9..2efac1307 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -98,28 +98,46 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { case HashTy: // hash must be of slice hash refSlice = reflect.ValueOf([]common.Hash(nil)) case FixedBytesTy: - refSlice = reflect.ValueOf([]byte(nil)) + refSlice = reflect.ValueOf([][]byte(nil)) default: // no other types are supported return nil, fmt.Errorf("abi: unsupported slice type %v", elem.T) } - // get the offset which determines the start of this array ... - offset := int(common.BytesToBig(output[index : index+32]).Uint64()) - if offset+32 > len(output) { - return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32) - } - slice := output[offset:] - // ... starting with the size of the array in elements ... - size := int(common.BytesToBig(slice[:32]).Uint64()) - slice = slice[32:] - // ... and make sure that we've at the very least the amount of bytes - // available in the buffer. - if size*32 > len(slice) { - return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32) + var slice []byte + var size int + var offset int + if t.Type.IsSlice { + + // get the offset which determines the start of this array ... + offset = int(common.BytesToBig(output[index : index+32]).Uint64()) + if offset+32 > len(output) { + return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32) + } + + slice = output[offset:] + // ... starting with the size of the array in elements ... + size = int(common.BytesToBig(slice[:32]).Uint64()) + slice = slice[32:] + // ... and make sure that we've at the very least the amount of bytes + // available in the buffer. + if size*32 > len(slice) { + return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32) + } + + // reslice to match the required size + slice = slice[:(size * 32)] + } else if t.Type.IsArray { + //get the number of elements in the array + size = t.Type.SliceSize + + //check to make sure array size matches up + if index+32*size > len(output) { + return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), index+32*size) + } + //slice is there for a fixed amount of times + slice = output[index : index+size*32] } - // reslice to match the required size - slice = slice[:(size * 32)] for i := 0; i < size; i++ { var ( inter interface{} // interface type @@ -136,6 +154,8 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { inter = common.BytesToAddress(returnOutput) case HashTy: inter = common.BytesToHash(returnOutput) + case FixedBytesTy: + inter = returnOutput } // append the item to our reflect slice refSlice = reflect.Append(refSlice, reflect.ValueOf(inter)) |