Calldata validation tests

This commit is contained in:
wechman 2022-07-22 10:16:04 +02:00
parent 3c0a7355d0
commit d066dd2bc0
7 changed files with 304 additions and 15 deletions

View File

@ -0,0 +1,27 @@
pragma abicoder v2;
contract C {
function f(uint[][] calldata a) public returns (uint[][] memory) {
return a;
}
function g(uint[][][] calldata a) public returns (uint[][][] memory) {
return a;
}
function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {
return a;
}
}
// ====
// compileViaYul: also
// ----
// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8
// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8
// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE
// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8
// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE
// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8
// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8
// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE

View File

@ -1,22 +1,37 @@
pragma abicoder v2;
contract C {
function h(uint[][] calldata a) public {
abi.encode(a);
}
struct S { uint[] x; }
function f(S calldata a) public {
abi.encode(a);
}
function f(uint[][] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function g(uint8[][][] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function h(uint16[][2][] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function i(uint16[][][1] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function j(uint16[2][][] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
}
// ====
// revertStrings: debug
// compileViaYul: also
// ----
// h(uint256[][]): 0x20, 1, 0x20, 0 ->
// h(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// h(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// h(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// f((uint256[])): 0x20, 0x20, 0 ->
// f((uint256[])): 0x20, 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// f((uint256[])): 0x20, 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// f((uint256[])): 0x20, 0x20, 3 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0
// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0
// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access offset"
// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0
// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0
// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13
// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12
// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"
// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15
// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride"

View File

@ -0,0 +1,43 @@
pragma abicoder v2;
contract C {
uint[] s;
uint[2] n;
function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {
return (a, b);
}
function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {
return abi.encode(a, b);
}
function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {
return abi.encode(a[which], b[1]);
}
function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {
s = a;
n = b;
return abi.encode(s);
}
}
// ====
// compileViaYul: also
// ----
// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2
// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6
// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE
// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2
// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6
// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE
// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2
// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2
// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE
// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2
// gas irOptimized: 111653
// gas legacy: 112987
// gas legacyOptimized: 112104
// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6
// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE

View File

@ -0,0 +1,37 @@
pragma abicoder v2;
contract C {
uint[] s;
uint[2] n;
function f_memory(uint[][] calldata a) public returns (uint[][] memory) {
return a;
}
function f_encode(uint[][] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {
return a[which];
}
}
// ====
// compileViaYul: also
// ----
// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2
// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2
// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2
// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE
// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2
// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2
// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2
// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE
// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2
// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2
// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2
// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2
// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0
// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2
// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE

View File

@ -0,0 +1,56 @@
pragma abicoder v2;
contract C {
struct D { uint[] x; }
struct S { uint x; }
function f(D calldata a) public returns (bytes memory){
return abi.encode(a);
}
function g(D[2] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function h(D[][] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function i(D[2][] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function j(S[] memory a) public returns (bytes memory) {
return abi.encode(a);
}
function k(S[2] memory a) public returns (bytes memory) {
return abi.encode(a);
}
function l(S[][] memory a) public returns (bytes memory) {
return abi.encode(a);
}
}
// ====
// compileViaYul: also
// ----
// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0
// f((uint256[])): 0x20, 0x20, 1 -> FAILURE
// f((uint256[])): 0x20, 0x20, 2 -> FAILURE
// f((uint256[])): 0x20, 0x20, 3 -> FAILURE
// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3
// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE
// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1
// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE
// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3
// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE
// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2
// j((uint256)[]): 0x20, 2, 1 -> FAILURE
// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2
// k((uint256)[2]): 1 -> FAILURE
// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9
// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9
// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE

View File

@ -0,0 +1,42 @@
pragma abicoder v2;
contract C {
struct S { uint[] a; }
function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {
return abi.encode(s[i][j]);
}
function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {
return abi.encode(s[i][j][k]);
}
function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {
return abi.encode(s[0][i]);
}
function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {
return abi.encode(s[i][j].a);
}
function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {
return abi.encode(s[i][j].a);
}
}
// ====
// compileViaYul: also
// revertStrings: debug
// ----
// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7
// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8
// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4
// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6
// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex"4e487b71", 0x32
// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex"4e487b71", 0x32
// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9
// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex"4e487b71", 0x32
// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6
// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex"4e487b71", 0x32
// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9
// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex"4e487b71", 0x32

View File

@ -0,0 +1,69 @@
pragma abicoder v2;
contract C {
uint[] aTmp;
uint[2] bTmp;
function f_memory(uint[] calldata a) public returns (uint[] memory) {
return a;
}
function f_encode(uint[] calldata a) public returns (bytes memory) {
return abi.encode(a);
}
function f_storage(uint[] calldata a) public returns (bytes memory) {
aTmp = a;
return abi.encode(aTmp);
}
function f_index(uint[] calldata a, uint which) public returns (uint) {
return a[which];
}
function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {
return (a, b);
}
function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {
return abi.encode(a, b);
}
function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {
aTmp = a;
bTmp = b;
return abi.encode(aTmp, bTmp);
}
function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {
return (a[which], b[0]);
}
}
// ====
// compileViaYul: also
// ----
// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0
// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7
// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE
// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0
// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7
// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE
// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0
// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7
// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE
// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7
// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8
// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex"4e487b71", 0x32
// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0
// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7
// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE
// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0
// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7
// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE
// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0
// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7
// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE
// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1
// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1
// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE