params and grants tests, fix param validation

This commit is contained in:
Richard Holland
2022-10-11 12:52:08 +00:00
parent 01e7793df1
commit f1cbeca57d
4 changed files with 169 additions and 4 deletions

View File

@@ -128,6 +128,7 @@ namespace hook
WASM_TOO_SMALL = 80,
WASM_VALIDATION = 81, // a generic error while parsing wasm, usually leb128 overflow
HOOK_CBAK_DIFF_TYPES = 82, // hook and cbak function definitions were different
PARAMETERS_NAME_REPEATED = 83,
// RH NOTE: only HookSet msgs got log codes, possibly all Hook log lines should get a code?
};
};

View File

@@ -101,6 +101,20 @@ validateHookGrants(SetHookCtx& ctx, STArray const& hookGrants)
bool
validateHookParams(SetHookCtx& ctx, STArray const& hookParams)
{
const int paramKeyMax = hook::maxHookParameterKeySize();
const int paramValueMax = hook::maxHookParameterValueSize();
int paramCount = (int)(hookParams.size());
if (paramCount > 16)
{
JLOG(ctx.j.trace())
<< "HookSet(" << hook::log::HOOK_PARAMS_COUNT << ")[" << HS_ACC()
<< "]: Malformed transaction: Txn would result in too many parameters on hook";
return false;
}
std::set<ripple::Blob> alreadySet;
for (auto const& hookParam : hookParams)
{
auto const& hookParamObj = dynamic_cast<STObject const*>(&hookParam);
@@ -114,6 +128,8 @@ validateHookParams(SetHookCtx& ctx, STArray const& hookParams)
return false;
}
// RH TODO: rippled's template system already does most of these checks, run through and
// remove redundant template checking.
bool nameFound = false;
for (auto const& paramElement : *hookParamObj)
{
@@ -140,8 +156,31 @@ validateHookParams(SetHookCtx& ctx, STArray const& hookParams)
<< "SetHook sfHookParameter must contain at least sfHookParameterName";
return false;
}
}
ripple::Blob const& paramName = hookParam.getFieldVL(sfHookParameterName);
if (paramName.size() > paramKeyMax ||
(hookParam.isFieldPresent(sfHookParameterValue) &&
hookParam.getFieldVL(sfHookParameterValue).size() > paramValueMax))
{
JLOG(ctx.j.trace())
<< "HookSet(" << hook::log::HOOK_PARAM_SIZE << ")[" << HS_ACC()
<< "]: Malformed transaction: Txn would result in a too large parameter name/value on hook";
return false;
}
if (alreadySet.find(paramName) != alreadySet.end())
{
JLOG(ctx.j.trace())
<< "HookSet(" << hook::log::PARAMETERS_NAME_REPEATED << ")[" << HS_ACC()
<< "]: Malformed transaction: "
<< "SetHook sfHookParameters must contain each parameter name at most once";
return false;
}
alreadySet.emplace(paramName);
}
return true;
}

View File

@@ -76,6 +76,8 @@ JSS(HookOn); // field
JSS(Hooks); // field
JSS(HookGrants); // field
JSS(HookParameters); // field
JSS(HookParameterName); // field
JSS(HookParameterValue); // field
JSS(Invalid); //
JSS(LastLedgerSequence); // in: TransactionSign; field
JSS(LedgerHashes); // ledger type.

View File

@@ -171,6 +171,18 @@ public:
env.close();
}
// invalid flags
{
Json::Value iv;
iv[jss::CreateCode] = "";
iv[jss::Flags] = "2147483648";
jv[jss::Hooks][0U][jss::Hook] = iv;
env(jv,
M("Hook DELETE operation must include hsfOVERRIDE flag"),
HSFEE, ter(temMALFORMED));
env.close();
}
// grants, parameters, hookon, hookapiversion, hooknamespace keys must be absent
for (auto const& [key, value]:
JSSMap {
@@ -189,16 +201,125 @@ public:
M("Hook DELETE operation cannot include: grants, params, hookon, apiversion, namespace"),
HSFEE, ter(temMALFORMED));
env.close();
}
}
}
void testMalformedInstall()
{
testcase("Checks malformed install operation");
using namespace jtx;
Env env{*this, supported_amendments()};
auto const alice = Account{"alice"};
env.fund(XRP(10000), alice);
Json::Value jv;
jv[jss::Account] = alice.human();
jv[jss::TransactionType] = jss::SetHook;
jv[jss::Flags] = 0;
jv[jss::Hooks] = Json::Value{Json::arrayValue};
// trying to set api version
{
Json::Value iv;
iv[jss::HookHash] = to_string(uint256{beast::zero});
iv[jss::HookApiVersion] = 1U;
jv[jss::Hooks][0U][jss::Hook] = iv;
env(jv,
M("Hook Install operation cannot set apiversion"),
HSFEE, ter(temMALFORMED));
env.close();
}
}
void testMalformedParamsGrants()
{
testcase("Checks malformed grants/params on create operation");
using namespace jtx;
Env env{*this, supported_amendments()};
auto const alice = Account{"alice"};
env.fund(XRP(10000), alice);
Json::Value jv;
jv[jss::Account] = alice.human();
jv[jss::TransactionType] = jss::SetHook;
jv[jss::Flags] = 0;
jv[jss::Hooks] = Json::Value{Json::arrayValue};
// check blank grants
{
Json::Value iv;
iv[jss::HookHash] = to_string(uint256{beast::zero});
iv[jss::HookGrants] = Json::Value{Json::arrayValue};
jv[jss::Hooks][0U][jss::Hook] = iv;
env(jv,
M("HSO must include at least one entry in HookGrants when field is present"),
HSFEE, ter(temMALFORMED));
env.close();
}
// check too many parameters
{
Json::Value iv;
iv[jss::HookHash] = to_string(uint256{beast::zero});
Json::Value params {Json::arrayValue};
for (uint32_t i = 0; i < 17; ++i)
{
params[i] = Json::Value{Json::arrayValue};
char buf[10];
snprintf(buf, 10, "param%d", i);
params[i][jss::HookParameterName] = Json::Value{std::string(buf)};
snprintf(buf, 10, "value%d", i);
params[i][jss::HookParameterValue] = Json::Value{std::string(buf)};
}
iv[jss::HookParameters] = params;
jv[jss::Hooks][0U][jss::Hook] = iv;
env(jv,
M("HSO must not include more than 16 parameters"),
HSFEE, ter(temMALFORMED));
env.close();
}
// check repeat parameters
{
Json::Value iv;
iv[jss::HookHash] = to_string(uint256{beast::zero});
Json::Value params {Json::arrayValue};
for (uint32_t i = 0; i < 2; ++i)
{
params[i] = Json::Value{Json::arrayValue};
params[i][jss::HookParameterName] = "param";
}
iv[jss::HookParameters] = params;
jv[jss::Hooks][0U][jss::Hook] = iv;
env(jv,
M("HSO must not repeat parameter names"),
HSFEE, ter(temMALFORMED));
env.close();
}
// RH TODO: check too long name, too long value
}
void testMalformedCreate()
{
testcase("Checks malformed create operation");
using namespace jtx;
Env env{*this, supported_amendments()};
auto const alice = Account{"alice"};
env.fund(XRP(10000), alice);
Json::Value jv;
jv[jss::Account] = alice.human();
jv[jss::TransactionType] = jss::SetHook;
jv[jss::Flags] = 0;
jv[jss::Hooks] = Json::Value{Json::arrayValue};
// RH UPTO
}
void testMalformedUpdate()
@@ -336,7 +457,9 @@ public:
testMalformedTxStructure();
testInferHookSetOperation();
testMalformedDelete();
testMalformedInstall();
testMalformedParamsGrants();
testMalformedWasm();
testAccept();
testRollback();