accounts/abi: multiple fixes to arguments

This commit is contained in:
Marius van der Wijden 2020-04-01 17:22:25 +02:00
parent ebf0efeeb2
commit f4b170a088
2 changed files with 28 additions and 41 deletions

View file

@ -92,9 +92,8 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error {
if len(data) == 0 {
if len(arguments) != 0 {
return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected")
} else {
return nil // Nothing to unmarshal, return
}
return nil // Nothing to unmarshal, return
}
// make sure the passed value is arguments pointer
if reflect.Ptr != reflect.ValueOf(v).Kind() {
@ -115,18 +114,24 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error {
// UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value
func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error {
// Make sure map is not nil
if v == nil {
return fmt.Errorf("abi: cannot unpack into a nil map")
}
if len(data) == 0 {
if len(arguments) != 0 {
return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected")
} else {
return nil // Nothing to unmarshal, return
}
return nil // Nothing to unmarshal, return
}
marshalledValues, err := arguments.UnpackValues(data)
if err != nil {
return err
}
return arguments.unpackIntoMap(v, marshalledValues)
for i, arg := range arguments.NonIndexed() {
v[arg.Name] = marshalledValues[i]
}
return nil
}
// unpack sets the unmarshalled value to go format.
@ -198,19 +203,6 @@ func unpack(t *Type, dst interface{}, src interface{}) error {
return nil
}
// unpackIntoMap unpacks marshalledValues into the provided map[string]interface{}
func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error {
// Make sure map is not nil
if v == nil {
return fmt.Errorf("abi: cannot unpack into a nil map")
}
for i, arg := range arguments.NonIndexed() {
v[arg.Name] = marshalledValues[i]
}
return nil
}
// unpackAtomic unpacks ( hexdata -> go ) a single value
func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error {
if arguments.LengthNonIndexed() == 0 {
@ -236,30 +228,28 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interfac
// unpackTuple unpacks ( hexdata -> go ) a batch of values.
func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
var (
value = reflect.ValueOf(v).Elem()
typ = value.Type()
kind = value.Kind()
value = reflect.ValueOf(v).Elem()
typ = value.Type()
kind = value.Kind()
nonIndexedArgs = arguments.NonIndexed()
)
if err := requireUnpackKind(value, typ, kind, arguments); err != nil {
if err := requireUnpackKind(value, len(nonIndexedArgs), arguments); err != nil {
return err
}
// If the interface is a struct, get of abi->struct_field mapping
var abi2struct map[string]string
if kind == reflect.Struct {
var (
argNames []string
err error
)
for _, arg := range arguments.NonIndexed() {
argNames = append(argNames, arg.Name)
argNames := make([]string, len(nonIndexedArgs))
for i, arg := range nonIndexedArgs {
argNames[i] = arg.Name
}
abi2struct, err = mapArgNamesToStructFields(argNames, value)
if err != nil {
var err error
if abi2struct, err = mapArgNamesToStructFields(argNames, value); err != nil {
return err
}
}
for i, arg := range arguments.NonIndexed() {
for i, arg := range nonIndexedArgs {
switch kind {
case reflect.Struct:
field := value.FieldByName(abi2struct[arg.Name])

View file

@ -118,18 +118,16 @@ func requireAssignable(dst, src reflect.Value) error {
}
// requireUnpackKind verifies preconditions for unpacking `args` into `kind`
func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
args Arguments) error {
switch k {
func requireUnpackKind(v reflect.Value, minLength int, args Arguments) error {
switch v.Kind() {
case reflect.Struct:
case reflect.Slice, reflect.Array:
if minLen := args.LengthNonIndexed(); v.Len() < minLen {
if v.Len() < minLength {
return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d",
minLen, v.Len())
minLength, v.Len())
}
default:
return fmt.Errorf("abi: cannot unmarshal tuple into %v", t)
return fmt.Errorf("abi: cannot unmarshal tuple into %v", v.Type())
}
return nil
}
@ -156,9 +154,8 @@ func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[stri
continue
}
// skip fields that have no abi:"" tag.
var ok bool
var tagName string
if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok {
tagName, ok := typ.Field(i).Tag.Lookup("abi")
if !ok {
continue
}
// check if tag is empty.