Add safe_cast (RIPD-1702):

This change ensures that no overflow can occur when casting
between enums and integral types.
This commit is contained in:
Howard Hinnant
2018-12-21 17:13:58 -05:00
committed by Nik Bougalis
parent 494724578a
commit 148bbf4e8f
35 changed files with 213 additions and 86 deletions

View File

@@ -1474,6 +1474,7 @@ install (
src/ripple/basics/FileUtilities.h
src/ripple/basics/LocalValue.h
src/ripple/basics/Log.h
src/ripple/basics/safe_cast.h
src/ripple/basics/Slice.h
src/ripple/basics/StringUtilities.h
src/ripple/basics/ToString.h

View File

@@ -46,6 +46,7 @@
#include <ripple/app/tx/apply.h>
#include <ripple/basics/ByteUtilities.h>
#include <ripple/basics/ResolverAsio.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/Sustain.h>
#include <ripple/basics/PerfLog.h>
#include <ripple/json/json_reader.h>
@@ -1068,7 +1069,7 @@ public:
*db << "PRAGMA page_count;", soci::into(pageCount);
std::uint32_t freePages = maxPages - pageCount;
std::uint64_t freeSpace =
static_cast<std::uint64_t>(freePages) * pageSize;
safe_cast<std::uint64_t>(freePages) * pageSize;
JLOG(m_journal.info())
<< "Transaction DB pathname: " << dbPath.string()
<< "; file size: " << dbSize.value_or(-1) << " bytes"

View File

@@ -42,6 +42,7 @@
#include <ripple/basics/base64.h>
#include <ripple/basics/mulDiv.h>
#include <ripple/basics/PerfLog.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/UptimeClock.h>
#include <ripple/core/ConfigSections.h>
#include <ripple/crypto/csprng.h>
@@ -1664,7 +1665,7 @@ void NetworkOPsImp::pubServer ()
if(f.em)
{
auto const loadFactor =
std::max(static_cast<std::uint64_t>(f.loadFactorServer),
std::max(safe_cast<std::uint64_t>(f.loadFactorServer),
mulDiv(f.em->openLedgerFeeLevel, f.loadBaseServer,
f.em->referenceFeeLevel).second);
@@ -2121,7 +2122,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters)
{
if (when)
info[jss::validator_list_expires] =
static_cast<Json::UInt>(when->time_since_epoch().count());
safe_cast<Json::UInt>(when->time_since_epoch().count());
else
info[jss::validator_list_expires] = 0;
}
@@ -2227,7 +2228,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters)
auto const loadBaseFeeEscalation =
escalationMetrics.referenceFeeLevel;
auto const loadFactor = std::max(static_cast<std::uint64_t>(loadFactorServer),
auto const loadFactor = std::max(safe_cast<std::uint64_t>(loadFactorServer),
mulDiv(loadFactorFeeEscalation, loadBaseServer, loadBaseFeeEscalation).second);
if (!human)

View File

@@ -20,6 +20,7 @@
#include <ripple/app/misc/LoadFeeTrack.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/core/Config.h>
#include <ripple/ledger/ReadView.h>
#include <ripple/protocol/STAmount.h>
@@ -149,8 +150,8 @@ scaleFeeLoad(std::uint64_t fee, LoadFeeTrack const& feeTrack,
// The denominator of the fraction we're trying to compute.
// fees.units and lftNormalFee are both 32 bit,
// so the multiplication can't overflow.
auto den = static_cast<std::uint64_t>(fees.units)
* static_cast<std::uint64_t>(feeTrack.getLoadBase());
auto den = safe_cast<std::uint64_t>(fees.units)
* safe_cast<std::uint64_t>(feeTrack.getLoadBase());
// Reduce fee * baseFee * feeFactor / (fees.units * lftNormalFee)
// to lowest terms.
lowestTerms(fee, den);

View File

@@ -22,6 +22,7 @@
#include <ripple/app/misc/HashRouter.h>
#include <ripple/basics/chrono.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/conditions/Condition.h>
#include <ripple/conditions/Fulfillment.h>
#include <ripple/ledger/ApplyView.h>
@@ -358,7 +359,7 @@ EscrowFinish::calculateBaseFee (
if (auto const fb = tx[~sfFulfillment])
{
extraFee += view.fees().units *
(32 + static_cast<std::uint64_t> (fb->size() / 16));
(32 + safe_cast<std::uint64_t> (fb->size() / 16));
}
return Transactor::calculateBaseFee (view, tx) + extraFee;

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/Sustain.h>
#include <ripple/beast/core/CurrentThreadName.h>
#include <boost/format.hpp>
@@ -41,8 +42,8 @@ namespace ripple {
static auto const sleepBeforeWaiting = 10;
static auto const sleepBetweenWaits = 1;
static pid_t pManager = static_cast<pid_t> (0);
static pid_t pChild = static_cast<pid_t> (0);
static pid_t pManager = safe_cast<pid_t> (0);
static pid_t pChild = safe_cast<pid_t> (0);
static void pass_signal (int a)
{

View File

@@ -0,0 +1,78 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2018 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_BASICS_SAFE_CAST_H_INCLUDED
#define RIPPLE_BASICS_SAFE_CAST_H_INCLUDED
#include <type_traits>
namespace ripple {
// safe_cast adds compile-time checks to a static_cast to ensure that
// the destination can hold all values of the source. This is particularly
// handy when the source or destination is an enumeration type.
template <class Dest, class Src>
inline
constexpr
std::enable_if_t
<
std::is_integral<Dest>::value && std::is_integral<Src>::value,
Dest
>
safe_cast(Src s) noexcept
{
static_assert(std::is_signed<Dest>::value || std::is_unsigned<Src>::value,
"Cannot cast signed to unsigned");
constexpr unsigned not_same = std::is_signed<Dest>::value !=
std::is_signed<Src>::value;
static_assert(sizeof(Dest) >= sizeof(Src) + not_same,
"Destination is too small to hold all values of source");
return static_cast<Dest>(s);
}
template <class Dest, class Src>
inline
constexpr
std::enable_if_t
<
std::is_enum<Dest>::value && std::is_integral<Src>::value,
Dest
>
safe_cast(Src s) noexcept
{
return static_cast<Dest>(safe_cast<std::underlying_type_t<Dest>>(s));
}
template <class Dest, class Src>
inline
constexpr
std::enable_if_t
<
std::is_integral<Dest>::value && std::is_enum<Src>::value,
Dest
>
safe_cast(Src s) noexcept
{
return safe_cast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
}
} // ripple
#endif

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/conditions/Condition.h>
#include <ripple/conditions/Fulfillment.h>
#include <ripple/conditions/impl/PreimageSha256.h>
@@ -116,31 +117,32 @@ Fulfillment::deserialize(
std::unique_ptr<Fulfillment> f;
switch (static_cast<Type>(p.tag))
using TagType = decltype(p.tag);
switch (p.tag)
{
case Type::preimageSha256:
case safe_cast<TagType>(Type::preimageSha256):
f = PreimageSha256::deserialize(Slice(s.data(), p.length), ec);
if (ec)
return {};
s += p.length;
break;
case Type::prefixSha256:
case safe_cast<TagType>(Type::prefixSha256):
ec = error::unsupported_type;
return {};
break;
case Type::thresholdSha256:
case safe_cast<TagType>(Type::thresholdSha256):
ec = error::unsupported_type;
return {};
break;
case Type::rsaSha256:
case safe_cast<TagType>(Type::rsaSha256):
ec = error::unsupported_type;
return {};
break;
case Type::ed25519Sha256:
case safe_cast<TagType>(Type::ed25519Sha256):
ec = error::unsupported_type;
return {};

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/conditions/impl/error.h>
#include <system_error>
#include <string>
@@ -41,7 +42,7 @@ public:
std::string
message(int ev) const override
{
switch (static_cast<error>(ev))
switch (safe_cast<error>(ev))
{
case error::unsupported_type:
return "Specification: Requested type not supported.";
@@ -136,7 +137,7 @@ std::error_code
make_error_code(error ev)
{
return std::error_code {
static_cast<std::underlying_type<error>::type>(ev),
safe_cast<std::underlying_type<error>::type>(ev),
detail::get_cryptoconditions_error_category()
};
}

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLE_LEDGER_APPLYVIEW_H_INCLUDED
#define RIPPLE_LEDGER_APPLYVIEW_H_INCLUDED
#include <ripple/basics/safe_cast.h>
#include <ripple/ledger/RawView.h>
#include <ripple/ledger/ReadView.h>
#include <boost/optional.hpp>
@@ -27,6 +28,7 @@
namespace ripple {
enum ApplyFlags
: std::uint32_t
{
tapNONE = 0x00,
@@ -48,14 +50,14 @@ ApplyFlags
operator|(ApplyFlags const& lhs,
ApplyFlags const& rhs)
{
return static_cast<ApplyFlags>(
static_cast<std::underlying_type_t<ApplyFlags>>(lhs) |
static_cast<std::underlying_type_t<ApplyFlags>>(rhs));
return safe_cast<ApplyFlags>(
safe_cast<std::underlying_type_t<ApplyFlags>>(lhs) |
safe_cast<std::underlying_type_t<ApplyFlags>>(rhs));
}
static_assert((tapPREFER_QUEUE | tapRETRY) == static_cast<ApplyFlags>(0x60),
static_assert((tapPREFER_QUEUE | tapRETRY) == safe_cast<ApplyFlags>(0x60u),
"ApplyFlags operator |");
static_assert((tapRETRY | tapPREFER_QUEUE) == static_cast<ApplyFlags>(0x60),
static_assert((tapRETRY | tapPREFER_QUEUE) == safe_cast<ApplyFlags>(0x60u),
"ApplyFlags operator |");
constexpr
@@ -63,9 +65,9 @@ ApplyFlags
operator&(ApplyFlags const& lhs,
ApplyFlags const& rhs)
{
return static_cast<ApplyFlags>(
static_cast<std::underlying_type_t<ApplyFlags>>(lhs) &
static_cast<std::underlying_type_t<ApplyFlags>>(rhs));
return safe_cast<ApplyFlags>(
safe_cast<std::underlying_type_t<ApplyFlags>>(lhs) &
safe_cast<std::underlying_type_t<ApplyFlags>>(rhs));
}
static_assert((tapPREFER_QUEUE & tapRETRY) == tapNONE,
@@ -77,11 +79,11 @@ constexpr
ApplyFlags
operator~(ApplyFlags const& flags)
{
return static_cast<ApplyFlags>(
~static_cast<std::underlying_type_t<ApplyFlags>>(flags));
return safe_cast<ApplyFlags>(
~safe_cast<std::underlying_type_t<ApplyFlags>>(flags));
}
static_assert(~tapRETRY == static_cast<ApplyFlags>(~0x20),
static_assert(~tapRETRY == safe_cast<ApplyFlags>(0xFFFFFFDFu),
"ApplyFlags operator ~");
inline

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLE_LEDGER_CASHDIFF_H_INCLUDED
#define RIPPLE_LEDGER_CASHDIFF_H_INCLUDED
#include <ripple/basics/safe_cast.h>
#include <ripple/protocol/STAmount.h>
#include <memory> // std::unique_ptr
@@ -44,13 +45,13 @@ inline CashFilter operator| (CashFilter lhs, CashFilter rhs)
{
using ul_t = std::underlying_type<CashFilter>::type;
return static_cast<CashFilter>(
static_cast<ul_t>(lhs) | static_cast<ul_t>(rhs));
safe_cast<ul_t>(lhs) | safe_cast<ul_t>(rhs));
}
inline CashFilter operator& (CashFilter lhs, CashFilter rhs)
{
using ul_t = std::underlying_type<CashFilter>::type;
return static_cast<CashFilter>(
static_cast<ul_t>(lhs) & static_cast<ul_t>(rhs));
safe_cast<ul_t>(lhs) & safe_cast<ul_t>(rhs));
}
//------------------------------------------------------------------------------

View File

@@ -29,6 +29,7 @@ namespace ripple {
/** The types of node objects. */
enum NodeObjectType
: std::uint32_t
{
hotUNKNOWN = 0,
hotLEDGER = 1,

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/nodestore/impl/DecodedBlob.h>
#include <algorithm>
#include <cassert>
@@ -48,7 +49,7 @@ DecodedBlob::DecodedBlob (void const* key, void const* value, int valueBytes)
if (valueBytes > 8)
{
unsigned char const* byte = static_cast <unsigned char const*> (value);
m_objectType = static_cast <NodeObjectType> (byte [8]);
m_objectType = safe_cast <NodeObjectType> (byte [8]);
}
if (valueBytes > 9)

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/overlay/Message.h>
#include <ripple/overlay/impl/TrafficCount.h>
#include <cstdint>
@@ -38,7 +39,7 @@ Message::Message (::google::protobuf::Message const& message, int type)
message.SerializeToArray (&mBuffer [Message::kHeaderBytes], messageBytes);
}
mCategory = static_cast<int>(TrafficCount::categorize
mCategory = safe_cast<int>(TrafficCount::categorize
(message, type, false));
}

View File

@@ -30,6 +30,7 @@
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/app/tx/apply.h>
#include <ripple/basics/random.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/UptimeClock.h>
#include <ripple/beast/core/LexicalCast.h>
#include <ripple/beast/core/SemanticVersion.h>
@@ -192,7 +193,7 @@ PeerImp::send (Message::pointer const& m)
return;
overlay_.reportTraffic (
static_cast<TrafficCount::category>(m->getCategory()),
safe_cast<TrafficCount::category>(m->getCategory()),
false, static_cast<int>(m->getBuffer().size()));
auto sendq_size = send_queue_.size();

View File

@@ -21,6 +21,7 @@
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/main/Application.h>
#include <ripple/basics/base64.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/beast/rfc2616.h>
#include <ripple/beast/core/LexicalCast.h>
#include <ripple/protocol/digest.h>
@@ -226,11 +227,11 @@ parseHello (bool request, boost::beast::http::fields const& h, beast::Journal jo
if (versions.empty())
return boost::none;
hello.set_protoversion(
(static_cast<std::uint32_t>(versions.back().first) << 16) |
(static_cast<std::uint32_t>(versions.back().second)));
(safe_cast<std::uint32_t>(versions.back().first) << 16) |
(safe_cast<std::uint32_t>(versions.back().second)));
hello.set_protoversionmin(
(static_cast<std::uint32_t>(versions.front().first) << 16) |
(static_cast<std::uint32_t>(versions.front().second)));
(safe_cast<std::uint32_t>(versions.front().first) << 16) |
(safe_cast<std::uint32_t>(versions.front().second)));
}
{
@@ -362,7 +363,7 @@ verifyHello (protocol::TMHello const& h,
JLOG(journal.trace()) <<
"Connect: time offset " <<
static_cast<std::int64_t>(ourTime) - h.nettime();
safe_cast<std::int64_t>(ourTime) - h.nettime();
}
if (h.protoversionmin () > to_packed (BuildInfo::getCurrentProtocol()))

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLE_OVERLAY_TRAFFIC_H_INCLUDED
#define RIPPLE_OVERLAY_TRAFFIC_H_INCLUDED
#include <ripple/basics/safe_cast.h>
#include <ripple/protocol/messages.h>
#include <atomic>
@@ -99,7 +100,7 @@ public:
{
for (category i = category::CT_base;
i <= category::CT_unknown;
i = static_cast<category>(static_cast<int>(i) + 1))
i = safe_cast<category>(safe_cast<std::underlying_type_t<category>>(i) + 1))
{
counts_[i];
}

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLE_PROTOCOL_SFIELD_H_INCLUDED
#define RIPPLE_PROTOCOL_SFIELD_H_INCLUDED
#include <ripple/basics/safe_cast.h>
#include <ripple/json/json_value.h>
#include <cstdint>
#include <utility>
@@ -86,7 +87,7 @@ inline
int
field_code(SerializedTypeID id, int index)
{
return (static_cast<int>(id) << 16) | index;
return (safe_cast<int>(id) << 16) | index;
}
// constexpr

View File

@@ -20,12 +20,13 @@
#ifndef RIPPLE_PROTOCOL_SERIALIZER_H_INCLUDED
#define RIPPLE_PROTOCOL_SERIALIZER_H_INCLUDED
#include <ripple/protocol/SField.h>
#include <ripple/basics/base_uint.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Buffer.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/Slice.h>
#include <ripple/beast/crypto/secure_erase.h>
#include <ripple/protocol/SField.h>
#include <cassert>
#include <cstdint>
#include <iomanip>
@@ -158,7 +159,7 @@ public:
int addFieldID (int type, int name);
int addFieldID (SerializedTypeID type, int name)
{
return addFieldID (static_cast<int> (type), name);
return addFieldID (safe_cast<int> (type), name);
}
// DEPRECATED
@@ -266,7 +267,7 @@ public:
std::setw (2) <<
std::hex <<
std::setfill ('0') <<
static_cast<unsigned int>(element);
safe_cast<unsigned int>(element);
}
return h.str ();
}

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLE_PROTOCOL_TER_H_INCLUDED
#define RIPPLE_PROTOCOL_TER_H_INCLUDED
#include <ripple/basics/safe_cast.h>
#include <ripple/json/json_value.h>
#include <boost/optional.hpp>
@@ -270,22 +271,22 @@ enum TECcodes : TERUnderlyingType
// For generic purposes, a free function that returns the value of a TE*codes.
constexpr TERUnderlyingType TERtoInt (TELcodes v)
{ return static_cast<TERUnderlyingType>(v); }
{ return safe_cast<TERUnderlyingType>(v); }
constexpr TERUnderlyingType TERtoInt (TEMcodes v)
{ return static_cast<TERUnderlyingType>(v); }
{ return safe_cast<TERUnderlyingType>(v); }
constexpr TERUnderlyingType TERtoInt (TEFcodes v)
{ return static_cast<TERUnderlyingType>(v); }
{ return safe_cast<TERUnderlyingType>(v); }
constexpr TERUnderlyingType TERtoInt (TERcodes v)
{ return static_cast<TERUnderlyingType>(v); }
{ return safe_cast<TERUnderlyingType>(v); }
constexpr TERUnderlyingType TERtoInt (TEScodes v)
{ return static_cast<TERUnderlyingType>(v); }
{ return safe_cast<TERUnderlyingType>(v); }
constexpr TERUnderlyingType TERtoInt (TECcodes v)
{ return static_cast<TERUnderlyingType>(v); }
{ return safe_cast<TERUnderlyingType>(v); }
//------------------------------------------------------------------------------
// Template class that is specific to selected ranges of error codes. The

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/protocol/SField.h>
#include <cassert>
#include <map>
@@ -358,7 +359,7 @@ SField::getField (int code)
if (it != unknownCodeToField.end ())
return * (it->second);
return *(unknownCodeToField[code] = std::unique_ptr<SField const>(
new SField(static_cast<SerializedTypeID>(type), field)));
new SField(safe_cast<SerializedTypeID>(type), field)));
}
}
@@ -385,7 +386,7 @@ std::string SField::getName () const
if (fieldValue == 0)
return "";
return std::to_string(static_cast<int> (fieldType)) + "/" +
return std::to_string(safe_cast<int> (fieldType)) + "/" +
std::to_string(fieldValue);
}

View File

@@ -20,6 +20,7 @@
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/protocol/SystemParameters.h>
#include <ripple/protocol/STAmount.h>
@@ -246,13 +247,13 @@ STAmount::STAmount (Issue const& issue,
STAmount::STAmount (Issue const& issue,
std::uint32_t mantissa, int exponent, bool negative)
: STAmount (issue, static_cast<std::uint64_t>(mantissa), exponent, negative)
: STAmount (issue, safe_cast<std::uint64_t>(mantissa), exponent, negative)
{
}
STAmount::STAmount (Issue const& issue,
int mantissa, int exponent)
: STAmount (issue, static_cast<std::int64_t>(mantissa), exponent)
: STAmount (issue, safe_cast<std::int64_t>(mantissa), exponent)
{
}

View File

@@ -19,6 +19,7 @@
#include <ripple/basics/Log.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/protocol/LedgerFormats.h>
#include <ripple/protocol/STInteger.h>
#include <ripple/protocol/TxFormats.h>
@@ -98,7 +99,7 @@ STUInt16::getText () const
if (getFName () == sfLedgerEntryType)
{
auto item = LedgerFormats::getInstance ().findByType (
static_cast <LedgerEntryType> (value_));
safe_cast<LedgerEntryType> (value_));
if (item != nullptr)
return item->getName ();
@@ -107,7 +108,7 @@ STUInt16::getText () const
if (getFName () == sfTransactionType)
{
auto item =TxFormats::getInstance().findByType (
static_cast <TxType> (value_));
safe_cast<TxType> (value_));
if (item != nullptr)
return item->getName ();
@@ -123,7 +124,7 @@ STUInt16::getJson (int) const
if (getFName () == sfLedgerEntryType)
{
auto item = LedgerFormats::getInstance ().findByType (
static_cast <LedgerEntryType> (value_));
safe_cast<LedgerEntryType> (value_));
if (item != nullptr)
return item->getName ();
@@ -132,7 +133,7 @@ STUInt16::getJson (int) const
if (getFName () == sfTransactionType)
{
auto item = TxFormats::getInstance().findByType (
static_cast <TxType> (value_));
safe_cast<TxType> (value_));
if (item != nullptr)
return item->getName ();

View File

@@ -19,6 +19,7 @@
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/JsonFields.h>
@@ -32,6 +33,10 @@ STLedgerEntry::STLedgerEntry (Keylet const& k)
, key_ (k.key)
, type_ (k.type)
{
if (!(0u <= type_ &&
type_ <= std::min<unsigned>(std::numeric_limits<std::uint16_t>::max(),
std::numeric_limits<std::underlying_type_t<LedgerEntryType>>::max())))
Throw<std::runtime_error> ("invalid ledger entry type: out of range");
auto const format =
LedgerFormats::getInstance().findByType (type_);
@@ -66,7 +71,7 @@ STLedgerEntry::STLedgerEntry (
void STLedgerEntry::setSLEType ()
{
auto format = LedgerFormats::getInstance().findByType (
static_cast <LedgerEntryType> (
safe_cast <LedgerEntryType> (
getFieldU16 (sfLedgerEntryType)));
if (format == nullptr)

View File

@@ -18,6 +18,7 @@
//==============================================================================
#include <ripple/basics/contract.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/LedgerFormats.h>
@@ -275,6 +276,9 @@ static boost::optional<detail::STVar> parseLeaf (
TxType const txType (TxFormats::getInstance().
findTypeByName (strValue));
if (txType == ttINVALID)
Throw<std::runtime_error>(
"Invalid transaction format name");
ret = detail::make_stvar <STUInt16> (field,
static_cast <std::uint16_t> (txType));
@@ -287,6 +291,13 @@ static boost::optional<detail::STVar> parseLeaf (
LedgerFormats::getInstance().
findTypeByName (strValue));
if (!(0u <= type &&
type <= std::min<unsigned>(
std::numeric_limits<std::uint16_t>::max(),
std::numeric_limits<std::underlying_type_t
<LedgerEntryType>>::max())))
Throw<std::runtime_error>(
"Invalid ledger entry type: out of range");
ret = detail::make_stvar <STUInt16> (field,
static_cast <std::uint16_t> (type));
@@ -346,7 +357,7 @@ static boost::optional<detail::STVar> parseLeaf (
else if (value.isUInt ())
{
ret = detail::make_stvar <STUInt32> (field,
static_cast <std::uint32_t> (value.asUInt ()));
safe_cast <std::uint32_t> (value.asUInt ()));
}
else
{
@@ -378,7 +389,7 @@ static boost::optional<detail::STVar> parseLeaf (
else if (value.isUInt ())
{
ret = detail::make_stvar <STUInt64> (field,
static_cast <std::uint64_t> (value.asUInt ()));
safe_cast <std::uint64_t> (value.asUInt ()));
}
else
{

View File

@@ -17,6 +17,10 @@
*/
//==============================================================================
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/protocol/STTx.h>
#include <ripple/protocol/HashPrefix.h>
#include <ripple/protocol/JsonFields.h>
@@ -27,9 +31,6 @@
#include <ripple/protocol/STArray.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/UintTypes.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/json/to_string.h>
#include <boost/format.hpp>
#include <array>
@@ -49,7 +50,7 @@ auto getTxFormat (TxType type)
Throw<std::runtime_error> (
"Invalid transaction type " +
std::to_string (
static_cast<std::underlying_type_t<TxType>>(type)));
safe_cast<std::underlying_type_t<TxType>>(type)));
}
return format;
@@ -58,7 +59,7 @@ auto getTxFormat (TxType type)
STTx::STTx (STObject&& object) noexcept (false)
: STObject (std::move (object))
{
tx_type_ = static_cast <TxType> (getFieldU16 (sfTransactionType));
tx_type_ = safe_cast<TxType> (getFieldU16 (sfTransactionType));
applyTemplate (getTxFormat (tx_type_)->elements); // may throw
tid_ = getHash(HashPrefix::transactionID);
}
@@ -74,7 +75,7 @@ STTx::STTx (SerialIter& sit) noexcept (false)
if (set (sit))
Throw<std::runtime_error> ("Transaction contains an object terminator");
tx_type_ = static_cast<TxType> (getFieldU16 (sfTransactionType));
tx_type_ = safe_cast<TxType> (getFieldU16 (sfTransactionType));
applyTemplate (getTxFormat (tx_type_)->elements); // May throw
tid_ = getHash(HashPrefix::transactionID);
@@ -92,7 +93,7 @@ STTx::STTx (
assembler (*this);
tx_type_ = static_cast<TxType>(getFieldU16 (sfTransactionType));
tx_type_ = safe_cast<TxType>(getFieldU16 (sfTransactionType));
if (tx_type_ != type)
LogicError ("Transaction type was mutated during assembly");
@@ -523,7 +524,7 @@ isPseudoTx(STObject const& tx)
auto t = tx[~sfTransactionType];
if (!t)
return false;
auto tt = static_cast<TxType>(*t);
auto tt = safe_cast<TxType>(*t);
return tt == ttAMENDMENT || tt == ttFEE;
}

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/protocol/tokens.h>
#include <ripple/protocol/digest.h>
#include <boost/container/small_vector.hpp>
@@ -166,7 +167,7 @@ encodeToken (TokenType type,
// Lay the data out as
// <type><token><checksum>
buf[0] = static_cast<std::underlying_type_t <TokenType>>(type);
buf[0] = safe_cast<std::underlying_type_t <TokenType>>(type);
if (size)
std::memcpy(buf.data() + 1, token, size);
checksum(buf.data() + 1 + size, buf.data(), 1 + size);
@@ -259,14 +260,14 @@ std::string
decodeBase58Token (std::string const& s,
TokenType type, InverseArray const& inv)
{
auto ret = decodeBase58(s, inv);
std::string const ret = decodeBase58(s, inv);
// Reject zero length tokens
if (ret.size() < 6)
return {};
// The type must match.
if (type != static_cast<TokenType>(ret[0]))
if (type != safe_cast<TokenType>(static_cast<std::uint8_t>(ret[0])))
return {};
// And the checksum must as well.

View File

@@ -864,12 +864,11 @@ ServerHandlerImp::processRequest (Port const& port,
}
auto response = to_string (reply);
rpc_time_.notify (static_cast <beast::insight::Event::value_type> (
rpc_time_.notify (
std::chrono::duration_cast <std::chrono::milliseconds> (
std::chrono::high_resolution_clock::now () - start)));
std::chrono::high_resolution_clock::now () - start));
++rpc_requests_;
rpc_size_.notify (static_cast <beast::insight::Event::value_type> (
response.size ()));
rpc_size_.notify (beast::insight::Event::value_type{response.size()});
response += '\n';

View File

@@ -187,8 +187,8 @@ ShardArchiveHandler::complete(path dstPath)
auto const mode {ptr->app_.getOPs().getOperatingMode()};
if (ptr->validate_ && mode != NetworkOPs::omFULL)
{
timer_.expires_from_now(static_cast<std::chrono::seconds>(
(NetworkOPs::omFULL - mode) * 10));
timer_.expires_from_now(std::chrono::seconds{
(NetworkOPs::omFULL - mode) * 10});
timer_.async_wait(
[=, dstPath = std::move(dstPath), ptr = std::move(ptr)]
(boost::system::error_code const& ec)

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLE_SERVER_BASEWSPEER_H_INCLUDED
#define RIPPLE_SERVER_BASEWSPEER_H_INCLUDED
#include <ripple/basics/safe_cast.h>
#include <ripple/server/impl/BasePeer.h>
#include <ripple/protocol/BuildInfo.h>
#include <ripple/beast/utility/rngfill.h>
@@ -214,8 +215,9 @@ send(std::shared_ptr<WSMsg> w)
{
JLOG(this->j_.info()) <<
"closing slow client";
cr_.code = static_cast<boost::beast::websocket::close_code>(4000);
cr_.reason = "Client is too slow.";
cr_.code = safe_cast<decltype(cr_.code)>
(boost::beast::websocket::close_code::policy_error);
cr_.reason = "Policy error: client is too slow.";
wq_.erase(std::next(wq_.begin()), wq_.end());
close();
return;

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <ripple/server/Port.h>
#include <ripple/beast/rfc2616.h>
#include <ripple/beast/core/LexicalCast.h>
@@ -192,7 +193,7 @@ parse_Port (ParsedPort& port, Section const& section, std::ostream& log)
{
try
{
port.limit = static_cast<int> (
port.limit = safe_cast<int> (
beast::lexicalCastThrow<std::uint16_t>(lim));
}
catch (std::exception const&)

View File

@@ -19,6 +19,7 @@
#include <ripple/app/paths/RippleCalc.h>
#include <ripple/app/paths/impl/Steps.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/core/Config.h>
#include <ripple/ledger/ApplyViewImpl.h>
#include <ripple/ledger/PaymentSandbox.h>
@@ -183,6 +184,7 @@ allpe(AccountID const& a, Issue const& iss)
class ElementComboIter
{
enum class SB /*state bit*/
: std::uint16_t
{ acc,
iss,
cur,
@@ -200,7 +202,7 @@ class ElementComboIter
last };
std::uint16_t state_ = 0;
static_assert(static_cast<size_t>(SB::last) <= sizeof(decltype(state_)) * 8, "");
static_assert(safe_cast<size_t>(SB::last) <= sizeof(decltype(state_)) * 8, "");
STPathElement const* prev_ = nullptr;
// disallow iss and cur to be specified with acc is specified (simplifies some tests)
bool const allowCompound_ = false;
@@ -208,7 +210,7 @@ class ElementComboIter
bool
has(SB s) const
{
return state_ & (1 << static_cast<int>(s));
return state_ & (1 << safe_cast<int>(s));
}
bool

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/basics/safe_cast.h>
#include <test/jtx/Account.h>
#include <test/jtx/amount.h>
#include <cassert>
@@ -119,7 +120,7 @@ PrettyAmount
IOU::operator()(detail::epsilon_multiple m) const
{
return { STAmount(issue(),
static_cast<std::uint64_t>(m.n), -81),
safe_cast<std::uint64_t>(m.n), -81),
account.name() };
}

View File

@@ -21,6 +21,7 @@
#include <ripple/nodestore/DummyScheduler.h>
#include <ripple/nodestore/Manager.h>
#include <ripple/basics/BasicConfig.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/unity/rocksdb.h>
#include <ripple/beast/utility/temp_dir.h>
#include <ripple/beast/xor_shift_engine.h>
@@ -121,7 +122,7 @@ public:
Blob value(d_size_(gen_));
rngcpy (&value[0], value.size(), gen_);
return NodeObject::createObject (
static_cast<NodeObjectType>(d_type_(gen_)),
safe_cast<NodeObjectType>(d_type_(gen_)),
std::move(value), key);
}

View File

@@ -19,6 +19,7 @@
#include <ripple/peerfinder/impl/Livecache.h>
#include <ripple/basics/chrono.h>
#include <ripple/basics/safe_cast.h>
#include <ripple/beast/unit_test.h>
#include <ripple/beast/clock/manual_clock.h>
#include <test/beast/IPEndpointCommon.h>
@@ -134,7 +135,7 @@ public:
add(
beast::IP::randomEP(true),
c,
ripple::rand_int(0, static_cast<int>(Tuning::maxHops + 1)));
ripple::rand_int(0, safe_cast<int>(Tuning::maxHops + 1)));
auto h = c.hops.histogram();
if(! BEAST_EXPECT(! h.empty()))
return;
@@ -159,7 +160,7 @@ public:
add(
beast::IP::randomEP(true),
c,
ripple::rand_int(0, static_cast<int>(Tuning::maxHops + 1)));
ripple::rand_int(0, safe_cast<int>(Tuning::maxHops + 1)));
using at_hop = std::vector <ripple::PeerFinder::Endpoint>;
using all_hops = std::array <at_hop, 1 + Tuning::maxHops + 1>;