mirror of
https://github.com/Xahau/xahaud.git
synced 2026-08-22 16:00:57 +00:00
APIv2(ledger_entry): return invalidParams for bad parameters (#4630)
- Verify "check", used to retrieve a Check object, is a string. - Verify "nft_page", used to retrieve an NFT Page, is a string. - Verify "index", used to retrieve any type of ledger object by its unique ID, is a string. - Verify "directory", used to retrieve a DirectoryNode, is a string or an object. This change only impacts api_version 2 since it is a breaking change. https://xrpl.org/ledger_entry.html Fix #4550
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <ripple/protocol/Issue.h>
|
||||
|
||||
#include <ripple/json/json_errors.h>
|
||||
#include <ripple/protocol/AccountID.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
@@ -78,7 +79,7 @@ issueFromJson(Json::Value const& v)
|
||||
{
|
||||
if (!v.isObject())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
Throw<Json::error>(
|
||||
"issueFromJson can only be specified with a 'object' Json value");
|
||||
}
|
||||
|
||||
@@ -87,37 +88,34 @@ issueFromJson(Json::Value const& v)
|
||||
|
||||
if (!curStr.isString())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
Throw<Json::error>(
|
||||
"issueFromJson currency must be a string Json value");
|
||||
}
|
||||
|
||||
auto const currency = to_currency(curStr.asString());
|
||||
if (currency == badCurrency() || currency == noCurrency())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"issueFromJson currency must be a valid currency");
|
||||
Throw<Json::error>("issueFromJson currency must be a valid currency");
|
||||
}
|
||||
|
||||
if (isXRP(currency))
|
||||
{
|
||||
if (!issStr.isNull())
|
||||
{
|
||||
Throw<std::runtime_error>("Issue, XRP should not have issuer");
|
||||
Throw<Json::error>("Issue, XRP should not have issuer");
|
||||
}
|
||||
return xrpIssue();
|
||||
}
|
||||
|
||||
if (!issStr.isString())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"issueFromJson issuer must be a string Json value");
|
||||
Throw<Json::error>("issueFromJson issuer must be a string Json value");
|
||||
}
|
||||
auto const issuer = parseBase58<AccountID>(issStr.asString());
|
||||
|
||||
if (!issuer)
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"issueFromJson issuer must be a valid account");
|
||||
Throw<Json::error>("issueFromJson issuer must be a valid account");
|
||||
}
|
||||
|
||||
return Issue{currency, *issuer};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1926,18 +1926,231 @@ public:
|
||||
|
||||
std::string const ledgerHash{to_string(env.closed()->info().hash)};
|
||||
|
||||
auto makeParams = [&apiVersion](std::function<void(Json::Value&)> f) {
|
||||
Json::Value params;
|
||||
params[jss::api_version] = apiVersion;
|
||||
f(params);
|
||||
return params;
|
||||
};
|
||||
// "features" is not an option supported by ledger_entry.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::api_version] = apiVersion;
|
||||
jvParams[jss::features] = ledgerHash;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr =
|
||||
env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&ledgerHash](Json::Value& jvParams) {
|
||||
jvParams[jss::features] = ledgerHash;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
});
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "unknownOption", "");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "unknownOption", "");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
Json::Value const injectObject = []() {
|
||||
Json::Value obj(Json::objectValue);
|
||||
obj[jss::account] = "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
|
||||
obj[jss::ledger_index] = "validated";
|
||||
return obj;
|
||||
}();
|
||||
Json::Value const injectArray = []() {
|
||||
Json::Value arr(Json::arrayValue);
|
||||
arr[0u] = "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
|
||||
arr[1u] = "validated";
|
||||
return arr;
|
||||
}();
|
||||
|
||||
// invalid input for fields that can handle an object, but can't handle
|
||||
// an array
|
||||
for (auto const& field : {
|
||||
jss::directory,
|
||||
jss::escrow,
|
||||
jss::offer,
|
||||
jss::ticket,
|
||||
jss::amm,
|
||||
jss::import_vlseq,
|
||||
jss::uri_token,
|
||||
jss::hook,
|
||||
})
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&field, &injectArray](Json::Value& jvParams) {
|
||||
jvParams[field] = injectArray;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "internal", "Internal error.");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
// Fields that can handle objects just fine
|
||||
for (auto const& field : {
|
||||
jss::directory,
|
||||
jss::escrow,
|
||||
jss::offer,
|
||||
jss::ticket,
|
||||
jss::amm,
|
||||
jss::import_vlseq,
|
||||
jss::uri_token,
|
||||
})
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&field, &injectObject](Json::Value& jvParams) {
|
||||
jvParams[field] = injectObject;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
|
||||
for (auto const& inject : {injectObject, injectArray})
|
||||
{
|
||||
// invalid input for fields that can't handle an object or an array
|
||||
for (auto const& field :
|
||||
{jss::index,
|
||||
jss::account_root,
|
||||
jss::check,
|
||||
jss::payment_channel})
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&field, &inject](Json::Value& jvParams) {
|
||||
jvParams[field] = inject;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "internal", "Internal error.");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
// directory sub-fields
|
||||
for (auto const& field : {jss::dir_root, jss::owner})
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&field, &inject](Json::Value& jvParams) {
|
||||
jvParams[jss::directory][field] = inject;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "internal", "Internal error.");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
// escrow sub-fields
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&inject](Json::Value& jvParams) {
|
||||
jvParams[jss::escrow][jss::owner] = inject;
|
||||
jvParams[jss::escrow][jss::seq] = 99;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "internal", "Internal error.");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
// offer sub-fields
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&inject](Json::Value& jvParams) {
|
||||
jvParams[jss::offer][jss::account] = inject;
|
||||
jvParams[jss::offer][jss::seq] = 99;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "internal", "Internal error.");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
// ripple_state sub-fields
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&inject](Json::Value& jvParams) {
|
||||
Json::Value rs(Json::objectValue);
|
||||
rs[jss::currency] = "FOO";
|
||||
rs[jss::accounts] = Json::Value(Json::arrayValue);
|
||||
rs[jss::accounts][0u] =
|
||||
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
|
||||
rs[jss::accounts][1u] =
|
||||
"rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
|
||||
rs[jss::currency] = inject;
|
||||
jvParams[jss::ripple_state] = std::move(rs);
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "internal", "Internal error.");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
// ticket sub-fields
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&inject](Json::Value& jvParams) {
|
||||
jvParams[jss::ticket][jss::account] = inject;
|
||||
jvParams[jss::ticket][jss::ticket_seq] = 99;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
if (apiVersion < 2u)
|
||||
checkErrorValue(jrr, "internal", "Internal error.");
|
||||
else
|
||||
checkErrorValue(jrr, "invalidParams", "");
|
||||
}
|
||||
|
||||
// Fields that can handle malformed inputs just fine
|
||||
for (auto const& field : {jss::nft_page, jss::deposit_preauth})
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&field, &inject](Json::Value& jvParams) {
|
||||
jvParams[field] = inject;
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
// Subfields of deposit_preauth that can handle malformed inputs
|
||||
// fine
|
||||
for (auto const& field : {jss::owner, jss::authorized})
|
||||
{
|
||||
auto const jvParams =
|
||||
makeParams([&field, &inject](Json::Value& jvParams) {
|
||||
auto pa = Json::Value(Json::objectValue);
|
||||
pa[jss::owner] = "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
|
||||
pa[jss::authorized] =
|
||||
"rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
|
||||
pa[field] = inject;
|
||||
jvParams[jss::deposit_preauth] = std::move(pa);
|
||||
});
|
||||
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
checkErrorValue(jrr, "malformedRequest", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief ledger RPC requests as a way to drive
|
||||
|
||||
Reference in New Issue
Block a user