mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10187 from ethereum/validateExternal
[SolYul] Properly validate external functions from calldata.
This commit is contained in:
commit
06d0459a72
@ -3553,37 +3553,44 @@ string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromC
|
|||||||
}
|
}
|
||||||
|
|
||||||
solAssert(_type.isValueType(), "");
|
solAssert(_type.isValueType(), "");
|
||||||
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
|
Whiskers templ(R"(
|
||||||
if (funType->kind() == FunctionType::Kind::External)
|
function <functionName>(ptr) -> <returnVariables> {
|
||||||
return Whiskers(R"(
|
|
||||||
function <functionName>(memPtr) -> addr, selector {
|
|
||||||
let combined := <load>(memPtr)
|
|
||||||
addr, selector := <splitFunction>(combined)
|
|
||||||
}
|
|
||||||
)")
|
|
||||||
("functionName", functionName)
|
|
||||||
("load", _fromCalldata ? "calldataload" : "mload")
|
|
||||||
("splitFunction", splitExternalFunctionIdFunction())
|
|
||||||
.render();
|
|
||||||
|
|
||||||
|
|
||||||
return Whiskers(R"(
|
|
||||||
function <functionName>(ptr) -> value {
|
|
||||||
<?fromCalldata>
|
<?fromCalldata>
|
||||||
value := calldataload(ptr)
|
let value := calldataload(ptr)
|
||||||
<validate>(value)
|
<validate>(value)
|
||||||
<!fromCalldata>
|
<!fromCalldata>
|
||||||
value := <cleanup>(mload(ptr))
|
let value := <cleanup>(mload(ptr))
|
||||||
</fromCalldata>
|
</fromCalldata>
|
||||||
|
|
||||||
|
<returnVariables> :=
|
||||||
|
<?externalFunction>
|
||||||
|
<splitFunction>(value)
|
||||||
|
<!externalFunction>
|
||||||
|
value
|
||||||
|
</externalFunction>
|
||||||
}
|
}
|
||||||
)")
|
)");
|
||||||
("functionName", functionName)
|
templ("functionName", functionName);
|
||||||
("fromCalldata", _fromCalldata)
|
templ("fromCalldata", _fromCalldata);
|
||||||
("validate", validatorFunction(_type, true))
|
if (_fromCalldata)
|
||||||
|
templ("validate", validatorFunction(_type, true));
|
||||||
|
auto const* funType = dynamic_cast<FunctionType const*>(&_type);
|
||||||
|
if (funType && funType->kind() == FunctionType::Kind::External)
|
||||||
|
{
|
||||||
|
templ("externalFunction", true);
|
||||||
|
templ("splitFunction", splitExternalFunctionIdFunction());
|
||||||
|
templ("returnVariables", "addr, selector");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
templ("externalFunction", false);
|
||||||
|
templ("returnVariables", "returnValue");
|
||||||
|
}
|
||||||
|
|
||||||
// Byte array elements generally need cleanup.
|
// Byte array elements generally need cleanup.
|
||||||
// Other types are cleaned as well to account for dirty memory e.g. due to inline assembly.
|
// Other types are cleaned as well to account for dirty memory e.g. due to inline assembly.
|
||||||
("cleanup", cleanupFunction(_type))
|
templ("cleanup", cleanupFunction(_type));
|
||||||
.render();
|
return templ.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ contract C {
|
|||||||
return (this.ggg(s.f), this.h(s));
|
return (this.ggg(s.f), this.h(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// ffff(uint256): 0 -> 0, 0
|
// ffff(uint256): 0 -> 0, 0
|
||||||
// ggg(function): 0 -> 0
|
// ggg(function): 0 -> 0
|
||||||
|
Loading…
Reference in New Issue
Block a user