mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix and updated test.
This commit is contained in:
parent
db27051024
commit
8cb01a9953
@ -1,5 +1,9 @@
|
||||
### 0.8.13 (unreleased)
|
||||
|
||||
Important Bugfixes:
|
||||
* Code Generator: Correctly encode literals used in ``abi.encodeCall`` in place of fixed bytes arguments.
|
||||
|
||||
|
||||
Language Features:
|
||||
* General: Allow annotating inline assembly as memory-safe to allow optimizations and stack limit evasion that rely on respecting Solidity's memory model.
|
||||
* General: ``using M for Type;`` is allowed at file level and ``M`` can now also be a brace-enclosed list of free functions or library functions.
|
||||
|
@ -1,4 +1,15 @@
|
||||
[
|
||||
{
|
||||
"uid": "SOL-2022-1",
|
||||
"name": "AbiEncodeCallLiteralAsFixedBytesBug",
|
||||
"summary": "Literals used for a fixed length bytes parameter in ``abi.encodeCall`` were encoded incorrectly.",
|
||||
"description": "For the encoding, the compiler only considered the types of the expressions in the second argument of ``abi.encodeCall`` itself, but not the parameter types of the function given as first argument. In almost all cases the abi encoding of the type of the expression matches the abi encoding of the parameter type of the given function. This is because the type checker ensures the expression is implicitly convertible to the respective parameter type. However this is not true for number literals used for fixed bytes types shorter than 32 bytes, nor for string literals used for any fixed bytes type. Number literals were encoded as numbers instead of being shifted to become left-aligned. String literals were encoded as dynamically sized memory strings instead of being converted to a left-aligned bytes value.",
|
||||
"link": "https://blog.soliditylang.org/2022/03/16/encodecall-bug/",
|
||||
"introduced": "0.8.11",
|
||||
"fixed": "0.8.13",
|
||||
"severity": "very low"
|
||||
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2021-4",
|
||||
"name": "UserDefinedValueTypesBug",
|
||||
@ -8,7 +19,6 @@
|
||||
"introduced": "0.8.8",
|
||||
"fixed": "0.8.9",
|
||||
"severity": "very low"
|
||||
|
||||
},
|
||||
{
|
||||
"uid": "SOL-2021-3",
|
||||
|
@ -1549,11 +1549,15 @@
|
||||
"released": "2021-11-09"
|
||||
},
|
||||
"0.8.11": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"AbiEncodeCallLiteralAsFixedBytesBug"
|
||||
],
|
||||
"released": "2021-12-20"
|
||||
},
|
||||
"0.8.12": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"AbiEncodeCallLiteralAsFixedBytesBug"
|
||||
],
|
||||
"released": "2022-02-16"
|
||||
},
|
||||
"0.8.2": {
|
||||
|
@ -1258,6 +1258,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
function.kind() == FunctionType::Kind::ABIEncodeWithSignature;
|
||||
|
||||
TypePointers argumentTypes;
|
||||
TypePointers targetTypes;
|
||||
|
||||
ASTNode::listAccept(arguments, *this);
|
||||
|
||||
@ -1265,14 +1266,17 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
{
|
||||
solAssert(arguments.size() == 2);
|
||||
|
||||
auto const functionPtr = dynamic_cast<FunctionTypePointer>(arguments[0]->annotation().type);
|
||||
solAssert(functionPtr);
|
||||
|
||||
// Account for tuples with one component which become that component
|
||||
if (auto const tupleType = dynamic_cast<TupleType const*>(arguments[1]->annotation().type))
|
||||
argumentTypes = tupleType->components();
|
||||
else
|
||||
argumentTypes.emplace_back(arguments[1]->annotation().type);
|
||||
|
||||
auto functionPtr = dynamic_cast<FunctionTypePointer>(arguments[0]->annotation().type);
|
||||
solAssert(functionPtr);
|
||||
functionPtr = functionPtr->asExternallyCallableFunction(false);
|
||||
solAssert(functionPtr);
|
||||
targetTypes = functionPtr->parameterTypes();
|
||||
}
|
||||
else
|
||||
for (unsigned i = 0; i < arguments.size(); ++i)
|
||||
@ -1292,12 +1296,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
if (isPacked)
|
||||
{
|
||||
solAssert(!function.padArguments(), "");
|
||||
utils().packedEncode(argumentTypes, TypePointers());
|
||||
utils().packedEncode(argumentTypes, targetTypes);
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(function.padArguments(), "");
|
||||
utils().abiEncode(argumentTypes, TypePointers());
|
||||
utils().abiEncode(argumentTypes, targetTypes);
|
||||
}
|
||||
utils().fetchFreeMemoryPointer();
|
||||
// stack: [<selector/functionPointer/signature>] <data_encoding_area_end> <bytes_memory_ptr>
|
||||
|
@ -1160,10 +1160,22 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
for (auto const& argument: argumentsOfEncodeFunction)
|
||||
{
|
||||
argumentTypes.emplace_back(&type(*argument));
|
||||
targetTypes.emplace_back(type(*argument).fullEncodingType(false, true, isPacked));
|
||||
argumentVars += IRVariable(*argument).stackSlots();
|
||||
}
|
||||
|
||||
if (functionType->kind() == FunctionType::Kind::ABIEncodeCall)
|
||||
{
|
||||
auto encodedFunctionType = dynamic_cast<FunctionType const*>(arguments.front()->annotation().type);
|
||||
solAssert(encodedFunctionType);
|
||||
encodedFunctionType = encodedFunctionType->asExternallyCallableFunction(false);
|
||||
solAssert(encodedFunctionType);
|
||||
targetTypes = encodedFunctionType->parameterTypes();
|
||||
}
|
||||
else
|
||||
for (auto const& argument: argumentsOfEncodeFunction)
|
||||
targetTypes.emplace_back(type(*argument).fullEncodingType(false, true, isPacked));
|
||||
|
||||
|
||||
if (functionType->kind() == FunctionType::Kind::ABIEncodeCall)
|
||||
{
|
||||
auto const& selectorType = dynamic_cast<FunctionType const&>(type(*arguments.front()));
|
||||
|
@ -1,22 +1,21 @@
|
||||
contract C {
|
||||
function removeSignature(bytes memory x) internal pure returns (bytes memory r) {
|
||||
r = new bytes(x.length - 4);
|
||||
for (uint i = 0; i < x.length - 4; ++i)
|
||||
r[i] = x[i + 4];
|
||||
function removeSignature(bytes calldata x) external pure returns (bytes memory) {
|
||||
return x[4:];
|
||||
}
|
||||
function g(bytes2, bytes2) public {}
|
||||
function g(bytes2, bytes2, bytes2) public {}
|
||||
function h(uint16, uint16) public {}
|
||||
function f() public returns (bytes memory) {
|
||||
uint16 x = 0x1234;
|
||||
return removeSignature(abi.encodeCall(this.g, (0x1234, bytes2(x))));
|
||||
return this.removeSignature(abi.encodeCall(this.g, (0x1234, "ab", bytes2(x))));
|
||||
}
|
||||
function f2() public returns (bytes memory) {
|
||||
bytes2 x = 0x1234;
|
||||
return removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));
|
||||
return this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f() -> 0x20, 0x40, 0x1234, 0x1234000000000000000000000000000000000000000000000000000000000000
|
||||
// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000
|
||||
// f2() -> 0x20, 0x40, 0x1234, 0x1234
|
||||
|
Loading…
Reference in New Issue
Block a user