Fix crash when passing zero to bytes.concat()

This commit is contained in:
Kamil Śliwak 2021-06-25 20:13:59 +02:00
parent cbf1c3ae69
commit ca0b1bf3f3
9 changed files with 127 additions and 0 deletions

View File

@ -8,6 +8,7 @@ Compiler Features:
Bugfixes:
* Code Generator: Fix internal compiler error when calling functions bound to calldata structs and arrays.
* Code Generator: Fix internal compiler error when passing zero to ``bytes.concat()``.
* Type Checker: Fix internal error and prevent static calls to unimplemented modifiers.

View File

@ -1086,6 +1086,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
literalType && literalType->value().size() <= 32
)
targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
else if (auto const* literalType = dynamic_cast<RationalNumberType const*>(argument->annotation().type))
{
solAssert(literalType->value() == 0, "");
targetTypes.emplace_back(TypeProvider::fixedBytes(1));
}
else
{
solAssert(argument->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");

View File

@ -2476,6 +2476,11 @@ string YulUtilFunctions::bytesConcatFunction(vector<Type const*> const& _argumen
literalType && literalType->value().size() <= 32
)
targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
else if (auto const* literalType = dynamic_cast<RationalNumberType const*>(argumentType))
{
solAssert(literalType->value() == 0, "");
targetTypes.emplace_back(TypeProvider::fixedBytes(1));
}
else
{
solAssert(argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");

View File

@ -0,0 +1,15 @@
contract C {
function f() public returns (bytes memory) {
return bytes.concat(0, -0, 0.0, -0.0, 0e10, 0e-10, 0x00, (0));
}
function g() public returns (bytes memory) {
return bytes.concat(0, "abc", 0, "abc", 0);
}
}
// ====
// compileViaYul: also
// compileToEwasm: also
// ----
// f() -> 0x20, 8, "\0\0\0\0\0\0\0\0"
// g() -> 0x20, 9, "\0abc\0abc\0"

View File

@ -0,0 +1,6 @@
contract C {
function f() public pure {
bytes.concat(0, -0, 0.0, -0.0, 0e10, 0e-10, (0), 0x00, hex"00", unicode"abc", "abc");
}
}
// ----

View File

@ -0,0 +1,7 @@
contract C {
function f() public {
bytes.concat([], [], []);
}
}
// ----
// TypeError 6378: (60-62): Unable to deduce common type for array elements.

View File

@ -0,0 +1,40 @@
contract C {
struct S {
uint x;
}
enum E {A, B, C}
mapping(uint => E) m;
function f() public {
bool b;
uint u;
uint8 u8;
address a;
address payable ap;
function () external fext;
function () internal fint;
uint[] memory uDynamic;
uint[2] memory uStatic;
C c;
S memory s;
E e;
bytes.concat(b, u, u8, a, ap, fext, fint, uDynamic, uStatic, c, s, e, m);
}
}
// ----
// TypeError 8015: (425-426): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bool provided.
// TypeError 8015: (428-429): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256 provided.
// TypeError 8015: (431-433): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.
// TypeError 8015: (435-436): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address provided.
// TypeError 8015: (438-440): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address payable provided.
// TypeError 8015: (442-446): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () external provided.
// TypeError 8015: (448-452): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.
// TypeError 8015: (454-462): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[] provided.
// TypeError 8015: (464-471): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[2] provided.
// TypeError 8015: (473-474): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but contract C provided.
// TypeError 8015: (476-477): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S provided.
// TypeError 8015: (479-480): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but enum C.E provided.
// TypeError 8015: (482-483): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but mapping(uint256 => enum C.E) provided.

View File

@ -0,0 +1,48 @@
contract C {
struct S {
uint x;
}
enum E {A, B, C}
function f() public {
bytes.concat(
false,
1,
1e10,
1e-10,
0.1,
0x11112222333344445555666677778888999900, // One byte less than an address
0x1111222233334444555566667777888899990000, // Address
0x111122223333444455556666777788889999000011, // One byte more than an address
f,
(),
(0, 0),
[0],
[0][:],
[0][0],
new C(),
S(0),
E.A
);
}
}
// ----
// TypeError 1227: (540-546): Index range access is only supported for dynamic calldata arrays.
// TypeError 8015: (133-138): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bool provided.
// TypeError 8015: (152-153): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 1 provided.
// TypeError 8015: (167-171): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 10000000000 provided.
// TypeError 8015: (185-190): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but rational_const 1 / 10000000000 provided.
// TypeError 8015: (204-207): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but rational_const 1 / 10 provided.
// TypeError 8015: (221-261): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 3806...(37 digits omitted)...1680 provided.
// TypeError 8015: (312-354): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address provided.
// TypeError 8015: (381-425): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 2494...(42 digits omitted)...0497 provided.
// TypeError 8015: (472-473): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.
// TypeError 8015: (487-489): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple() provided.
// TypeError 8015: (503-509): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple(int_const 0,int_const 0) provided.
// TypeError 8015: (523-526): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] provided.
// TypeError 8015: (540-546): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] slice provided.
// TypeError 8015: (560-566): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.
// TypeError 8015: (580-587): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but contract C provided.
// TypeError 8015: (601-605): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S provided.
// TypeError 8015: (619-622): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but enum C.E provided.