Return error when limit<=0 (#804)

Fix #806
This commit is contained in:
cyan317
2023-08-02 15:34:42 +01:00
committed by GitHub
parent 1804e3e9c0
commit c90bc15959
45 changed files with 832 additions and 562 deletions

View File

@@ -457,7 +457,7 @@ traverseNFTObjects(
}
// the object exists and the key is in right range, must be nft page
ripple::SLE pageSLE{ripple::SLE{ripple::SerialIter{page->data(), page->size()}, currentPage}};
ripple::SLE pageSLE{ripple::SerialIter{page->data(), page->size()}, currentPage};
auto count = 0u;
// traverse the nft page linked list until the start of the list or reach the limit

View File

@@ -67,6 +67,12 @@ template <typename Expected>
{
if (not value.is_int64() && not value.is_uint64())
hasError = true;
// specify the type is unsigened, it can not be negative
if constexpr (std::is_unsigned_v<Expected>)
{
if (value.is_int64() and value.as_int64() < 0)
hasError = true;
}
}
return not hasError;
@@ -214,6 +220,89 @@ public:
}
};
/**
* @brief Validate that value is equal or greater than the specified min
*/
template <typename Type>
class Min final
{
Type min_;
public:
/**
* @brief Construct the validator storing min value
*
* @param min
*/
explicit Min(Type min) : min_{min}
{
}
/**
* @brief Verify that the JSON value is not smaller than min
*
* @param value The JSON value representing the outer object
* @param key The key used to retrieve the tested value from the outer
* object
*/
[[nodiscard]] MaybeError
verify(boost::json::value const& value, std::string_view key) const
{
using boost::json::value_to;
if (not value.is_object() or not value.as_object().contains(key.data()))
return {}; // ignore. field does not exist, let 'required' fail instead
auto const res = value_to<Type>(value.as_object().at(key.data()));
if (res < min_)
return Error{Status{RippledError::rpcINVALID_PARAMS}};
return {};
}
};
/**
* @brief Validate that value is not greater than max
*/
template <typename Type>
class Max final
{
Type max_;
public:
/**
* @brief Construct the validator storing max value
*
* @param max
*/
explicit Max(Type max) : max_{max}
{
}
/**
* @brief Verify that the JSON value is not greater than max
*
* @param value The JSON value representing the outer object
* @param key The key used to retrieve the tested value from the outer object
*/
[[nodiscard]] MaybeError
verify(boost::json::value const& value, std::string_view key) const
{
using boost::json::value_to;
if (not value.is_object() or not value.as_object().contains(key.data()))
return {}; // ignore. field does not exist, let 'required' fail instead
auto const res = value_to<Type>(value.as_object().at(key.data()));
if (res > max_)
return Error{Status{RippledError::rpcINVALID_PARAMS}};
return {};
}
};
/**
* @brief Validates that the value is equal to the one passed in
*/

View File

@@ -99,7 +99,10 @@ public:
{JS(account), validation::Required{}, validation::AccountValidator},
{JS(destination_account), validation::Type<std::string>{}, validation::AccountValidator},
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(marker), validation::AccountMarkerValidator},
};

View File

@@ -102,7 +102,10 @@ public:
{JS(peer), meta::WithCustomError{validation::AccountValidator, Status(RippledError::rpcACT_MALFORMED)}},
{JS(ignore_default), validation::Type<bool>{}},
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(marker), validation::AccountMarkerValidator},
};

View File

@@ -76,7 +76,10 @@ public:
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(marker), validation::Uint256HexStringValidator},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
};
return rpcSpec;

View File

@@ -86,7 +86,10 @@ public:
{JS(account), validation::Required{}, validation::AccountValidator},
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>(LIMIT_MIN, LIMIT_MAX)},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>(LIMIT_MIN, LIMIT_MAX)},
{JS(type),
validation::Type<std::string>{},
validation::OneOf<std::string>{

View File

@@ -87,7 +87,10 @@ public:
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(marker), validation::AccountMarkerValidator},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}}};
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}}};
return rpcSpec;
}

View File

@@ -98,6 +98,7 @@ public:
{JS(forward), validation::Type<bool>{}},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, std::numeric_limits<int32_t>::max()}},
{JS(marker),
meta::WithCustomError{

View File

@@ -96,7 +96,10 @@ public:
{JS(taker),
meta::WithCustomError{
validation::AccountValidator, Status(RippledError::rpcINVALID_PARAMS, "Invalid field 'taker'")}},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(ledger_index), validation::LedgerIndexValidator},
};

View File

@@ -92,7 +92,11 @@ public:
{"out_of_order", validation::Type<bool>{}},
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(limit), validation::Type<uint32_t>{}},
{
JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
},
{JS(marker),
validation::Type<uint32_t, std::string>{},
meta::IfType<std::string>{validation::Uint256HexStringValidator}},

View File

@@ -96,7 +96,10 @@ public:
{JS(ledger_index_max), validation::Type<int32_t>{}},
{JS(binary), validation::Type<bool>{}},
{JS(forward), validation::Type<bool>{}},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(marker),
meta::WithCustomError{
validation::Type<boost::json::object>{}, Status{RippledError::rpcINVALID_PARAMS, "invalidMarker"}},

View File

@@ -70,7 +70,10 @@ public:
{JS(nft_id), validation::Required{}, validation::Uint256HexStringValidator},
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(limit), validation::Type<uint32_t>{}, modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(limit),
validation::Type<uint32_t>{},
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(marker), validation::Uint256HexStringValidator},
};

View File

@@ -84,7 +84,10 @@ public:
Status{RippledError::rpcINVALID_PARAMS, "role field is invalid"}}},
{JS(ledger_hash), validation::Uint256HexStringValidator},
{JS(ledger_index), validation::LedgerIndexValidator},
{JS(limit), validation::Type<uint32_t>(), modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(limit),
validation::Type<uint32_t>(),
validation::Min(1u),
modifiers::Clamp<int32_t>{LIMIT_MIN, LIMIT_MAX}},
{JS(transactions), validation::Type<bool>()},
};