mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[whiskers] Add check that template contain tags.
This commit is contained in:
parent
a75b87c80e
commit
061fecbc90
@ -1231,9 +1231,10 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)
|
|||||||
"abi_decode_" +
|
"abi_decode_" +
|
||||||
_type.identifier();
|
_type.identifier();
|
||||||
return createFunction(functionName, [&]() {
|
return createFunction(functionName, [&]() {
|
||||||
string templ;
|
Whiskers w;
|
||||||
if (_type.isDynamicallySized())
|
if (_type.isDynamicallySized())
|
||||||
templ = R"(
|
{
|
||||||
|
w = Whiskers(R"(
|
||||||
// <readableTypeName>
|
// <readableTypeName>
|
||||||
function <functionName>(offset, end) -> arrayPos, length {
|
function <functionName>(offset, end) -> arrayPos, length {
|
||||||
if iszero(slt(add(offset, 0x1f), end)) { <revertStringOffset> }
|
if iszero(slt(add(offset, 0x1f), end)) { <revertStringOffset> }
|
||||||
@ -1242,25 +1243,27 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)
|
|||||||
arrayPos := add(offset, 0x20)
|
arrayPos := add(offset, 0x20)
|
||||||
if gt(add(arrayPos, mul(length, <stride>)), end) { <revertStringPos> }
|
if gt(add(arrayPos, mul(length, <stride>)), end) { <revertStringPos> }
|
||||||
}
|
}
|
||||||
)";
|
)");
|
||||||
|
w("revertStringOffset", revertReasonIfDebug("ABI decoding: invalid calldata array offset"));
|
||||||
|
w("revertStringLength", revertReasonIfDebug("ABI decoding: invalid calldata array length"));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
templ = R"(
|
{
|
||||||
|
w = Whiskers(R"(
|
||||||
// <readableTypeName>
|
// <readableTypeName>
|
||||||
function <functionName>(offset, end) -> arrayPos {
|
function <functionName>(offset, end) -> arrayPos {
|
||||||
arrayPos := offset
|
arrayPos := offset
|
||||||
if gt(add(arrayPos, mul(<length>, <stride>)), end) { <revertStringPos> }
|
if gt(add(arrayPos, mul(<length>, <stride>)), end) { <revertStringPos> }
|
||||||
}
|
}
|
||||||
)";
|
)");
|
||||||
Whiskers w{templ};
|
w("length", toCompactHexWithPrefix(_type.length()));
|
||||||
// TODO add test
|
}
|
||||||
w("revertStringOffset", revertReasonIfDebug("ABI decoding: invalid calldata array offset"));
|
|
||||||
w("revertStringLength", revertReasonIfDebug("ABI decoding: invalid calldata array length"));
|
|
||||||
w("revertStringPos", revertReasonIfDebug("ABI decoding: invalid calldata array stride"));
|
w("revertStringPos", revertReasonIfDebug("ABI decoding: invalid calldata array stride"));
|
||||||
w("functionName", functionName);
|
w("functionName", functionName);
|
||||||
w("readableTypeName", _type.toString(true));
|
w("readableTypeName", _type.toString(true));
|
||||||
w("stride", toCompactHexWithPrefix(_type.calldataStride()));
|
w("stride", toCompactHexWithPrefix(_type.calldataStride()));
|
||||||
if (!_type.isDynamicallySized())
|
|
||||||
w("length", toCompactHexWithPrefix(_type.length()));
|
// TODO add test
|
||||||
return w.render();
|
return w.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -959,7 +959,6 @@ string YulUtilFunctions::overflowCheckedUnsignedExpFunction()
|
|||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("panic", panicFunction(PanicCode::UnderOverflow))
|
("panic", panicFunction(PanicCode::UnderOverflow))
|
||||||
("expLoop", overflowCheckedExpLoopFunction())
|
("expLoop", overflowCheckedExpLoopFunction())
|
||||||
("shr_1", shiftRightFunction(1))
|
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1326,8 +1325,6 @@ string YulUtilFunctions::byteArrayTransitLongToShortFunction(ArrayType const& _t
|
|||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("dataPosition", arrayDataAreaFunction(_type))
|
("dataPosition", arrayDataAreaFunction(_type))
|
||||||
("extractUsedApplyLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
|
("extractUsedApplyLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
|
||||||
("shl", shiftLeftFunctionDynamic())
|
|
||||||
("ones", formatNumber((bigint(1) << 256) - 1))
|
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1420,7 +1417,6 @@ string YulUtilFunctions::storageByteArrayPopFunction(ArrayType const& _type)
|
|||||||
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
|
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
|
||||||
("indexAccess", storageArrayIndexAccessFunction(_type))
|
("indexAccess", storageArrayIndexAccessFunction(_type))
|
||||||
("setToZero", storageSetToZeroFunction(*_type.baseType()))
|
("setToZero", storageSetToZeroFunction(*_type.baseType()))
|
||||||
("shl", shiftLeftFunctionDynamic())
|
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1492,7 +1488,6 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type, Type c
|
|||||||
("storeValue", updateStorageValueFunction(*_fromType, *_type.baseType()))
|
("storeValue", updateStorageValueFunction(*_fromType, *_type.baseType()))
|
||||||
("maxArrayLength", (u256(1) << 64).str())
|
("maxArrayLength", (u256(1) << 64).str())
|
||||||
("shl", shiftLeftFunctionDynamic())
|
("shl", shiftLeftFunctionDynamic())
|
||||||
("shr", shiftRightFunction(248))
|
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1658,7 +1653,6 @@ string YulUtilFunctions::clearStorageStructFunction(StructType const& _type)
|
|||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("storageSize", _type.storageSize().str())
|
|
||||||
("member", memberSetValues)
|
("member", memberSetValues)
|
||||||
.render();
|
.render();
|
||||||
});
|
});
|
||||||
@ -1742,7 +1736,6 @@ string YulUtilFunctions::copyArrayToStorageFunction(ArrayType const& _fromType,
|
|||||||
templ("srcDataLocation", arrayDataAreaFunction(_fromType));
|
templ("srcDataLocation", arrayDataAreaFunction(_fromType));
|
||||||
if (fromCalldata)
|
if (fromCalldata)
|
||||||
{
|
{
|
||||||
templ("dynamicallySizedBase", _fromType.baseType()->isDynamicallySized());
|
|
||||||
templ("dynamicallyEncodedBase", _fromType.baseType()->isDynamicallyEncoded());
|
templ("dynamicallyEncodedBase", _fromType.baseType()->isDynamicallyEncoded());
|
||||||
if (_fromType.baseType()->isDynamicallyEncoded())
|
if (_fromType.baseType()->isDynamicallyEncoded())
|
||||||
templ("accessCalldataTail", accessCalldataTailFunction(*_fromType.baseType()));
|
templ("accessCalldataTail", accessCalldataTailFunction(*_fromType.baseType()));
|
||||||
@ -3380,7 +3373,6 @@ string YulUtilFunctions::copyStructToStorageFunction(StructType const& _from, St
|
|||||||
solAssert(srcOffset == 0, "");
|
solAssert(srcOffset == 0, "");
|
||||||
|
|
||||||
}
|
}
|
||||||
t("memberStorageSlotOffset", to_string(offset));
|
|
||||||
t("updateStorageValue", updateStorageValueFunction(
|
t("updateStorageValue", updateStorageValueFunction(
|
||||||
memberType,
|
memberType,
|
||||||
*toStructMembers[i].type,
|
*toStructMembers[i].type,
|
||||||
|
@ -891,7 +891,6 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
|
|||||||
}
|
}
|
||||||
|
|
||||||
t("fallback", fallbackCode);
|
t("fallback", fallbackCode);
|
||||||
t("revertNoSignature", "");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
t(
|
t(
|
||||||
|
@ -40,6 +40,7 @@ Whiskers& Whiskers::operator()(string _parameter, string _value)
|
|||||||
{
|
{
|
||||||
checkParameterValid(_parameter);
|
checkParameterValid(_parameter);
|
||||||
checkParameterUnknown(_parameter);
|
checkParameterUnknown(_parameter);
|
||||||
|
checkTemplateContainsTags(_parameter, {""});
|
||||||
m_parameters[move(_parameter)] = move(_value);
|
m_parameters[move(_parameter)] = move(_value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -48,6 +49,7 @@ Whiskers& Whiskers::operator()(string _parameter, bool _value)
|
|||||||
{
|
{
|
||||||
checkParameterValid(_parameter);
|
checkParameterValid(_parameter);
|
||||||
checkParameterUnknown(_parameter);
|
checkParameterUnknown(_parameter);
|
||||||
|
checkTemplateContainsTags(_parameter, {"?", "/"});
|
||||||
m_conditions[move(_parameter)] = _value;
|
m_conditions[move(_parameter)] = _value;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -59,6 +61,7 @@ Whiskers& Whiskers::operator()(
|
|||||||
{
|
{
|
||||||
checkParameterValid(_listParameter);
|
checkParameterValid(_listParameter);
|
||||||
checkParameterUnknown(_listParameter);
|
checkParameterUnknown(_listParameter);
|
||||||
|
checkTemplateContainsTags(_listParameter, {"#", "/"});
|
||||||
for (auto const& element: _values)
|
for (auto const& element: _values)
|
||||||
for (auto const& val: element)
|
for (auto const& val: element)
|
||||||
checkParameterValid(val.first);
|
checkParameterValid(val.first);
|
||||||
@ -100,6 +103,19 @@ void Whiskers::checkParameterUnknown(string const& _parameter) const
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Whiskers::checkTemplateContainsTags(string const& _parameter, vector<string> const& _prefixes) const
|
||||||
|
{
|
||||||
|
for (auto const& prefix: _prefixes)
|
||||||
|
{
|
||||||
|
string tag{"<" + prefix + _parameter + ">"};
|
||||||
|
assertThrow(
|
||||||
|
m_template.find(tag) != string::npos,
|
||||||
|
WhiskersError,
|
||||||
|
"Tag '" + tag + "' not found in template:\n" + m_template
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template<class ReplaceCallback>
|
template<class ReplaceCallback>
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
using StringMap = std::map<std::string, std::string>;
|
using StringMap = std::map<std::string, std::string>;
|
||||||
using StringListMap = std::map<std::string, std::vector<StringMap>>;
|
using StringListMap = std::map<std::string, std::vector<StringMap>>;
|
||||||
|
|
||||||
explicit Whiskers(std::string _template);
|
explicit Whiskers(std::string _template = "");
|
||||||
|
|
||||||
/// Sets a single regular parameter, <paramName>.
|
/// Sets a single regular parameter, <paramName>.
|
||||||
Whiskers& operator()(std::string _parameter, std::string _value);
|
Whiskers& operator()(std::string _parameter, std::string _value);
|
||||||
@ -94,6 +94,12 @@ private:
|
|||||||
void checkParameterValid(std::string const& _parameter) const;
|
void checkParameterValid(std::string const& _parameter) const;
|
||||||
void checkParameterUnknown(std::string const& _parameter) const;
|
void checkParameterUnknown(std::string const& _parameter) const;
|
||||||
|
|
||||||
|
/// Checks whether the string stored in `m_template` contains all the tags specified.
|
||||||
|
/// @param _parameter name of the parameter. This name is used to construct the tag(s).
|
||||||
|
/// @param _prefixes a vector of strings, where each element is used to compose the tag
|
||||||
|
/// like `"<" + element + _parameter + ">"`. Each element of _prefixes is used as a prefix of the tag name.
|
||||||
|
void checkTemplateContainsTags(std::string const& _parameter, std::vector<std::string> const& _prefixes) const;
|
||||||
|
|
||||||
static std::string replace(
|
static std::string replace(
|
||||||
std::string const& _template,
|
std::string const& _template,
|
||||||
StringMap const& _parameters,
|
StringMap const& _parameters,
|
||||||
|
@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(parameter_collision)
|
|||||||
vector<map<string, string>> list(1);
|
vector<map<string, string>> list(1);
|
||||||
list[0]["a"] = "x";
|
list[0]["a"] = "x";
|
||||||
Whiskers m(templ);
|
Whiskers m(templ);
|
||||||
m("a", "X")("b", list);
|
BOOST_CHECK_THROW(m("a", "X")("b", list), WhiskersError);
|
||||||
BOOST_CHECK_THROW(m.render(), WhiskersError);
|
BOOST_CHECK_THROW(m.render(), WhiskersError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user