Fix ICE for 32-byte hex literals and zero literals in bytes.concat() by disallowing them

This commit is contained in:
Kamil Śliwak 2021-06-28 16:53:54 +02:00
parent 1d1d74bd0e
commit 6a50d088a0
8 changed files with 75 additions and 44 deletions

View File

@ -11,7 +11,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()``.
* Code Generator: Fix internal compiler error when passing a 32-byte hex literal or a zero literal to ``bytes.concat()`` by disallowing such literals.
* Type Checker: Fix internal error and prevent static calls to unimplemented modifiers.

View File

@ -2033,11 +2033,14 @@ void TypeChecker::typeCheckBytesConcatFunction(
typeCheckFunctionGeneralChecks(_functionCall, _functionType);
for (shared_ptr<Expression const> const& argument: _functionCall.arguments())
if (
Type const* argumentType = type(*argument);
{
Type const* argumentType = type(*argument);
bool notConvertibleToBytes =
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::fixedBytes(32)) &&
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory())
)
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory());
bool numberLiteral = (dynamic_cast<RationalNumberType const*>(argumentType) != nullptr);
if (notConvertibleToBytes || numberLiteral)
m_errorReporter.typeError(
8015_error,
argument->location(),
@ -2045,6 +2048,7 @@ void TypeChecker::typeCheckBytesConcatFunction(
"bytes or fixed bytes type is required, but " +
argumentType->toString(true) + " provided."
);
}
}
void TypeChecker::typeCheckFunctionGeneralChecks(

View File

@ -1086,13 +1086,9 @@ 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(!dynamic_cast<RationalNumberType const*>(argument->annotation().type), "");
solAssert(argument->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");
targetTypes.emplace_back(TypeProvider::bytesMemory());
}

View File

@ -2476,13 +2476,9 @@ 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(!dynamic_cast<RationalNumberType const*>(argumentType), "");
solAssert(argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");
targetTypes.emplace_back(TypeProvider::bytesMemory());
}

View File

@ -1,15 +0,0 @@
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

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

View File

@ -12,9 +12,13 @@ contract C {
1e10,
1e-10,
0.1,
0x1234567,
0x11112222333344445555666677778888999900, // One byte less than an address
0x1111222233334444555566667777888899990000, // Address
0x111122223333444455556666777788889999000011, // One byte more than an address
0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff, // exactly 32 bytes
-0x0000000000000000000000000000000000000000000000000000000000000001, // exactly 32 bytes
bytes(bytes32(0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff))[:],
f,
(),
(0, 0),
@ -28,21 +32,27 @@ contract C {
}
}
// ----
// TypeError 1227: (540-546): Index range access is only supported for dynamic calldata arrays.
// TypeError 9640: (697-779): Explicit type conversion not allowed from "bytes32" to "bytes memory".
// TypeError 1227: (697-782): Index range access is only supported for dynamic calldata arrays.
// TypeError 1227: (864-870): 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.
// TypeError 8015: (221-230): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 19088743 provided.
// TypeError 8015: (244-284): 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: (335-377): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address provided.
// TypeError 8015: (404-448): 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: (495-561): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 3027...(66 digits omitted)...5855 provided.
// TypeError 8015: (596-663): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const -1 provided.
// TypeError 8015: (697-782): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bytes slice provided.
// TypeError 8015: (796-797): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.
// TypeError 8015: (811-813): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple() provided.
// TypeError 8015: (827-833): 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: (847-850): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] provided.
// TypeError 8015: (864-870): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] slice provided.
// TypeError 8015: (884-890): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.
// TypeError 8015: (904-911): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but contract C provided.
// TypeError 8015: (925-929): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S provided.
// TypeError 8015: (943-946): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but enum C.E provided.

View File

@ -0,0 +1,33 @@
contract C {
function f() public pure {
bytes.concat(
0,
-0,
0.0,
-0.0,
0e10,
-0e10,
0e-10,
-0e-10,
(0),
0x00,
-0x00,
0x0000000000000000000000000000000000000000000000000000000000000000, // exactly 32 bytes
-0x0000000000000000000000000000000000000000000000000000000000000000 // exactly 32 bytes
);
}
}
// ----
// TypeError 8015: (78-79): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (93-95): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (109-112): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (126-130): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (144-148): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (162-167): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (181-186): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (200-206): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (220-223): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (237-241): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (255-260): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (274-340): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.
// TypeError 8015: (374-441): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.