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
73534343
Commit
73534343
authored
Dec 28, 2018
by
weimumu
Committed by
Guillaume Ballet
Dec 28, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix string array unpack bug in accounts/abi (#18364)
parent
9e9fc87e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
69 additions
and
1 deletion
+69
-1
argument.go
accounts/abi/argument.go
+1
-1
unpack.go
accounts/abi/unpack.go
+7
-0
unpack_test.go
accounts/abi/unpack_test.go
+61
-0
No files found.
accounts/abi/argument.go
View file @
73534343
...
...
@@ -202,7 +202,7 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) {
virtualArgs
:=
0
for
index
,
arg
:=
range
arguments
.
NonIndexed
()
{
marshalledValue
,
err
:=
toGoType
((
index
+
virtualArgs
)
*
32
,
arg
.
Type
,
data
)
if
arg
.
Type
.
T
==
ArrayTy
{
if
arg
.
Type
.
T
==
ArrayTy
&&
(
*
arg
.
Type
.
Elem
)
.
T
!=
StringTy
{
// If we have a static array, like [3]uint256, these are coded as
// just like uint256,uint256,uint256.
// This means that we need to add two 'virtual' arguments when
...
...
accounts/abi/unpack.go
View file @
73534343
...
...
@@ -195,8 +195,15 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) {
switch
t
.
T
{
case
SliceTy
:
if
(
*
t
.
Elem
)
.
T
==
StringTy
{
return
forEachUnpack
(
t
,
output
[
begin
:
],
0
,
end
)
}
return
forEachUnpack
(
t
,
output
,
begin
,
end
)
case
ArrayTy
:
if
(
*
t
.
Elem
)
.
T
==
StringTy
{
offset
:=
int64
(
binary
.
BigEndian
.
Uint64
(
returnOutput
[
len
(
returnOutput
)
-
8
:
]))
return
forEachUnpack
(
t
,
output
[
offset
:
],
0
,
t
.
Size
)
}
return
forEachUnpack
(
t
,
output
,
index
,
t
.
Size
)
case
StringTy
:
// variable arrays are written at the end of the return bytes
return
string
(
output
[
begin
:
begin
+
end
]),
nil
...
...
accounts/abi/unpack_test.go
View file @
73534343
...
...
@@ -241,6 +241,16 @@ var unpackTests = []unpackTest{
enc
:
"000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"
,
want
:
[
3
]
*
big
.
Int
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
),
big
.
NewInt
(
3
)},
},
{
def
:
`[{"type": "string[4]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000548656c6c6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005576f726c64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b476f2d657468657265756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000"
,
want
:
[
4
]
string
{
"Hello"
,
"World"
,
"Go-ethereum"
,
"Ethereum"
},
},
{
def
:
`[{"type": "string[]"}]`
,
enc
:
"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b676f2d657468657265756d000000000000000000000000000000000000000000"
,
want
:
[]
string
{
"Ethereum"
,
"go-ethereum"
},
},
{
def
:
`[{"type": "int8[]"}]`
,
enc
:
"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"
,
...
...
@@ -516,6 +526,57 @@ func TestMultiReturnWithArray(t *testing.T) {
}
}
func
TestMultiReturnWithStringArray
(
t
*
testing
.
T
)
{
const
definition
=
`[{"name" : "multi", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
buff
:=
new
(
bytes
.
Buffer
)
buff
.
Write
(
common
.
Hex2Bytes
(
"000000000000000000000000000000000000000000000000000000005c1b78ea0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000001a055690d9db80000000000000000000000000000ab1257528b3782fb40d7ed5f72e624b744dffb2f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001048656c6c6f2c20457468657265756d2100000000000000000000000000000000"
))
temp
,
_
:=
big
.
NewInt
(
0
)
.
SetString
(
"30000000000000000000"
,
10
)
ret1
,
ret1Exp
:=
new
([
3
]
*
big
.
Int
),
[
3
]
*
big
.
Int
{
big
.
NewInt
(
1545304298
),
big
.
NewInt
(
6
),
temp
}
ret2
,
ret2Exp
:=
new
(
common
.
Address
),
common
.
HexToAddress
(
"ab1257528b3782fb40d7ed5f72e624b744dffb2f"
)
ret3
,
ret3Exp
:=
new
([
2
]
string
),
[
2
]
string
{
"Ethereum"
,
"Hello, Ethereum!"
}
ret4
,
ret4Exp
:=
new
(
bool
),
false
if
err
:=
abi
.
Unpack
(
&
[]
interface
{}{
ret1
,
ret2
,
ret3
,
ret4
},
"multi"
,
buff
.
Bytes
());
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
reflect
.
DeepEqual
(
*
ret1
,
ret1Exp
)
{
t
.
Error
(
"big.Int array result"
,
*
ret1
,
"!= Expected"
,
ret1Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret2
,
ret2Exp
)
{
t
.
Error
(
"address result"
,
*
ret2
,
"!= Expected"
,
ret2Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret3
,
ret3Exp
)
{
t
.
Error
(
"string array result"
,
*
ret3
,
"!= Expected"
,
ret3Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret4
,
ret4Exp
)
{
t
.
Error
(
"bool result"
,
*
ret4
,
"!= Expected"
,
ret4Exp
)
}
}
func
TestMultiReturnWithStringSlice
(
t
*
testing
.
T
)
{
const
definition
=
`[{"name" : "multi", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
buff
:=
new
(
bytes
.
Buffer
)
buff
.
Write
(
common
.
Hex2Bytes
(
"000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008657468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b676f2d657468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000065"
))
ret1
,
ret1Exp
:=
new
([]
string
),
[]
string
{
"ethereum"
,
"go-ethereum"
}
ret2
,
ret2Exp
:=
new
([]
*
big
.
Int
),
[]
*
big
.
Int
{
big
.
NewInt
(
100
),
big
.
NewInt
(
101
)}
if
err
:=
abi
.
Unpack
(
&
[]
interface
{}{
ret1
,
ret2
},
"multi"
,
buff
.
Bytes
());
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
reflect
.
DeepEqual
(
*
ret1
,
ret1Exp
)
{
t
.
Error
(
"string slice result"
,
*
ret1
,
"!= Expected"
,
ret1Exp
)
}
if
!
reflect
.
DeepEqual
(
*
ret2
,
ret2Exp
)
{
t
.
Error
(
"uint256 slice result"
,
*
ret2
,
"!= Expected"
,
ret2Exp
)
}
}
func
TestMultiReturnWithDeeplyNestedArray
(
t
*
testing
.
T
)
{
// Similar to TestMultiReturnWithArray, but with a special case in mind:
// values of nested static arrays count towards the size as well, and any element following
...
...
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