Add common validator (#510)

Fixes #512
This commit is contained in:
cyan317
2023-02-15 13:54:53 +00:00
committed by GitHub
parent 08f7a7a476
commit b7fa9b09fe
3 changed files with 98 additions and 0 deletions

View File

@@ -17,10 +17,12 @@
*/
//==============================================================================
#include <ripple/basics/base_uint.h>
#include <rpc/common/Validators.h>
#include <boost/json/value.hpp>
#include <charconv>
#include <string_view>
namespace RPCng::validation {
@@ -86,4 +88,42 @@ CustomValidator::verify(boost::json::value const& value, std::string_view key)
return validator_(value.as_object().at(key.data()), key);
}
[[nodiscard]] bool
checkIsU32Numeric(std::string_view sv)
{
uint32_t unused;
auto [_, ec] = std::from_chars(sv.data(), sv.data() + sv.size(), unused);
return ec == std::errc();
}
CustomValidator LedgerHashValidator = CustomValidator{
[](boost::json::value const& value, std::string_view key) -> MaybeError {
if (!value.is_string())
{
return Error{RPC::Status{
RPC::RippledError::rpcINVALID_PARAMS, "ledgerHashNotString"}};
}
ripple::uint256 ledgerHash;
if (!ledgerHash.parseHex(value.as_string().c_str()))
return Error{RPC::Status{
RPC::RippledError::rpcINVALID_PARAMS, "ledgerHashMalformed"}};
return MaybeError{};
}};
CustomValidator LedgerIndexValidator = CustomValidator{
[](boost::json::value const& value, std::string_view key) -> MaybeError {
auto err = Error{RPC::Status{
RPC::RippledError::rpcINVALID_PARAMS, "ledgerIndexMalformed"}};
if (!value.is_string() && !(value.is_uint64() || value.is_int64()))
{
return err;
}
if (value.is_string() && value.as_string() != "validated" &&
!checkIsU32Numeric(value.as_string().c_str()))
{
return err;
}
return MaybeError{};
}};
} // namespace RPCng::validation

View File

@@ -340,4 +340,24 @@ public:
verify(boost::json::value const& value, std::string_view key) const;
};
/**
* @brief Helper function to check if sv is an uint32 number or not
*/
[[nodiscard]] bool
checkIsU32Numeric(std::string_view sv);
/**
* @brief Provide a common used validator for ledger hash
* LedgerHash must be a string and hex
*/
extern CustomValidator LedgerIndexValidator;
/**
* @brief Provide a common used validator for ledger index
* LedgerIndex must be a string or int
* If the specified LedgerIndex is a string, it's value must be either
* "validated" or a valid integer value represented as a string.
*/
extern CustomValidator LedgerHashValidator;
} // namespace RPCng::validation

View File

@@ -242,3 +242,41 @@ TEST_F(RPCBaseTest, CustomValidator)
auto failingInput = json::parse(R"({ "taker": "wrongformat" })");
ASSERT_FALSE(spec.validate(failingInput));
}
TEST_F(RPCBaseTest, LedgerHashValidator)
{
auto spec = RpcSpec{
{"ledgerHash", LedgerHashValidator},
};
auto passingInput = json::parse(
R"({ "ledgerHash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC" })");
ASSERT_TRUE(spec.validate(passingInput));
auto failingInput = json::parse(R"({ "ledgerHash": "wrongformat" })");
ASSERT_FALSE(spec.validate(failingInput));
failingInput = json::parse(R"({ "ledgerHash": 256 })");
auto err = spec.validate(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "ledgerHashNotString");
}
TEST_F(RPCBaseTest, LedgerIndexValidator)
{
auto spec = RpcSpec{
{"ledgerIndex", LedgerIndexValidator},
};
auto passingInput = json::parse(R"({ "ledgerIndex": "validated" })");
ASSERT_TRUE(spec.validate(passingInput));
passingInput = json::parse(R"({ "ledgerIndex": "256" })");
ASSERT_TRUE(spec.validate(passingInput));
passingInput = json::parse(R"({ "ledgerIndex": 256 })");
ASSERT_TRUE(spec.validate(passingInput));
auto failingInput = json::parse(R"({ "ledgerIndex": "wrongformat" })");
auto err = spec.validate(failingInput);
ASSERT_FALSE(err);
ASSERT_EQ(err.error().message, "ledgerIndexMalformed");
}