Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
a306e17a
Commit
a306e17a
authored
Mar 31, 2016
by
Jeffrey Wilcke
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
abi: removed implicit type casting & refactored type parsing
parent
968d8ffe
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
80 additions
and
53 deletions
+80
-53
abi.go
accounts/abi/abi.go
+1
-1
abi_test.go
accounts/abi/abi_test.go
+22
-11
type.go
accounts/abi/type.go
+57
-41
No files found.
accounts/abi/abi.go
View file @
a306e17a
...
...
@@ -186,7 +186,7 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
// argument in T.
func
toGoType
(
i
int
,
t
Argument
,
output
[]
byte
)
(
interface
{},
error
)
{
// we need to treat slices differently
if
t
.
Type
.
Kind
==
reflect
.
Slice
{
if
t
.
Type
.
Is
Slice
{
return
toGoSlice
(
i
,
t
,
output
)
}
...
...
accounts/abi/abi_test.go
View file @
a306e17a
...
...
@@ -59,7 +59,7 @@ func TestType(t *testing.T) {
if
err
!=
nil
{
t
.
Error
(
err
)
}
if
typ
.
Kind
!=
reflect
.
Ptr
{
if
typ
.
Kind
!=
reflect
.
Uint
{
t
.
Error
(
"expected uint32 to have kind Ptr"
)
}
...
...
@@ -67,8 +67,8 @@ func TestType(t *testing.T) {
if
err
!=
nil
{
t
.
Error
(
err
)
}
if
typ
.
Kind
!=
reflect
.
Slice
{
t
.
Error
(
"expected uint32[] to
have typ
e slice"
)
if
!
typ
.
Is
Slice
{
t
.
Error
(
"expected uint32[] to
b
e slice"
)
}
if
typ
.
Type
!=
ubig_t
{
t
.
Error
(
"expcted uith32[] to have type uint64"
)
...
...
@@ -78,13 +78,13 @@ func TestType(t *testing.T) {
if
err
!=
nil
{
t
.
Error
(
err
)
}
if
typ
.
Kind
!=
reflect
.
Slice
{
t
.
Error
(
"expected uint32[2] to
have kind
slice"
)
if
!
typ
.
Is
Slice
{
t
.
Error
(
"expected uint32[2] to
be
slice"
)
}
if
typ
.
Type
!=
ubig_t
{
t
.
Error
(
"expcted uith32[2] to have type uint64"
)
}
if
typ
.
Size
!=
2
{
if
typ
.
S
liceS
ize
!=
2
{
t
.
Error
(
"expected uint32[2] to have a size of 2"
)
}
}
...
...
@@ -149,10 +149,6 @@ func TestTestNumbers(t *testing.T) {
t
.
Errorf
(
"expected send( ptr ) to throw, requires *big.Int instead of *int"
)
}
if
_
,
err
:=
abi
.
Pack
(
"send"
,
1000
);
err
!=
nil
{
t
.
Error
(
"expected send(1000) to cast to big"
)
}
if
_
,
err
:=
abi
.
Pack
(
"test"
,
uint32
(
1000
));
err
!=
nil
{
t
.
Error
(
err
)
}
...
...
@@ -204,7 +200,7 @@ func TestTestSlice(t *testing.T) {
t
.
FailNow
()
}
slice
:=
make
([]
byte
,
2
)
slice
:=
make
([]
uint64
,
2
)
if
_
,
err
:=
abi
.
Pack
(
"uint64[2]"
,
slice
);
err
!=
nil
{
t
.
Error
(
err
)
}
...
...
@@ -214,6 +210,21 @@ func TestTestSlice(t *testing.T) {
}
}
func
TestImplicitTypeCasts
(
t
*
testing
.
T
)
{
abi
,
err
:=
JSON
(
strings
.
NewReader
(
jsondata2
))
if
err
!=
nil
{
t
.
Error
(
err
)
t
.
FailNow
()
}
slice
:=
make
([]
uint8
,
2
)
_
,
err
=
abi
.
Pack
(
"uint64[2]"
,
slice
)
expStr
:=
"`uint64[2]` abi: cannot use type uint8 as type uint64"
if
err
.
Error
()
!=
expStr
{
t
.
Errorf
(
"expected %v, got %v"
,
expStr
,
err
)
}
}
func
TestMethodSignature
(
t
*
testing
.
T
)
{
String
,
_
:=
NewType
(
"string"
)
String32
,
_
:=
NewType
(
"string32"
)
...
...
accounts/abi/type.go
View file @
a306e17a
...
...
@@ -40,6 +40,9 @@ const (
// Type is the reflection of the supported argument type
type
Type
struct
{
IsSlice
bool
SliceSize
int
Kind
reflect
.
Kind
Type
reflect
.
Type
Size
int
...
...
@@ -47,6 +50,11 @@ type Type struct {
stringKind
string
// holds the unparsed string for deriving signatures
}
var
(
fullTypeRegex
=
regexp
.
MustCompile
(
"([a-zA-Z0-9]+)(
\\
[([0-9]*)?
\\
])?"
)
typeRegex
=
regexp
.
MustCompile
(
"([a-zA-Z]+)([0-9]*)?"
)
)
// NewType returns a fully parsed Type given by the input string or an error if it can't be parsed.
//
// Strings can be in the format of:
...
...
@@ -61,51 +69,54 @@ type Type struct {
// address int256 uint256 real[2]
func
NewType
(
t
string
)
(
typ
Type
,
err
error
)
{
// 1. full string 2. type 3. (opt.) is slice 4. (opt.) size
freg
,
err
:=
regexp
.
Compile
(
"([a-zA-Z0-9]+)(
\\
[([0-9]*)?
\\
])?"
)
if
err
!=
nil
{
return
Type
{},
err
}
res
:=
freg
.
FindAllStringSubmatch
(
t
,
-
1
)[
0
]
var
(
isslice
bool
size
int
)
// parse the full representation of the abi-type definition; including:
// * full string
// * type
// * is slice
// * slice size
res
:=
fullTypeRegex
.
FindAllStringSubmatch
(
t
,
-
1
)[
0
]
// check if type is slice and parse type.
switch
{
case
res
[
3
]
!=
""
:
// err is ignored. Already checked for number through the regexp
s
ize
,
_
=
strconv
.
Atoi
(
res
[
3
])
iss
lice
=
true
typ
.
SliceS
ize
,
_
=
strconv
.
Atoi
(
res
[
3
])
typ
.
IsS
lice
=
true
case
res
[
2
]
!=
""
:
isslice
=
true
size
=
-
1
typ
.
IsSlice
,
typ
.
SliceSize
=
true
,
-
1
case
res
[
0
]
==
""
:
return
Type
{},
fmt
.
Errorf
(
"
type parse error for `%s`
"
,
t
)
return
Type
{},
fmt
.
Errorf
(
"
abi: type parse error: %s
"
,
t
)
}
treg
,
err
:=
regexp
.
Compile
(
"([a-zA-Z]+)([0-9]*)?"
)
if
err
!=
nil
{
return
Type
{},
err
// parse the type and size of the abi-type.
parsedType
:=
typeRegex
.
FindAllStringSubmatch
(
res
[
1
],
-
1
)[
0
]
// varSize is the size of the variable
var
varSize
int
if
len
(
parsedType
[
2
])
>
0
{
var
err
error
varSize
,
err
=
strconv
.
Atoi
(
parsedType
[
2
])
if
err
!=
nil
{
return
Type
{},
fmt
.
Errorf
(
"abi: error parsing variable size: %v"
,
err
)
}
}
parsedType
:=
treg
.
FindAllStringSubmatch
(
res
[
1
],
-
1
)[
0
]
vsize
,
_
:=
strconv
.
Atoi
(
parsedType
[
2
])
vtype
:=
parsedType
[
1
]
// substitute canonical representation
if
vsize
==
0
&&
(
vtype
==
"int"
||
vtype
==
"uint"
)
{
vsize
=
256
// varType is the parsed abi type
varType
:=
parsedType
[
1
]
// substitute canonical integer
if
varSize
==
0
&&
(
varType
==
"int"
||
varType
==
"uint"
)
{
varSize
=
256
t
+=
"256"
}
switch
v
t
ype
{
switch
v
arT
ype
{
case
"int"
:
typ
.
Kind
=
reflect
.
Ptr
typ
.
Kind
=
reflect
.
Int
typ
.
Type
=
big_t
typ
.
Size
=
256
typ
.
Size
=
varSize
typ
.
T
=
IntTy
case
"uint"
:
typ
.
Kind
=
reflect
.
Ptr
typ
.
Kind
=
reflect
.
Uint
typ
.
Type
=
ubig_t
typ
.
Size
=
256
typ
.
Size
=
varSize
typ
.
T
=
UintTy
case
"bool"
:
typ
.
Kind
=
reflect
.
Bool
...
...
@@ -120,7 +131,7 @@ func NewType(t string) (typ Type, err error) {
typ
.
Kind
=
reflect
.
String
typ
.
Size
=
-
1
typ
.
T
=
StringTy
if
v
s
ize
>
0
{
if
v
arS
ize
>
0
{
typ
.
Size
=
32
}
case
"hash"
:
...
...
@@ -131,8 +142,8 @@ func NewType(t string) (typ Type, err error) {
case
"bytes"
:
typ
.
Kind
=
reflect
.
Array
typ
.
Type
=
byte_ts
typ
.
Size
=
v
s
ize
if
v
s
ize
==
0
{
typ
.
Size
=
v
arS
ize
if
v
arS
ize
==
0
{
typ
.
T
=
BytesTy
}
else
{
typ
.
T
=
FixedBytesTy
...
...
@@ -140,13 +151,6 @@ func NewType(t string) (typ Type, err error) {
default
:
return
Type
{},
fmt
.
Errorf
(
"unsupported arg type: %s"
,
t
)
}
// if the type is a slice we must set Kind to a reflect.Slice
// so that serialisation can be determined based on this kind.
if
isslice
{
typ
.
Kind
=
reflect
.
Slice
typ
.
Size
=
size
}
typ
.
stringKind
=
t
return
...
...
@@ -173,14 +177,26 @@ func (t Type) pack(v interface{}) ([]byte, error) {
value
:=
reflect
.
ValueOf
(
v
)
switch
kind
:=
value
.
Kind
();
kind
{
case
reflect
.
Uint
,
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
:
// check input is unsigned
if
t
.
Type
!=
ubig_t
{
return
nil
,
fmt
.
Errorf
(
"type mismatch: %s for %T"
,
t
.
Type
,
v
)
return
nil
,
fmt
.
Errorf
(
"abi: type mismatch: %s for %T"
,
t
.
Type
,
v
)
}
// no implicit type casting
if
int
(
value
.
Type
()
.
Size
()
*
8
)
!=
t
.
Size
{
return
nil
,
fmt
.
Errorf
(
"abi: cannot use type %T as type uint%d"
,
v
,
t
.
Size
)
}
return
packNum
(
value
,
t
.
T
),
nil
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
if
t
.
Type
!=
ubig_t
{
return
nil
,
fmt
.
Errorf
(
"type mismatch: %s for %T"
,
t
.
Type
,
v
)
}
// no implicit type casting
if
int
(
value
.
Type
()
.
Size
()
*
8
)
!=
t
.
Size
{
return
nil
,
fmt
.
Errorf
(
"abi: cannot use type %T as type uint%d"
,
v
,
t
.
Size
)
}
return
packNum
(
value
,
t
.
T
),
nil
case
reflect
.
Ptr
:
// If the value is a ptr do a assign check (only used by
...
...
@@ -201,7 +217,7 @@ func (t Type) pack(v interface{}) ([]byte, error) {
return
packBytesSlice
(
value
.
Bytes
(),
value
.
Len
()),
nil
}
if
t
.
S
ize
>
-
1
&&
value
.
Len
()
>
t
.
Size
{
if
t
.
S
liceSize
>
-
1
&&
value
.
Len
()
>
t
.
Slice
Size
{
return
nil
,
fmt
.
Errorf
(
"%v out of bound. %d for %d"
,
value
.
Kind
(),
value
.
Len
(),
t
.
Size
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment