fix: Fix UBSan issue (#7554)

This commit is contained in:
Mayukha Vadari
2026-06-17 17:50:17 -04:00
committed by GitHub
parent aac6be218a
commit c2ab83c960

View File

@@ -20,11 +20,21 @@
#include <bit>
#include <cstdint>
#include <limits>
#include <memory>
#include <optional>
namespace xrpl {
static std::optional<std::uint32_t>
applyCountDelta(std::uint32_t current, std::int64_t delta)
{
std::int64_t const next = static_cast<std::int64_t>(current) + delta;
if (next < 0 || next > std::numeric_limits<std::uint32_t>::max())
return std::nullopt;
return static_cast<std::uint32_t>(next);
}
std::uint32_t
SponsorshipTransfer::getFlagsMask(PreflightContext const& ctx)
{
@@ -363,12 +373,12 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
return tesSUCCESS;
}
TER
static TER
reduceReserveCount(
ApplyView& view,
AccountID const& account,
AccountID const& sponsor,
int32_t delta)
int64_t delta)
{
if (delta == 0)
return tesSUCCESS;
@@ -380,16 +390,15 @@ reduceReserveCount(
if (!sponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
auto const reserveCount = sponsorSle->getFieldU32(sfReserveCount);
int32_t const afterReserveCount = reserveCount + delta;
if (afterReserveCount < 0)
auto const afterReserveCount = applyCountDelta(sponsorSle->getFieldU32(sfReserveCount), delta);
if (!afterReserveCount)
{
// already checked in preclaim()
UNREACHABLE("xrpl::reduceReserveCount : invalid reserve count");
return tefINTERNAL; // LCOV_EXCL_LINE
}
sponsorSle->at(sfReserveCount) = static_cast<unsigned>(afterReserveCount);
sponsorSle->at(sfReserveCount) = *afterReserveCount;
view.update(sponsorSle);
return tesSUCCESS;
}
@@ -407,16 +416,17 @@ SponsorshipTransfer::doApply()
if (!sponseeSle)
return tefINTERNAL; // LCOV_EXCL_LINE
auto const setSponsorFieldU32 = [](auto const& sle, auto const& field, auto const& delta) {
int32_t const newValue = static_cast<int32_t>(sle->getFieldU32(field)) + delta;
if (newValue < 0)
auto const setSponsorFieldU32 =
[] [[nodiscard]] (auto const& sle, auto const& field, auto const& delta) -> TER {
auto const newValue = applyCountDelta(sle->getFieldU32(field), delta);
if (!newValue)
{
UNREACHABLE("xrpl::SponsorshipTransfer::doApply : Invalid sponsor field value");
return;
return tecINTERNAL; // LCOV_EXCL_LINE
}
sle->at(field) = static_cast<std::uint32_t>(newValue);
sle->at(field) = *newValue;
return tesSUCCESS;
};
if (isObjectSponsor)
@@ -436,7 +446,7 @@ SponsorshipTransfer::doApply()
if (!ownerSle)
return tefINTERNAL; // LCOV_EXCL_LINE
auto const ownerCountDelta = getLedgerEntryOwnerCount(objSle);
std::int64_t const ownerCountDelta = getLedgerEntryOwnerCount(objSle);
auto const& sponsorField = getLedgerEntrySponsorField(objSle, *ownerAccountID);
@@ -446,14 +456,20 @@ SponsorshipTransfer::doApply()
XRPL_ASSERT(!!newSponsorAccountID, "New sponsor is required when creating sponsorship");
// update owner's sponsored count
setSponsorFieldU32(ownerSle, sfSponsoredOwnerCount, ownerCountDelta);
if (auto const ter =
setSponsorFieldU32(ownerSle, sfSponsoredOwnerCount, ownerCountDelta);
!isTesSuccess(ter))
return ter;
view().update(ownerSle);
// increment new sponsor's sponsoring count
auto const newSponsorSle = view().peek(keylet::account(newSponsorAccountID));
if (!newSponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
setSponsorFieldU32(newSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
if (auto const ter =
setSponsorFieldU32(newSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
!isTesSuccess(ter))
return ter;
view().update(newSponsorSle);
// set new sponsor to object
@@ -483,14 +499,20 @@ SponsorshipTransfer::doApply()
auto const oldSponsorSle = view().peek(keylet::account(oldSponsorAccountID));
if (!oldSponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
setSponsorFieldU32(oldSponsorSle, sfSponsoringOwnerCount, -ownerCountDelta);
if (auto const ter =
setSponsorFieldU32(oldSponsorSle, sfSponsoringOwnerCount, -ownerCountDelta);
!isTesSuccess(ter))
return ter;
view().update(oldSponsorSle);
// increment new sponsor's sponsoring count
auto const newSponsorSle = view().peek(keylet::account(newSponsorAccountID));
if (!newSponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
setSponsorFieldU32(newSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
if (auto const ter =
setSponsorFieldU32(newSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
!isTesSuccess(ter))
return ter;
view().update(newSponsorSle);
// set new sponsor to object
@@ -516,11 +538,17 @@ SponsorshipTransfer::doApply()
return tefINTERNAL; // LCOV_EXCL_LINE
// decrement sponsored count
setSponsorFieldU32(sponseeSle, sfSponsoredOwnerCount, -ownerCountDelta);
if (auto const ter =
setSponsorFieldU32(sponseeSle, sfSponsoredOwnerCount, -ownerCountDelta);
!isTesSuccess(ter))
return ter;
view().update(sponseeSle);
// decrement old sponsoring count
setSponsorFieldU32(oldSponsorSle, sfSponsoringOwnerCount, -ownerCountDelta);
if (auto const ter =
setSponsorFieldU32(oldSponsorSle, sfSponsoringOwnerCount, -ownerCountDelta);
!isTesSuccess(ter))
return ter;
view().update(oldSponsorSle);
// remove sponsor from object
@@ -538,7 +566,9 @@ SponsorshipTransfer::doApply()
auto const newSponsorSle = view().peek(keylet::account(newSponsorAccountID));
if (!newSponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
setSponsorFieldU32(newSponsorSle, sfSponsoringAccountCount, 1);
if (auto const ter = setSponsorFieldU32(newSponsorSle, sfSponsoringAccountCount, 1);
!isTesSuccess(ter))
return ter;
view().update(newSponsorSle);
// set new sponsor to account
@@ -553,7 +583,9 @@ SponsorshipTransfer::doApply()
auto const newSponsorSle = view().peek(keylet::account(newSponsorAccountID));
if (!newSponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
setSponsorFieldU32(newSponsorSle, sfSponsoringAccountCount, 1);
if (auto const ter = setSponsorFieldU32(newSponsorSle, sfSponsoringAccountCount, 1);
!isTesSuccess(ter))
return ter;
view().update(newSponsorSle);
// decrement old sponsoring count
@@ -561,7 +593,9 @@ SponsorshipTransfer::doApply()
auto const oldSponsorSle = view().peek(keylet::account(oldSponsor));
if (!oldSponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
setSponsorFieldU32(oldSponsorSle, sfSponsoringAccountCount, -1);
if (auto const ter = setSponsorFieldU32(oldSponsorSle, sfSponsoringAccountCount, -1);
!isTesSuccess(ter))
return ter;
view().update(oldSponsorSle);
// set new sponsor to account
@@ -579,7 +613,9 @@ SponsorshipTransfer::doApply()
auto const oldSponsorSle = view().peek(keylet::account(oldSponsorAccountID));
if (!oldSponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
setSponsorFieldU32(oldSponsorSle, sfSponsoringAccountCount, -1);
if (auto const ter = setSponsorFieldU32(oldSponsorSle, sfSponsoringAccountCount, -1);
!isTesSuccess(ter))
return ter;
view().update(oldSponsorSle);
}
}