mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Validate data size before calling uint256::fromVoid
This commit is contained in:
@@ -495,11 +495,14 @@ public:
|
||||
|
||||
for (auto& obj : cur_->ledger_objects().objects())
|
||||
{
|
||||
auto key = uint256::fromVoid(obj.key().data());
|
||||
auto key = uint256::fromVoidChecked(obj.key());
|
||||
if (!key)
|
||||
throw std::runtime_error("Received malformed object ID");
|
||||
|
||||
auto& data = obj.data();
|
||||
|
||||
SerialIter it{data.data(), data.size()};
|
||||
std::shared_ptr<SLE> sle = std::make_shared<SLE>(it, key);
|
||||
std::shared_ptr<SLE> sle = std::make_shared<SLE>(it, *key);
|
||||
|
||||
queue.push(sle);
|
||||
}
|
||||
|
||||
@@ -405,32 +405,35 @@ ReportingETL::buildNextLedger(
|
||||
|
||||
for (auto& obj : rawData.ledger_objects().objects())
|
||||
{
|
||||
auto key = uint256::fromVoid(obj.key().data());
|
||||
auto key = uint256::fromVoidChecked(obj.key());
|
||||
if (!key)
|
||||
throw std::runtime_error("Recevied malformed object ID");
|
||||
|
||||
auto& data = obj.data();
|
||||
|
||||
// indicates object was deleted
|
||||
if (data.size() == 0)
|
||||
{
|
||||
JLOG(journal_.trace()) << __func__ << " : "
|
||||
<< "Erasing object = " << key;
|
||||
if (next->exists(key))
|
||||
next->rawErase(key);
|
||||
<< "Erasing object = " << *key;
|
||||
if (next->exists(*key))
|
||||
next->rawErase(*key);
|
||||
}
|
||||
else
|
||||
{
|
||||
SerialIter it{data.data(), data.size()};
|
||||
std::shared_ptr<SLE> sle = std::make_shared<SLE>(it, key);
|
||||
std::shared_ptr<SLE> sle = std::make_shared<SLE>(it, *key);
|
||||
|
||||
if (next->exists(key))
|
||||
if (next->exists(*key))
|
||||
{
|
||||
JLOG(journal_.trace()) << __func__ << " : "
|
||||
<< "Replacing object = " << key;
|
||||
<< "Replacing object = " << *key;
|
||||
next->rawReplace(sle);
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(journal_.trace()) << __func__ << " : "
|
||||
<< "Inserting object = " << key;
|
||||
<< "Inserting object = " << *key;
|
||||
next->rawInsert(sle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +313,15 @@ public:
|
||||
return base_uint(data, VoidHelper());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static std::optional<base_uint>
|
||||
fromVoidChecked(T const& from)
|
||||
{
|
||||
if (from.size() != size())
|
||||
return {};
|
||||
return fromVoid(from.data());
|
||||
}
|
||||
|
||||
constexpr int
|
||||
signum() const
|
||||
{
|
||||
|
||||
@@ -97,14 +97,17 @@ parseLedgerArgs(
|
||||
}
|
||||
else if (ledgerCase == LedgerCase::kHash)
|
||||
{
|
||||
if (uint256::size() != specifier.hash().size())
|
||||
if (auto hash = uint256::fromVoidChecked(specifier.hash()))
|
||||
{
|
||||
ledger = *hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::INVALID_ARGUMENT,
|
||||
"ledger hash malformed"};
|
||||
return errorStatus;
|
||||
}
|
||||
ledger = uint256::fromVoid(specifier.hash().data());
|
||||
}
|
||||
return ledger;
|
||||
}
|
||||
|
||||
@@ -137,42 +137,49 @@ doLedgerDataGrpc(
|
||||
grpc::Status status = grpc::Status::OK;
|
||||
|
||||
std::shared_ptr<ReadView const> ledger;
|
||||
if (RPC::ledgerFromRequest(ledger, context))
|
||||
if (auto status = RPC::ledgerFromRequest(ledger, context))
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::NOT_FOUND, "ledger not found"};
|
||||
grpc::Status errorStatus;
|
||||
if (status.toErrorCode() == rpcINVALID_PARAMS)
|
||||
{
|
||||
errorStatus = grpc::Status(
|
||||
grpc::StatusCode::INVALID_ARGUMENT, status.message());
|
||||
}
|
||||
else
|
||||
{
|
||||
errorStatus =
|
||||
grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
|
||||
}
|
||||
return {response, errorStatus};
|
||||
}
|
||||
|
||||
ReadView::key_type key = ReadView::key_type();
|
||||
if (request.marker().size() != 0)
|
||||
uint256 startKey;
|
||||
if (auto key = uint256::fromVoidChecked(request.marker()))
|
||||
{
|
||||
key = uint256::fromVoid(request.marker().data());
|
||||
if (key.size() != request.marker().size())
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::INVALID_ARGUMENT, "marker malformed"};
|
||||
return {response, errorStatus};
|
||||
}
|
||||
startKey = *key;
|
||||
}
|
||||
else if (request.marker().size() != 0)
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::INVALID_ARGUMENT, "marker malformed"};
|
||||
return {response, errorStatus};
|
||||
}
|
||||
|
||||
auto e = ledger->sles.end();
|
||||
ReadView::key_type stopKey = ReadView::key_type();
|
||||
if (request.end_marker().size() != 0)
|
||||
if (auto key = uint256::fromVoidChecked(request.end_marker()))
|
||||
{
|
||||
stopKey = uint256::fromVoid(request.end_marker().data());
|
||||
if (stopKey.size() != request.marker().size())
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::INVALID_ARGUMENT, "end marker malformed"};
|
||||
return {response, errorStatus};
|
||||
}
|
||||
e = ledger->sles.upper_bound(stopKey);
|
||||
e = ledger->sles.upper_bound(*key);
|
||||
}
|
||||
else if (request.end_marker().size() != 0)
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::INVALID_ARGUMENT, "end marker malformed"};
|
||||
return {response, errorStatus};
|
||||
}
|
||||
|
||||
int maxLimit = RPC::Tuning::pageLength(true);
|
||||
|
||||
for (auto i = ledger->sles.upper_bound(key); i != e; ++i)
|
||||
for (auto i = ledger->sles.upper_bound(startKey); i != e; ++i)
|
||||
{
|
||||
auto sle = ledger->read(keylet::unchecked((*i)->key()));
|
||||
if (maxLimit-- <= 0)
|
||||
|
||||
@@ -377,23 +377,31 @@ doLedgerEntryGrpc(
|
||||
grpc::Status status = grpc::Status::OK;
|
||||
|
||||
std::shared_ptr<ReadView const> ledger;
|
||||
if (RPC::ledgerFromRequest(ledger, context))
|
||||
if (auto status = RPC::ledgerFromRequest(ledger, context))
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::NOT_FOUND, "ledger not found"};
|
||||
grpc::Status errorStatus;
|
||||
if (status.toErrorCode() == rpcINVALID_PARAMS)
|
||||
{
|
||||
errorStatus = grpc::Status(
|
||||
grpc::StatusCode::INVALID_ARGUMENT, status.message());
|
||||
}
|
||||
else
|
||||
{
|
||||
errorStatus =
|
||||
grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
|
||||
}
|
||||
return {response, errorStatus};
|
||||
}
|
||||
|
||||
std::string const& keyBytes = request.key();
|
||||
auto key = uint256::fromVoid(keyBytes.data());
|
||||
if (keyBytes.size() != key.size())
|
||||
auto key = uint256::fromVoidChecked(request.key());
|
||||
if (!key)
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::INVALID_ARGUMENT, "index malformed"};
|
||||
return {response, errorStatus};
|
||||
}
|
||||
|
||||
auto const sleNode = ledger->read(keylet::unchecked(key));
|
||||
auto const sleNode = ledger->read(keylet::unchecked(*key));
|
||||
if (!sleNode)
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
|
||||
@@ -110,10 +110,19 @@ doLedgerGrpc(RPC::GRPCContext<org::xrpl::rpc::v1::GetLedgerRequest>& context)
|
||||
grpc::Status status = grpc::Status::OK;
|
||||
|
||||
std::shared_ptr<ReadView const> ledger;
|
||||
if (RPC::ledgerFromRequest(ledger, context))
|
||||
if (auto status = RPC::ledgerFromRequest(ledger, context))
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::NOT_FOUND, "ledger not found"};
|
||||
grpc::Status errorStatus;
|
||||
if (status.toErrorCode() == rpcINVALID_PARAMS)
|
||||
{
|
||||
errorStatus = grpc::Status(
|
||||
grpc::StatusCode::INVALID_ARGUMENT, status.message());
|
||||
}
|
||||
else
|
||||
{
|
||||
errorStatus =
|
||||
grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
|
||||
}
|
||||
return {response, errorStatus};
|
||||
}
|
||||
|
||||
|
||||
@@ -456,12 +456,14 @@ doTxGrpc(RPC::GRPCContext<org::xrpl::rpc::v1::GetTransactionRequest>& context)
|
||||
|
||||
TxArgs args;
|
||||
|
||||
std::string const& hashBytes = request.hash();
|
||||
args.hash = uint256::fromVoid(hashBytes.data());
|
||||
if (args.hash.size() != hashBytes.size())
|
||||
if (auto hash = uint256::fromVoidChecked(request.hash()))
|
||||
{
|
||||
args.hash = *hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
grpc::Status errorStatus{
|
||||
grpc::StatusCode::INVALID_ARGUMENT, "ledger hash malformed"};
|
||||
grpc::StatusCode::INVALID_ARGUMENT, "tx hash malformed"};
|
||||
return {response, errorStatus};
|
||||
}
|
||||
|
||||
|
||||
@@ -294,8 +294,11 @@ ledgerFromSpecifier(
|
||||
switch (ledgerCase)
|
||||
{
|
||||
case LedgerCase::kHash: {
|
||||
uint256 ledgerHash = uint256::fromVoid(specifier.hash().data());
|
||||
return getLedger(ledger, ledgerHash, context);
|
||||
if (auto hash = uint256::fromVoidChecked(specifier.hash()))
|
||||
{
|
||||
return getLedger(ledger, *hash, context);
|
||||
}
|
||||
return {rpcINVALID_PARAMS, "ledgerHashMalformed"};
|
||||
}
|
||||
case LedgerCase::kSequence:
|
||||
return getLedger(ledger, specifier.sequence(), context);
|
||||
|
||||
@@ -419,6 +419,14 @@ class ReportingETL_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto [status, reply] =
|
||||
grpcLedgerData(env.closed()->seq(), "bad marker");
|
||||
BEAST_EXPECT(!status.ok());
|
||||
BEAST_EXPECT(
|
||||
status.error_code() == grpc::StatusCode::INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
num_accounts = 3000;
|
||||
|
||||
for (auto i = 0; i < num_accounts; i++)
|
||||
|
||||
Reference in New Issue
Block a user