What changed, and why it matters
This commit is a routine code cleanup that changes several functions to accept a lightweight string view instead of a full std::string object. It does not change what the functions do, only how input strings are passed around. There is no security bug being fixed here.
No security action required. Treat as normal refactoring review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors function signatures across blockfilter, common/messages, net, netaddress, and outputtype modules from const std::string& to std::string_view. It also updates internal implementations (e.g., using addr.ends_with and remove_suffix in SetTor, tfm::format in SetI2P). The behavior of parsing, comparison, and lookup logic remains unchanged. No bounds, validation, or logic changes that would affect security are introduced.
Changed components
src/blockfilter.cpp/hsrc/common/messages.cpp/hsrc/net.cpp/hsrc/netaddress.cpp/hsrc/outputtype.cpp/hInspect captured patch +28 / −25
diff --git a/src/blockfilter.cpp b/src/blockfilter.cpp
index 5e6702cc..94bcc497 100644
--- a/src/blockfilter.cpp
+++ b/src/blockfilter.cpp
@@ -4,6 +4,7 @@
#include <mutex>
#include <set>
+#include <string_view>
#include <blockfilter.h>
#include <crypto/siphash.h>
@@ -151,7 +152,8 @@ const std::string& BlockFilterTypeName(BlockFilterType filter_type)
return it != g_filter_types.end() ? it->second : unknown_retval;
}
-bool BlockFilterTypeByName(const std::string& name, BlockFilterType& filter_type) {
+bool BlockFilterTypeByName(std::string_view name, BlockFilterType& filter_type)
+{
for (const auto& entry : g_filter_types) {
if (entry.second == name) {
filter_type = entry.first;
diff --git a/src/blockfilter.h b/src/blockfilter.h
index 8eab4afa..b70afb90 100644
--- a/src/blockfilter.h
+++ b/src/blockfilter.h
@@ -10,6 +10,7 @@
#include <ios>
#include <set>
#include <string>
+#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -99,7 +100,7 @@ enum class BlockFilterType : uint8_t
const std::string& BlockFilterTypeName(BlockFilterType filter_type);
/** Find a filter type by its human-readable name. */
-bool BlockFilterTypeByName(const std::string& name, BlockFilterType& filter_type);
+bool BlockFilterTypeByName(std::string_view name, BlockFilterType& filter_type);
/** Get a list of known filter types. */
const std::set<BlockFilterType>& AllBlockFilterTypes();
diff --git a/src/common/messages.cpp b/src/common/messages.cpp
index fc0b4a88..e1169c76 100644
--- a/src/common/messages.cpp
+++ b/src/common/messages.cpp
@@ -16,6 +16,7 @@
#include <cassert>
#include <map>
#include <string>
+#include <string_view>
#include <utility>
#include <vector>
@@ -91,7 +92,7 @@ std::string InvalidEstimateModeErrorMessage()
return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\"";
}
-bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode)
+bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode)
{
auto searchkey = ToUpper(mode_string);
for (const auto& pair : FeeModeMap()) {
diff --git a/src/common/messages.h b/src/common/messages.h
index 5827fcce..5d33edac 100644
--- a/src/common/messages.h
+++ b/src/common/messages.h
@@ -12,6 +12,7 @@
#define BITCOIN_COMMON_MESSAGES_H
#include <string>
+#include <string_view>
struct bilingual_str;
@@ -23,7 +24,7 @@ enum class TransactionError;
namespace common {
enum class PSBTError;
-bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode);
+bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode);
std::string StringForFeeReason(FeeReason reason);
std::string FeeModes(const std::string& delimiter);
std::string FeeModeInfo(std::pair<std::string, FeeEstimateMode>& mode);
diff --git a/src/net.cpp b/src/net.cpp
index 066acc84..ef17824f 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -332,7 +332,7 @@ bool IsLocal(const CService& addr)
return mapLocalHost.count(addr) > 0;
}
-bool CConnman::AlreadyConnectedToHost(const std::string& host) const
+bool CConnman::AlreadyConnectedToHost(std::string_view host) const
{
LOCK(m_nodes_mutex);
return std::ranges::any_of(m_nodes, [&host](CNode* node) { return node->m_addr_name == host; });
@@ -3626,7 +3626,7 @@ void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
}
}
-bool CConnman::DisconnectNode(const std::string& strNode)
+bool CConnman::DisconnectNode(std::string_view strNode)
{
LOCK(m_nodes_mutex);
auto it = std::ranges::find_if(m_nodes, [&strNode](CNode* node) { return node->m_addr_name == strNode; });
diff --git a/src/net.h b/src/net.h
index 2b606cbe..6a591c4b 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1246,7 +1246,7 @@ public:
std::map<CNetAddr, LocalServiceInfo> getNetLocalAddresses() const;
uint32_t GetMappedAS(const CNetAddr& addr) const;
void GetNodeStats(std::vector<CNodeStats>& vstats) const;
- bool DisconnectNode(const std::string& node);
+ bool DisconnectNode(std::string_view node);
bool DisconnectNode(const CSubNet& subnet);
bool DisconnectNode(const CNetAddr& addr);
bool DisconnectNode(NodeId id);
@@ -1378,7 +1378,7 @@ private:
* @param[in] host String of the form "host[:port]", e.g. "localhost" or "localhost:8333" or "1.2.3.4:8333".
* @return true if connected to `host`.
*/
- bool AlreadyConnectedToHost(const std::string& host) const;
+ bool AlreadyConnectedToHost(std::string_view host) const;
/**
* Determine whether we're already connected to a given address:port.
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 7eb58f3e..fb2c2540 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -18,6 +18,7 @@
#include <cstdint>
#include <ios>
#include <iterator>
+#include <string_view>
#include <tuple>
using util::ContainsNoNUL;
@@ -208,7 +209,7 @@ static void Checksum(std::span<const uint8_t> addr_pubkey, uint8_t (&checksum)[C
}; // namespace torv3
-bool CNetAddr::SetSpecial(const std::string& addr)
+bool CNetAddr::SetSpecial(std::string_view addr)
{
if (!ContainsNoNUL(addr)) {
return false;
@@ -225,16 +226,11 @@ bool CNetAddr::SetSpecial(const std::string& addr)
return false;
}
-bool CNetAddr::SetTor(const std::string& addr)
+bool CNetAddr::SetTor(std::string_view addr)
{
- static const char* suffix{".onion"};
- static constexpr size_t suffix_len{6};
-
- if (addr.size() <= suffix_len || addr.substr(addr.size() - suffix_len) != suffix) {
- return false;
- }
-
- auto input = DecodeBase32(std::string_view{addr}.substr(0, addr.size() - suffix_len));
+ if (!addr.ends_with(".onion")) return false;
+ addr.remove_suffix(6);
+ auto input = DecodeBase32(addr);
if (!input) {
return false;
@@ -264,7 +260,7 @@ bool CNetAddr::SetTor(const std::string& addr)
return false;
}
-bool CNetAddr::SetI2P(const std::string& addr)
+bool CNetAddr::SetI2P(std::string_view addr)
{
// I2P addresses that we support consist of 52 base32 characters + ".b32.i2p".
static constexpr size_t b32_len{52};
@@ -277,7 +273,7 @@ bool CNetAddr::SetI2P(const std::string& addr)
// Remove the ".b32.i2p" suffix and pad to a multiple of 8 chars, so DecodeBase32()
// can decode it.
- const std::string b32_padded = addr.substr(0, b32_len) + "====";
+ const std::string b32_padded{tfm::format("%s====", addr.substr(0, b32_len))};
auto address_bytes = DecodeBase32(b32_padded);
diff --git a/src/netaddress.h b/src/netaddress.h
index 7c311e2f..48dbf03a 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -18,6 +18,7 @@
#include <cstdint>
#include <ios>
#include <string>
+#include <string_view>
#include <vector>
/**
@@ -151,7 +152,7 @@ public:
* @returns Whether the operation was successful.
* @see CNetAddr::IsTor(), CNetAddr::IsI2P()
*/
- bool SetSpecial(const std::string& addr);
+ bool SetSpecial(std::string_view addr);
bool IsBindAny() const; // INADDR_ANY equivalent
[[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
@@ -279,7 +280,7 @@ private:
* @returns Whether the operation was successful.
* @see CNetAddr::IsTor()
*/
- bool SetTor(const std::string& addr);
+ bool SetTor(std::string_view addr);
/**
* Parse an I2P address and set this object to it.
@@ -288,7 +289,7 @@ private:
* @returns Whether the operation was successful.
* @see CNetAddr::IsI2P()
*/
- bool SetI2P(const std::string& addr);
+ bool SetI2P(std::string_view addr);
/**
* Size of CNetAddr when serialized as ADDRv1 (pre-BIP155) (in bytes).
diff --git a/src/outputtype.cpp b/src/outputtype.cpp
index d4c2d95c..082641f5 100644
--- a/src/outputtype.cpp
+++ b/src/outputtype.cpp
@@ -20,7 +20,7 @@ static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m";
static const std::string OUTPUT_TYPE_STRING_UNKNOWN = "unknown";
-std::optional<OutputType> ParseOutputType(const std::string& type)
+std::optional<OutputType> ParseOutputType(std::string_view type)
{
if (type == OUTPUT_TYPE_STRING_LEGACY) {
return OutputType::LEGACY;
diff --git a/src/outputtype.h b/src/outputtype.h
index 5a6f0539..4dde381b 100644
--- a/src/outputtype.h
+++ b/src/outputtype.h
@@ -12,6 +12,7 @@
#include <array>
#include <optional>
#include <string>
+#include <string_view>
#include <vector>
enum class OutputType {
@@ -29,7 +30,7 @@ static constexpr auto OUTPUT_TYPES = std::array{
OutputType::BECH32M,
};
-std::optional<OutputType> ParseOutputType(const std::string& str);
+std::optional<OutputType> ParseOutputType(std::string_view str);
const std::string& FormatOutputType(OutputType type);
std::string FormatAllOutputTypes();
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.