Add unit tests for normalizeToRange

- Steal changes from @pratik's #6150 to avoid UB
This commit is contained in:
Ed Hennis
2026-01-28 17:28:27 -05:00
parent 5ab62f4422
commit 822023d8a4
4 changed files with 221 additions and 14 deletions

View File

@@ -874,14 +874,22 @@ Number::normalizeToRange(T minMantissa, T maxMantissa) const
int exponent = exponent_;
if constexpr (std::is_unsigned_v<T>)
{
XRPL_ASSERT_PARTS(
!negative,
"xrpl::Number::normalizeToRange",
"Number is non-negative for unsigned range.");
// To avoid logical errors in release builds, throw if the Number is
// negative for an unsigned range.
if (negative)
throw std::runtime_error(
"Number::normalizeToRange: Number is negative for "
"unsigned range.");
}
Number::normalize(negative, mantissa, exponent, minMantissa, maxMantissa);
// Cast mantissa to signed type first to avoid unsigned integer overflow
// when multiplying by negative sign
// Cast mantissa to signed type first (if T is a signed type) to avoid
// unsigned integer overflow when multiplying by negative sign
T signedMantissa = static_cast<T>(mantissa);
if (negative)
signedMantissa = -signedMantissa;

View File

@@ -568,6 +568,10 @@ STAmount::fromNumber(A const& a, Number const& number)
return STAmount{asset, intValue, 0, negative};
}
XRPL_ASSERT_PARTS(
working.signum() >= 0,
"ripple::STAmount::fromNumber",
"non-negative Number to normalize");
auto const [mantissa, exponent] =
working.normalizeToRange(cMinValue, cMaxValue);