aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi
diff options
context:
space:
mode:
authorRobert Zaremba <robert.zaremba@scale-it.pl>2017-11-10 09:30:26 +0800
committerMartin Holst Swende <martin@swende.se>2017-12-21 22:14:50 +0800
commit0ed8b838a991f81f79cc6ed4fa961c563203a7a2 (patch)
tree1b6c813a7271b73b4bc0f57ad8bf2ce49325285e /accounts/abi
parent9becba5540540bc37d4ad5eaaf7e4c1937a6542f (diff)
downloaddexon-0ed8b838a991f81f79cc6ed4fa961c563203a7a2.tar.gz
dexon-0ed8b838a991f81f79cc6ed4fa961c563203a7a2.tar.zst
dexon-0ed8b838a991f81f79cc6ed4fa961c563203a7a2.zip
accounts/abi: fix event unpack into slice
+ The event slice unpacker doesn't correctly extract element from the slice. The indexed arguments are not ignored as they should be (the data offset should not include the indexed arguments). + The `Elem()` call in the slice unpack doesn't work. The Slice related tests fails because of that. + the check in the loop are suboptimal and have been extracted out of the loop. + extracted common code from event and method tupleUnpack
Diffstat (limited to 'accounts/abi')
-rw-r--r--accounts/abi/argument.go10
-rw-r--r--accounts/abi/event.go23
-rw-r--r--accounts/abi/method.go16
-rw-r--r--accounts/abi/reflect.go8
-rw-r--r--accounts/abi/unpack.go2
5 files changed, 36 insertions, 23 deletions
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go
index 4691318ce..cd856061e 100644
--- a/accounts/abi/argument.go
+++ b/accounts/abi/argument.go
@@ -49,3 +49,13 @@ func (a *Argument) UnmarshalJSON(data []byte) error {
return nil
}
+
+func countNonIndexedArguments(args []Argument) int {
+ out := 0
+ for i := range args {
+ if !args[i].Indexed {
+ out++
+ }
+ }
+ return out
+}
diff --git a/accounts/abi/event.go b/accounts/abi/event.go
index 0d3c3c4fa..b67bc96a8 100644
--- a/accounts/abi/event.go
+++ b/accounts/abi/event.go
@@ -59,16 +59,19 @@ func (e Event) tupleUnpack(v interface{}, output []byte) error {
var (
value = valueOf.Elem()
typ = value.Type()
+ kind = value.Kind()
)
-
- if value.Kind() != reflect.Struct {
- return fmt.Errorf("abi: cannot unmarshal tuple in to %v", typ)
+ if err := requireUnpackKind(value, typ, kind, e.Inputs, true); err != nil {
+ return err
}
+ // `i` counts the nonindexed arguments.
+ // `j` counts the number of complex types.
+ // both `i` and `j` are used to to correctly compute `data` offset.
i, j := -1, 0
for _, input := range e.Inputs {
if input.Indexed {
- // can't read, continue
+ // Indexed arguments are not packed into data
continue
}
i++
@@ -83,7 +86,7 @@ func (e Event) tupleUnpack(v interface{}, output []byte) error {
}
reflectValue := reflect.ValueOf(marshalledValue)
- switch value.Kind() {
+ switch kind {
case reflect.Struct:
for j := 0; j < typ.NumField(); j++ {
field := typ.Field(j)
@@ -95,19 +98,13 @@ func (e Event) tupleUnpack(v interface{}, output []byte) error {
}
}
case reflect.Slice, reflect.Array:
- if value.Len() < i {
- return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", i, value.Len())
- }
v := value.Index(i)
- if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface {
- return fmt.Errorf("abi: cannot unmarshal %v in to %v", v.Type(), reflectValue.Type())
+ if err := requireAssignable(v, reflectValue); err != nil {
+ return err
}
- reflectValue := reflect.ValueOf(marshalledValue)
if err := set(v.Elem(), reflectValue, input); err != nil {
return err
}
- default:
- return fmt.Errorf("abi: cannot unmarshal tuple in to %v", typ)
}
}
return nil
diff --git a/accounts/abi/method.go b/accounts/abi/method.go
index 66e8751f3..ee79b51cb 100644
--- a/accounts/abi/method.go
+++ b/accounts/abi/method.go
@@ -101,7 +101,11 @@ func (method Method) tupleUnpack(v interface{}, output []byte) error {
var (
value = valueOf.Elem()
typ = value.Type()
+ kind = value.Kind()
)
+ if err := requireUnpackKind(value, typ, kind, method.Outputs, false); err != nil {
+ return err
+ }
j := 0
for i := 0; i < len(method.Outputs); i++ {
@@ -117,7 +121,7 @@ func (method Method) tupleUnpack(v interface{}, output []byte) error {
}
reflectValue := reflect.ValueOf(marshalledValue)
- switch value.Kind() {
+ switch kind {
case reflect.Struct:
for j := 0; j < typ.NumField(); j++ {
field := typ.Field(j)
@@ -129,19 +133,13 @@ func (method Method) tupleUnpack(v interface{}, output []byte) error {
}
}
case reflect.Slice, reflect.Array:
- if value.Len() < i {
- return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(method.Outputs), value.Len())
- }
v := value.Index(i)
- if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface {
- return fmt.Errorf("abi: cannot unmarshal %v in to %v", v.Type(), reflectValue.Type())
+ if err := requireAssignable(v, reflectValue); err != nil {
+ return err
}
- reflectValue := reflect.ValueOf(marshalledValue)
if err := set(v.Elem(), reflectValue, method.Outputs[i]); err != nil {
return err
}
- default:
- return fmt.Errorf("abi: cannot unmarshal tuple in to %v", typ)
}
}
return nil
diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go
index e953b77c1..fbcd576e5 100644
--- a/accounts/abi/reflect.go
+++ b/accounts/abi/reflect.go
@@ -85,3 +85,11 @@ func set(dst, src reflect.Value, output Argument) error {
}
return nil
}
+
+// requireAssignable assures that `dest` is a pointer and it's not an interface.
+func requireAssignable(dst, src reflect.Value) error {
+ if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface {
+ return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type())
+ }
+ return nil
+}
diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go
index 051fc1916..5adb91ff7 100644
--- a/accounts/abi/unpack.go
+++ b/accounts/abi/unpack.go
@@ -202,4 +202,4 @@ func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err
//fmt.Printf("LENGTH PREFIX INFO: \nsize: %v\noffset: %v\nstart: %v\n", length, offset, start)
return
-}
+} \ No newline at end of file