aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi/unpack_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/abi/unpack_test.go')
-rw-r--r--accounts/abi/unpack_test.go117
1 files changed, 116 insertions, 1 deletions
diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go
index a65426a30..ee6256709 100644
--- a/accounts/abi/unpack_test.go
+++ b/accounts/abi/unpack_test.go
@@ -130,7 +130,7 @@ var unpackTests = []unpackTest{
{
def: `[{"type": "bytes32"}]`,
enc: "0100000000000000000000000000000000000000000000000000000000000000",
- want: common.HexToHash("0100000000000000000000000000000000000000000000000000000000000000"),
+ want: [32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
def: `[{"type": "function"}]`,
@@ -190,6 +190,11 @@ var unpackTests = []unpackTest{
want: [2]uint32{1, 2},
},
{
+ def: `[{"type": "uint32[2][3][4]"}]`,
+ enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000018",
+ want: [4][3][2]uint32{{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}},
+ },
+ {
def: `[{"type": "uint64[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []uint64{1, 2},
@@ -435,6 +440,46 @@ func TestMultiReturnWithArray(t *testing.T) {
}
}
+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
+ // after such nested array argument should be read with the correct offset,
+ // so that it does not read content from the previous array argument.
+ const definition = `[{"name" : "multi", "outputs": [{"type": "uint64[3][2][4]"}, {"type": "uint64"}]}]`
+ abi, err := JSON(strings.NewReader(definition))
+ if err != nil {
+ t.Fatal(err)
+ }
+ buff := new(bytes.Buffer)
+ // construct the test array, each 3 char element is joined with 61 '0' chars,
+ // to from the ((3 + 61) * 0.5) = 32 byte elements in the array.
+ buff.Write(common.Hex2Bytes(strings.Join([]string{
+ "", //empty, to apply the 61-char separator to the first element as well.
+ "111", "112", "113", "121", "122", "123",
+ "211", "212", "213", "221", "222", "223",
+ "311", "312", "313", "321", "322", "323",
+ "411", "412", "413", "421", "422", "423",
+ }, "0000000000000000000000000000000000000000000000000000000000000")))
+ buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000009876"))
+
+ ret1, ret1Exp := new([4][2][3]uint64), [4][2][3]uint64{
+ {{0x111, 0x112, 0x113}, {0x121, 0x122, 0x123}},
+ {{0x211, 0x212, 0x213}, {0x221, 0x222, 0x223}},
+ {{0x311, 0x312, 0x313}, {0x321, 0x322, 0x323}},
+ {{0x411, 0x412, 0x413}, {0x421, 0x422, 0x423}},
+ }
+ ret2, ret2Exp := new(uint64), uint64(0x9876)
+ if err := abi.Unpack(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(*ret1, ret1Exp) {
+ t.Error("array result", *ret1, "!= Expected", ret1Exp)
+ }
+ if *ret2 != ret2Exp {
+ t.Error("int result", *ret2, "!= Expected", ret2Exp)
+ }
+}
+
func TestUnmarshal(t *testing.T) {
const definition = `[
{ "name" : "int", "constant" : false, "outputs": [ { "type": "uint256" } ] },
@@ -683,3 +728,73 @@ func TestUnmarshal(t *testing.T) {
t.Fatal("expected error:", err)
}
}
+
+func TestOOMMaliciousInput(t *testing.T) {
+ oomTests := []unpackTest{
+ {
+ def: `[{"type": "uint8[]"}]`,
+ enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset
+ "0000000000000000000000000000000000000000000000000000000000000003" + // num elems
+ "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1
+ "0000000000000000000000000000000000000000000000000000000000000002", // elem 2
+ },
+ { // Length larger than 64 bits
+ def: `[{"type": "uint8[]"}]`,
+ enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset
+ "00ffffffffffffffffffffffffffffffffffffffffffffff0000000000000002" + // num elems
+ "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1
+ "0000000000000000000000000000000000000000000000000000000000000002", // elem 2
+ },
+ { // Offset very large (over 64 bits)
+ def: `[{"type": "uint8[]"}]`,
+ enc: "00ffffffffffffffffffffffffffffffffffffffffffffff0000000000000020" + // offset
+ "0000000000000000000000000000000000000000000000000000000000000002" + // num elems
+ "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1
+ "0000000000000000000000000000000000000000000000000000000000000002", // elem 2
+ },
+ { // Offset very large (below 64 bits)
+ def: `[{"type": "uint8[]"}]`,
+ enc: "0000000000000000000000000000000000000000000000007ffffffffff00020" + // offset
+ "0000000000000000000000000000000000000000000000000000000000000002" + // num elems
+ "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1
+ "0000000000000000000000000000000000000000000000000000000000000002", // elem 2
+ },
+ { // Offset negative (as 64 bit)
+ def: `[{"type": "uint8[]"}]`,
+ enc: "000000000000000000000000000000000000000000000000f000000000000020" + // offset
+ "0000000000000000000000000000000000000000000000000000000000000002" + // num elems
+ "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1
+ "0000000000000000000000000000000000000000000000000000000000000002", // elem 2
+ },
+
+ { // Negative length
+ def: `[{"type": "uint8[]"}]`,
+ enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset
+ "000000000000000000000000000000000000000000000000f000000000000002" + // num elems
+ "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1
+ "0000000000000000000000000000000000000000000000000000000000000002", // elem 2
+ },
+ { // Very large length
+ def: `[{"type": "uint8[]"}]`,
+ enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset
+ "0000000000000000000000000000000000000000000000007fffffffff000002" + // num elems
+ "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1
+ "0000000000000000000000000000000000000000000000000000000000000002", // elem 2
+ },
+ }
+ for i, test := range oomTests {
+ def := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def)
+ abi, err := JSON(strings.NewReader(def))
+ if err != nil {
+ t.Fatalf("invalid ABI definition %s: %v", def, err)
+ }
+ encb, err := hex.DecodeString(test.enc)
+ if err != nil {
+ t.Fatalf("invalid hex: %s" + test.enc)
+ }
+ _, err = abi.Methods["method"].Outputs.UnpackValues(encb)
+ if err == nil {
+ t.Fatalf("Expected error on malicious input, test %d", i)
+ }
+ }
+}