Skip to content

Commit eaac16c

Browse files
authored
Merge pull request #11590 from ethereum/disallow-non-hex-zero-and-fix-bytes32-literals-in-bytes-concat
Disallow non-hex zero literals and fix 32-byte hex literals in `bytes.concat()`
2 parents ccad22b + 6a50d08 commit eaac16c

File tree

9 files changed

+76
-45
lines changed

9 files changed

+76
-45
lines changed

Changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Compiler Features:
1212
Bugfixes:
1313
* Code Generator: Fix crash when passing an empty string literal to ``bytes.concat()``.
1414
* Code Generator: Fix internal compiler error when calling functions bound to calldata structs and arrays.
15-
* Code Generator: Fix internal compiler error when passing zero to ``bytes.concat()``.
15+
* Code Generator: Fix internal compiler error when passing a 32-byte hex literal or a zero literal to ``bytes.concat()`` by disallowing such literals.
1616
* Type Checker: Fix internal error and prevent static calls to unimplemented modifiers.
1717

1818

libsolidity/analysis/TypeChecker.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,18 +2033,22 @@ void TypeChecker::typeCheckBytesConcatFunction(
20332033
typeCheckFunctionGeneralChecks(_functionCall, _functionType);
20342034

20352035
for (shared_ptr<Expression const> const& argument: _functionCall.arguments())
2036-
if (
2037-
Type const* argumentType = type(*argument);
2036+
{
2037+
Type const* argumentType = type(*argument);
2038+
bool notConvertibleToBytes =
20382039
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::fixedBytes(32)) &&
2039-
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory())
2040-
)
2040+
!argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory());
2041+
bool numberLiteral = (dynamic_cast<RationalNumberType const*>(argumentType) != nullptr);
2042+
2043+
if (notConvertibleToBytes || numberLiteral)
20412044
m_errorReporter.typeError(
20422045
8015_error,
20432046
argument->location(),
20442047
"Invalid type for argument in the bytes.concat function call. "
20452048
"bytes or fixed bytes type is required, but " +
20462049
argumentType->toString(true) + " provided."
20472050
);
2051+
}
20482052
}
20492053

20502054
void TypeChecker::typeCheckFunctionGeneralChecks(

libsolidity/ast/Types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ class RationalNumberType: public Type
593593
private:
594594
rational m_value;
595595

596-
/// Bytes type to which the rational can be explicitly converted.
596+
/// Bytes type to which the rational can be implicitly converted.
597597
/// Empty for all rationals that are not directly parsed from hex literals.
598598
Type const* m_compatibleBytesType;
599599

libsolidity/codegen/ExpressionCompiler.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,13 +1086,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
10861086
literalType && !literalType->value().empty() && literalType->value().size() <= 32
10871087
)
10881088
targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
1089-
else if (auto const* literalType = dynamic_cast<RationalNumberType const*>(argument->annotation().type))
1090-
{
1091-
solAssert(literalType->value() == 0, "");
1092-
targetTypes.emplace_back(TypeProvider::fixedBytes(1));
1093-
}
10941089
else
10951090
{
1091+
solAssert(!dynamic_cast<RationalNumberType const*>(argument->annotation().type), "");
10961092
solAssert(argument->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");
10971093
targetTypes.emplace_back(TypeProvider::bytesMemory());
10981094
}

libsolidity/codegen/YulUtilFunctions.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2476,13 +2476,9 @@ string YulUtilFunctions::bytesConcatFunction(vector<Type const*> const& _argumen
24762476
literalType && !literalType->value().empty() && literalType->value().size() <= 32
24772477
)
24782478
targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));
2479-
else if (auto const* literalType = dynamic_cast<RationalNumberType const*>(argumentType))
2480-
{
2481-
solAssert(literalType->value() == 0, "");
2482-
targetTypes.emplace_back(TypeProvider::fixedBytes(1));
2483-
}
24842479
else
24852480
{
2481+
solAssert(!dynamic_cast<RationalNumberType const*>(argumentType), "");
24862482
solAssert(argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), "");
24872483
targetTypes.emplace_back(TypeProvider::bytesMemory());
24882484
}

test/libsolidity/semanticTests/array/concat/bytes_concat_zero.sol

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
contract C {
22
function f() public pure {
3-
bytes.concat(0, -0, 0.0, -0.0, 0e10, 0e-10, (0), 0x00, hex"00", unicode"abc", "abc");
3+
bytes.concat(
4+
hex"00",
5+
hex"aabbcc",
6+
unicode"abc",
7+
"123",
8+
"abc"
9+
"123456789012345678901234567890123456789012345678901234567890" // Longer than 32 bytes
10+
);
411
}
512
}
613
// ----

test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_misc_literals_and_expressions.sol

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ contract C {
1212
1e10,
1313
1e-10,
1414
0.1,
15+
0x1234567,
1516
0x11112222333344445555666677778888999900, // One byte less than an address
1617
0x1111222233334444555566667777888899990000, // Address
1718
0x111122223333444455556666777788889999000011, // One byte more than an address
19+
0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff, // exactly 32 bytes
20+
-0x0000000000000000000000000000000000000000000000000000000000000001, // exactly 32 bytes
21+
bytes(bytes32(0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff))[:],
1822
f,
1923
(),
2024
(0, 0),
@@ -28,21 +32,27 @@ contract C {
2832
}
2933
}
3034
// ----
31-
// TypeError 1227: (540-546): Index range access is only supported for dynamic calldata arrays.
35+
// TypeError 9640: (697-779): Explicit type conversion not allowed from "bytes32" to "bytes memory".
36+
// TypeError 1227: (697-782): Index range access is only supported for dynamic calldata arrays.
37+
// TypeError 1227: (864-870): Index range access is only supported for dynamic calldata arrays.
3238
// TypeError 8015: (133-138): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bool provided.
3339
// 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.
3440
// 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.
3541
// 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.
3642
// 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.
37-
// 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.
38-
// TypeError 8015: (312-354): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address provided.
39-
// 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.
40-
// TypeError 8015: (472-473): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.
41-
// TypeError 8015: (487-489): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple() provided.
42-
// 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.
43-
// 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.
44-
// 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.
45-
// TypeError 8015: (560-566): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.
46-
// 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.
47-
// 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.
48-
// 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.
43+
// 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.
44+
// 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.
45+
// TypeError 8015: (335-377): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address provided.
46+
// 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.
47+
// 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.
48+
// 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.
49+
// 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.
50+
// TypeError 8015: (796-797): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.
51+
// TypeError 8015: (811-813): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple() provided.
52+
// 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.
53+
// 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.
54+
// 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.
55+
// TypeError 8015: (884-890): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.
56+
// 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.
57+
// 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.
58+
// 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.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
contract C {
2+
function f() public pure {
3+
bytes.concat(
4+
0,
5+
-0,
6+
0.0,
7+
-0.0,
8+
0e10,
9+
-0e10,
10+
0e-10,
11+
-0e-10,
12+
(0),
13+
0x00,
14+
-0x00,
15+
0x0000000000000000000000000000000000000000000000000000000000000000, // exactly 32 bytes
16+
-0x0000000000000000000000000000000000000000000000000000000000000000 // exactly 32 bytes
17+
);
18+
}
19+
}
20+
// ----
21+
// 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.
22+
// 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.
23+
// 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.
24+
// 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.
25+
// 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.
26+
// 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.
27+
// 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.
28+
// 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.
29+
// 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.
30+
// 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.
31+
// 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.
32+
// 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.
33+
// 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.

0 commit comments

Comments
 (0)