Add assertions for the buggy parts of ABIEncoderV2.

This commit is contained in:
chriseth 2019-04-25 16:24:35 +02:00
parent 9861145ca8
commit f4aa92bf89
3 changed files with 27 additions and 66 deletions

View File

@ -4,6 +4,7 @@ Important Bugfixes:
* Code Generator: Fix initialization routine of uninitialized internal function pointers in constructor context.
Bugfixes:
* ABIEncoderV2: Refuse to generate code that is known to be potentially buggy.
* General: Split rule list such that JavaScript environments with small stacks can use the compiler.

View File

@ -679,6 +679,16 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
_encodeAsLibraryTypes,
false
));
solAssert(
inMemory ||
!_from.baseType()->isValueType() ||
(
_from.baseType()->category() == Type::Category::Integer &&
!dynamic_cast<IntegerType const&>(*_from.baseType()).isSigned()
) ||
_from.baseType()->storageBytes() == 32,
"You are using a buggy part of ABIEncoderV2. Please use a newer compiler version or disable ABIEncoderV2."
);
templ("arrayElementAccess", inMemory ? "mload(srcPtr)" : _from.baseType()->isValueType() ? "sload(srcPtr)" : "srcPtr" );
templ("nextArrayElement", nextArrayElementFunction(_from));
return templ.render();
@ -777,6 +787,12 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
}
else
{
// This function is not always a problem, but it can overwrite other data areas.
solAssert(
false,
"You are using a potentially buggy part of ABIEncoderV2. Please use a newer compiler version or disable ABIEncoderV2."
);
// Multiple items per slot
solAssert(_from.baseType()->storageBytes() <= 16, "");
solAssert(!_from.baseType()->isDynamicallyEncoded(), "");
@ -927,6 +943,16 @@ string ABIFunctions::abiEncodingFunctionStruct(
}
else
memberTempl("preprocess", "");
solAssert(
(
memberTypeFrom->category() == Type::Category::Integer &&
!dynamic_cast<IntegerType const&>(*memberTypeFrom).isSigned()
) ||
memberTypeFrom->storageBytes() == 32,
"You are using a potentially buggy part of ABIEncoderV2. Please use a newer compiler version or disable ABIEncoderV2."
);
memberTempl("retrieveValue", shiftRightFunction(intraSlotOffset * 8) + "(slotValue)");
}
else

View File

@ -293,34 +293,6 @@ BOOST_AUTO_TEST_CASE(storage_array_dyn)
)
}
BOOST_AUTO_TEST_CASE(storage_array_compact)
{
string sourceCode = R"(
contract C {
int72[] x;
event E(int72[]);
function f() public {
x.push(-1);
x.push(2);
x.push(-3);
x.push(4);
x.push(-5);
x.push(6);
x.push(-7);
x.push(8);
E(x);
}
}
)";
BOTH_ENCODERS(
compileAndRun(sourceCode);
callContractFunction("f()");
REQUIRE_LOG_DATA(encodeArgs(
0x20, 8, u256(-1), 2, u256(-3), 4, u256(-5), 6, u256(-7), 8
));
)
}
BOOST_AUTO_TEST_CASE(external_function)
{
string sourceCode = R"(
@ -412,44 +384,6 @@ BOOST_AUTO_TEST_CASE(function_name_collision)
)
}
BOOST_AUTO_TEST_CASE(structs)
{
string sourceCode = R"(
contract C {
struct S { uint16 a; uint16 b; T[] sub; uint16 c; }
struct T { uint64[2] x; }
S s;
event e(uint16, S);
function f() public returns (uint, S) {
uint16 x = 7;
s.a = 8;
s.b = 9;
s.c = 10;
s.sub.length = 3;
s.sub[0].x[0] = 11;
s.sub[1].x[0] = 12;
s.sub[2].x[1] = 13;
e(x, s);
return (x, s);
}
}
)";
NEW_ENCODER(
compileAndRun(sourceCode, 0, "C");
bytes encoded = encodeArgs(
u256(7), 0x40,
8, 9, 0x80, 10,
3,
11, 0,
12, 0,
0, 13
);
BOOST_CHECK(callContractFunction("f()") == encoded);
REQUIRE_LOG_DATA(encoded);
)
}
BOOST_AUTO_TEST_CASE(empty_struct)
{
string sourceCode = R"(