mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Ensure that switchover vars are initialized before use: (#4527)
Global variables in different TUs are initialized in an undefined order. At least one global variable was accessing a global switchover variable. This caused the switchover variable to be accessed in an uninitialized state. Since the switchover is always explicitly set before transaction processing, this bug can not effect transaction processing, but could effect unit tests (and potentially the value of some global variables). Note: at the time of this patch the offending bug is not yet in production.
This commit is contained in:
@@ -186,7 +186,14 @@ mulRatio(
|
||||
std::uint32_t den,
|
||||
bool roundUp);
|
||||
|
||||
extern LocalValue<bool> stNumberSwitchover;
|
||||
// Since many uses of the number class do not have access to a ledger,
|
||||
// getSTNumberSwitchover needs to be globally accessible.
|
||||
|
||||
bool
|
||||
getSTNumberSwitchover();
|
||||
|
||||
void
|
||||
setSTNumberSwitchover(bool v);
|
||||
|
||||
/** RAII class to set and restore the Number switchover.
|
||||
*/
|
||||
@@ -198,16 +205,16 @@ class NumberSO
|
||||
public:
|
||||
~NumberSO()
|
||||
{
|
||||
*stNumberSwitchover = saved_;
|
||||
setSTNumberSwitchover(saved_);
|
||||
}
|
||||
|
||||
NumberSO(NumberSO const&) = delete;
|
||||
NumberSO&
|
||||
operator=(NumberSO const&) = delete;
|
||||
|
||||
explicit NumberSO(bool v) : saved_(*stNumberSwitchover)
|
||||
explicit NumberSO(bool v) : saved_(getSTNumberSwitchover())
|
||||
{
|
||||
*stNumberSwitchover = v;
|
||||
setSTNumberSwitchover(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,28 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
LocalValue<bool> stNumberSwitchover(true);
|
||||
namespace {
|
||||
|
||||
// Use a static inside a function to help prevent order-of-initialzation issues
|
||||
LocalValue<bool>&
|
||||
getStaticSTNumberSwitchover()
|
||||
{
|
||||
static LocalValue<bool> r{true};
|
||||
return r;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool
|
||||
getSTNumberSwitchover()
|
||||
{
|
||||
return *getStaticSTNumberSwitchover();
|
||||
}
|
||||
|
||||
void
|
||||
setSTNumberSwitchover(bool v)
|
||||
{
|
||||
*getStaticSTNumberSwitchover() = v;
|
||||
}
|
||||
|
||||
/* The range for the mantissa when normalized */
|
||||
static std::int64_t constexpr minMantissa = 1000000000000000ull;
|
||||
@@ -51,7 +72,7 @@ IOUAmount::normalize()
|
||||
return;
|
||||
}
|
||||
|
||||
if (*stNumberSwitchover)
|
||||
if (getSTNumberSwitchover())
|
||||
{
|
||||
Number const v{mantissa_, exponent_};
|
||||
mantissa_ = v.mantissa();
|
||||
@@ -117,7 +138,7 @@ IOUAmount::operator+=(IOUAmount const& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (*stNumberSwitchover)
|
||||
if (getSTNumberSwitchover())
|
||||
{
|
||||
*this = IOUAmount{Number{*this} + Number{other}};
|
||||
return *this;
|
||||
|
||||
Reference in New Issue
Block a user