mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-19 09:53:47 +01:00
Merge #21328: net, refactor: pass uint16 CService::port as uint16
52dd40a9fe
test: add missing netaddress include headers (Jon Atack)6f09c0f6b5
util: add missing braces and apply clang format to SplitHostPort() (Jon Atack)2875a764f7
util: add ParseUInt16(), use it in SplitHostPort() (Jon Atack)6423c8175f
p2p, refactor: pass and use uint16_t CService::port as uint16_t (Jon Atack) Pull request description: As noticed during review today in https://github.com/bitcoin/bitcoin/pull/20685#discussion_r584873708 of the upcoming I2P network support, `CService::port` is `uint16_t` but is passed around the codebase and into the ctors as `int`, which causes uneeded conversions and casts. We can avoid these (including in the incoming I2P code without further changes to it) by using ports with the correct type. The remaining conversions are pushed out to the user input boundaries where they can be range-checked and raise with user feedback in the next patch. ACKs for top commit: practicalswift: cr ACK52dd40a9fe
: patch looks correct MarcoFalke: cr ACK52dd40a9fe
vasild: ACK52dd40a9fe
Tree-SHA512: 203c1cab3189a206c55ecada77b9548b810281cdc533252b8e3330ae0606b467731c75f730ce9deb07cbaab66facf97e1ffd2051084ff9077cba6750366b0432
This commit is contained in:
commit
18cd0888ef
@ -618,9 +618,9 @@ static UniValue CallRPC(BaseRequestHandler* rh, const std::string& strMethod, co
|
||||
// 1. -rpcport
|
||||
// 2. port in -rpcconnect (ie following : in ipv4 or ]: in ipv6)
|
||||
// 3. default port for chain
|
||||
int port = BaseParams().RPCPort();
|
||||
uint16_t port{BaseParams().RPCPort()};
|
||||
SplitHostPort(gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host);
|
||||
port = gArgs.GetArg("-rpcport", port);
|
||||
port = static_cast<uint16_t>(gArgs.GetArg("-rpcport", port));
|
||||
|
||||
// Obtain event base
|
||||
raii_event_base base = obtain_event_base();
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
|
||||
const Consensus::Params& GetConsensus() const { return consensus; }
|
||||
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||
int GetDefaultPort() const { return nDefaultPort; }
|
||||
uint16_t GetDefaultPort() const { return nDefaultPort; }
|
||||
|
||||
const CBlock& GenesisBlock() const { return genesis; }
|
||||
/** Default value for -checkmempool and -checkblockindex argument */
|
||||
@ -121,7 +121,7 @@ protected:
|
||||
|
||||
Consensus::Params consensus;
|
||||
CMessageHeader::MessageStartChars pchMessageStart;
|
||||
int nDefaultPort;
|
||||
uint16_t nDefaultPort;
|
||||
uint64_t nPruneAfterHeight;
|
||||
uint64_t m_assumed_blockchain_size;
|
||||
uint64_t m_assumed_chain_state_size;
|
||||
|
@ -290,8 +290,8 @@ static bool ThreadHTTP(struct event_base* base)
|
||||
/** Bind HTTP server to specified addresses */
|
||||
static bool HTTPBindAddresses(struct evhttp* http)
|
||||
{
|
||||
int http_port = gArgs.GetArg("-rpcport", BaseParams().RPCPort());
|
||||
std::vector<std::pair<std::string, uint16_t> > endpoints;
|
||||
uint16_t http_port{static_cast<uint16_t>(gArgs.GetArg("-rpcport", BaseParams().RPCPort()))};
|
||||
std::vector<std::pair<std::string, uint16_t>> endpoints;
|
||||
|
||||
// Determine what addresses to bind to
|
||||
if (!(gArgs.IsArgSet("-rpcallowip") && gArgs.IsArgSet("-rpcbind"))) { // Default to loopback if not allowing external IPs
|
||||
@ -305,7 +305,7 @@ static bool HTTPBindAddresses(struct evhttp* http)
|
||||
}
|
||||
} else if (gArgs.IsArgSet("-rpcbind")) { // Specific bind address
|
||||
for (const std::string& strRPCBind : gArgs.GetArgs("-rpcbind")) {
|
||||
int port = http_port;
|
||||
uint16_t port{http_port};
|
||||
std::string host;
|
||||
SplitHostPort(strRPCBind, port, host);
|
||||
endpoints.push_back(std::make_pair(host, port));
|
||||
|
@ -113,7 +113,7 @@ void CConnman::AddAddrFetch(const std::string& strDest)
|
||||
|
||||
uint16_t GetListenPort()
|
||||
{
|
||||
return (uint16_t)(gArgs.GetArg("-port", Params().GetDefaultPort()));
|
||||
return static_cast<uint16_t>(gArgs.GetArg("-port", Params().GetDefaultPort()));
|
||||
}
|
||||
|
||||
// find 'best' local address for a particular peer
|
||||
@ -394,7 +394,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
|
||||
|
||||
// Resolve
|
||||
const int default_port = Params().GetDefaultPort();
|
||||
const uint16_t default_port{Params().GetDefaultPort()};
|
||||
if (pszDest) {
|
||||
std::vector<CService> resolved;
|
||||
if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
|
||||
@ -462,7 +462,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||
return nullptr;
|
||||
}
|
||||
std::string host;
|
||||
int port = default_port;
|
||||
uint16_t port{default_port};
|
||||
SplitHostPort(std::string(pszDest), port, host);
|
||||
bool proxyConnectionFailed;
|
||||
connected = ConnectThroughProxy(proxy, host, port, *sock, nConnectTimeout,
|
||||
|
@ -229,7 +229,7 @@ extern std::string strSubVersion;
|
||||
|
||||
struct LocalServiceInfo {
|
||||
int nScore;
|
||||
int nPort;
|
||||
uint16_t nPort;
|
||||
};
|
||||
|
||||
extern RecursiveMutex cs_mapLocalHost;
|
||||
|
@ -194,12 +194,12 @@ bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSL
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lookup(const std::string& name, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
|
||||
bool Lookup(const std::string& name, std::vector<CService>& vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
|
||||
{
|
||||
if (name.empty() || !ValidAsCString(name)) {
|
||||
return false;
|
||||
}
|
||||
int port = portDefault;
|
||||
uint16_t port{portDefault};
|
||||
std::string hostname;
|
||||
SplitHostPort(name, port, hostname);
|
||||
|
||||
@ -213,7 +213,7 @@ bool Lookup(const std::string& name, std::vector<CService>& vAddr, int portDefau
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function)
|
||||
bool Lookup(const std::string& name, CService& addr, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function)
|
||||
{
|
||||
if (!ValidAsCString(name)) {
|
||||
return false;
|
||||
@ -226,7 +226,7 @@ bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllo
|
||||
return true;
|
||||
}
|
||||
|
||||
CService LookupNumeric(const std::string& name, int portDefault, DNSLookupFn dns_lookup_function)
|
||||
CService LookupNumeric(const std::string& name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
|
||||
{
|
||||
if (!ValidAsCString(name)) {
|
||||
return {};
|
||||
@ -363,7 +363,7 @@ static std::string Socks5ErrorString(uint8_t err)
|
||||
}
|
||||
}
|
||||
|
||||
bool Socks5(const std::string& strDest, int port, const ProxyCredentials* auth, const Sock& sock)
|
||||
bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* auth, const Sock& sock)
|
||||
{
|
||||
IntrRecvError recvr;
|
||||
LogPrint(BCLog::NET, "SOCKS5 connecting %s\n", strDest);
|
||||
@ -665,7 +665,7 @@ bool IsProxy(const CNetAddr &addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, int port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed)
|
||||
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed)
|
||||
{
|
||||
// first connect to proxy server
|
||||
if (!ConnectSocketDirectly(proxy.proxy, sock.Get(), nTimeout, true)) {
|
||||
@ -677,11 +677,11 @@ bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, int
|
||||
ProxyCredentials random_auth;
|
||||
static std::atomic_int counter(0);
|
||||
random_auth.username = random_auth.password = strprintf("%i", counter++);
|
||||
if (!Socks5(strDest, (uint16_t)port, &random_auth, sock)) {
|
||||
if (!Socks5(strDest, port, &random_auth, sock)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!Socks5(strDest, (uint16_t)port, 0, sock)) {
|
||||
if (!Socks5(strDest, port, 0, sock)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ extern DNSLookupFn g_dns_lookup;
|
||||
* @returns Whether or not the specified host string successfully resolved to
|
||||
* any resulting network addresses.
|
||||
*
|
||||
* @see Lookup(const std::string&, std::vector<CService>&, int, bool, unsigned int, DNSLookupFn)
|
||||
* @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn)
|
||||
* for additional parameter descriptions.
|
||||
*/
|
||||
bool LookupHost(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
@ -119,7 +119,7 @@ bool LookupHost(const std::string& name, std::vector<CNetAddr>& vIP, unsigned in
|
||||
/**
|
||||
* Resolve a host string to its first corresponding network address.
|
||||
*
|
||||
* @see LookupHost(const std::string&, std::vector<CNetAddr>&, unsigned int, bool, DNSLookupFn)
|
||||
* @see LookupHost(const std::string&, std::vector<CNetAddr>&, uint16_t, bool, DNSLookupFn)
|
||||
* for additional parameter descriptions.
|
||||
*/
|
||||
bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
@ -129,7 +129,7 @@ bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSL
|
||||
*
|
||||
* @param name The string representing a service. Could be a name or a
|
||||
* numerical IP address (IPv6 addresses should be in their
|
||||
* disambiguated bracketed form), optionally followed by a port
|
||||
* disambiguated bracketed form), optionally followed by a uint16_t port
|
||||
* number. (e.g. example.com:8333 or
|
||||
* [2001:db8:85a3:8d3:1319:8a2e:370:7348]:420)
|
||||
* @param[out] vAddr The resulting services to which the specified service string
|
||||
@ -144,15 +144,15 @@ bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSL
|
||||
* @returns Whether or not the service string successfully resolved to any
|
||||
* resulting services.
|
||||
*/
|
||||
bool Lookup(const std::string& name, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
bool Lookup(const std::string& name, std::vector<CService>& vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
|
||||
/**
|
||||
* Resolve a service string to its first corresponding service.
|
||||
*
|
||||
* @see Lookup(const std::string&, std::vector<CService>&, int, bool, unsigned int, DNSLookupFn)
|
||||
* @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn)
|
||||
* for additional parameter descriptions.
|
||||
*/
|
||||
bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
bool Lookup(const std::string& name, CService& addr, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
|
||||
/**
|
||||
* Resolve a service string with a numeric IP to its first corresponding
|
||||
@ -160,10 +160,10 @@ bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllo
|
||||
*
|
||||
* @returns The resulting CService if the resolution was successful, [::]:0 otherwise.
|
||||
*
|
||||
* @see Lookup(const std::string&, std::vector<CService>&, int, bool, unsigned int, DNSLookupFn)
|
||||
* @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn)
|
||||
* for additional parameter descriptions.
|
||||
*/
|
||||
CService LookupNumeric(const std::string& name, int portDefault = 0, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
CService LookupNumeric(const std::string& name, uint16_t portDefault = 0, DNSLookupFn dns_lookup_function = g_dns_lookup);
|
||||
|
||||
/**
|
||||
* Parse and resolve a specified subnet string into the appropriate internal
|
||||
@ -219,7 +219,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
|
||||
*
|
||||
* @returns Whether or not the operation succeeded.
|
||||
*/
|
||||
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, int port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed);
|
||||
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed);
|
||||
|
||||
/** Disable or enable blocking-mode for a socket */
|
||||
bool SetSocketNonBlocking(const SOCKET& hSocket, bool fNonBlocking);
|
||||
@ -245,6 +245,6 @@ void InterruptSocks5(bool interrupt);
|
||||
* @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC1928: SOCKS Protocol
|
||||
* Version 5</a>
|
||||
*/
|
||||
bool Socks5(const std::string& strDest, int port, const ProxyCredentials* auth, const Sock& socket);
|
||||
bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* auth, const Sock& socket);
|
||||
|
||||
#endif // BITCOIN_NETBASE_H
|
||||
|
@ -67,7 +67,7 @@ private Q_SLOTS:
|
||||
void updateDefaultProxyNets();
|
||||
|
||||
Q_SIGNALS:
|
||||
void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
|
||||
void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, uint16_t nProxyPort);
|
||||
|
||||
private:
|
||||
Ui::OptionsDialog *ui;
|
||||
|
@ -914,7 +914,7 @@ static RPCHelpMan addpeeraddress()
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
|
||||
std::string addr_string = request.params[0].get_str();
|
||||
uint16_t port = request.params[1].get_int();
|
||||
uint16_t port{static_cast<uint16_t>(request.params[1].get_int())};
|
||||
|
||||
CNetAddr net_addr;
|
||||
if (!LookupHost(addr_string, net_addr, false)) {
|
||||
|
@ -100,7 +100,7 @@ static CNetAddr ResolveIP(const std::string& ip)
|
||||
return addr;
|
||||
}
|
||||
|
||||
static CService ResolveService(const std::string& ip, const int port = 0)
|
||||
static CService ResolveService(const std::string& ip, uint16_t port = 0)
|
||||
{
|
||||
CService serv;
|
||||
BOOST_CHECK_MESSAGE(Lookup(ip, serv, port, false), strprintf("failed to resolve: %s:%i", ip, port));
|
||||
|
@ -2,8 +2,9 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <netaddress.h>
|
||||
#include <util/asmap.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
@ -18,7 +18,7 @@ FUZZ_TARGET(netbase_dns_lookup)
|
||||
const std::string name = fuzzed_data_provider.ConsumeRandomLengthString(512);
|
||||
const unsigned int max_results = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
|
||||
const bool allow_lookup = fuzzed_data_provider.ConsumeBool();
|
||||
const int default_port = fuzzed_data_provider.ConsumeIntegral<int>();
|
||||
const uint16_t default_port = fuzzed_data_provider.ConsumeIntegral<uint16_t>();
|
||||
|
||||
auto fuzzed_dns_lookup_function = [&](const std::string&, bool) {
|
||||
std::vector<CNetAddr> resolved_addresses;
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
@ -38,7 +39,7 @@ FUZZ_TARGET_INIT(socks5, initialize_socks5)
|
||||
// This Socks5(...) fuzzing harness would have caught CVE-2017-18350 within
|
||||
// a few seconds of fuzzing.
|
||||
(void)Socks5(fuzzed_data_provider.ConsumeRandomLengthString(512),
|
||||
fuzzed_data_provider.ConsumeIntegral<int>(),
|
||||
fuzzed_data_provider.ConsumeIntegral<uint16_t>(),
|
||||
fuzzed_data_provider.ConsumeBool() ? &proxy_credentials : nullptr,
|
||||
fuzzed_sock);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <blockfilter.h>
|
||||
#include <clientversion.h>
|
||||
#include <logging.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <outputtype.h>
|
||||
#include <rpc/client.h>
|
||||
@ -82,7 +83,7 @@ FUZZ_TARGET(string)
|
||||
#ifndef WIN32
|
||||
(void)ShellEscape(random_string_1);
|
||||
#endif // WIN32
|
||||
int port_out;
|
||||
uint16_t port_out;
|
||||
std::string host_out;
|
||||
SplitHostPort(random_string_1, port_out, host_out);
|
||||
(void)TimingResistantEqual(random_string_1, random_string_2);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <clientversion.h>
|
||||
#include <cstdint>
|
||||
#include <net.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <serialize.h>
|
||||
#include <span.h>
|
||||
@ -91,7 +92,7 @@ BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup)
|
||||
BOOST_AUTO_TEST_CASE(cnode_listen_port)
|
||||
{
|
||||
// test default
|
||||
uint16_t port = GetListenPort();
|
||||
uint16_t port{GetListenPort()};
|
||||
BOOST_CHECK(port == Params().GetDefaultPort());
|
||||
// test set port
|
||||
uint16_t altPort = 12345;
|
||||
|
@ -3,6 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <net_permissions.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <protocol.h>
|
||||
#include <serialize.h>
|
||||
@ -83,31 +84,31 @@ BOOST_AUTO_TEST_CASE(netbase_properties)
|
||||
|
||||
}
|
||||
|
||||
bool static TestSplitHost(std::string test, std::string host, int port)
|
||||
bool static TestSplitHost(const std::string& test, const std::string& host, uint16_t port)
|
||||
{
|
||||
std::string hostOut;
|
||||
int portOut = -1;
|
||||
uint16_t portOut{0};
|
||||
SplitHostPort(test, portOut, hostOut);
|
||||
return hostOut == host && port == portOut;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(netbase_splithost)
|
||||
{
|
||||
BOOST_CHECK(TestSplitHost("www.bitcoincore.org", "www.bitcoincore.org", -1));
|
||||
BOOST_CHECK(TestSplitHost("[www.bitcoincore.org]", "www.bitcoincore.org", -1));
|
||||
BOOST_CHECK(TestSplitHost("www.bitcoincore.org", "www.bitcoincore.org", 0));
|
||||
BOOST_CHECK(TestSplitHost("[www.bitcoincore.org]", "www.bitcoincore.org", 0));
|
||||
BOOST_CHECK(TestSplitHost("www.bitcoincore.org:80", "www.bitcoincore.org", 80));
|
||||
BOOST_CHECK(TestSplitHost("[www.bitcoincore.org]:80", "www.bitcoincore.org", 80));
|
||||
BOOST_CHECK(TestSplitHost("127.0.0.1", "127.0.0.1", -1));
|
||||
BOOST_CHECK(TestSplitHost("127.0.0.1", "127.0.0.1", 0));
|
||||
BOOST_CHECK(TestSplitHost("127.0.0.1:8333", "127.0.0.1", 8333));
|
||||
BOOST_CHECK(TestSplitHost("[127.0.0.1]", "127.0.0.1", -1));
|
||||
BOOST_CHECK(TestSplitHost("[127.0.0.1]", "127.0.0.1", 0));
|
||||
BOOST_CHECK(TestSplitHost("[127.0.0.1]:8333", "127.0.0.1", 8333));
|
||||
BOOST_CHECK(TestSplitHost("::ffff:127.0.0.1", "::ffff:127.0.0.1", -1));
|
||||
BOOST_CHECK(TestSplitHost("::ffff:127.0.0.1", "::ffff:127.0.0.1", 0));
|
||||
BOOST_CHECK(TestSplitHost("[::ffff:127.0.0.1]:8333", "::ffff:127.0.0.1", 8333));
|
||||
BOOST_CHECK(TestSplitHost("[::]:8333", "::", 8333));
|
||||
BOOST_CHECK(TestSplitHost("::8333", "::8333", -1));
|
||||
BOOST_CHECK(TestSplitHost("::8333", "::8333", 0));
|
||||
BOOST_CHECK(TestSplitHost(":8333", "", 8333));
|
||||
BOOST_CHECK(TestSplitHost("[]:8333", "", 8333));
|
||||
BOOST_CHECK(TestSplitHost("", "", -1));
|
||||
BOOST_CHECK(TestSplitHost("", "", 0));
|
||||
}
|
||||
|
||||
bool static TestParse(std::string src, std::string canon)
|
||||
|
@ -107,23 +107,25 @@ std::vector<unsigned char> ParseHex(const std::string& str)
|
||||
return ParseHex(str.c_str());
|
||||
}
|
||||
|
||||
void SplitHostPort(std::string in, int &portOut, std::string &hostOut) {
|
||||
void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut)
|
||||
{
|
||||
size_t colon = in.find_last_of(':');
|
||||
// if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
|
||||
bool fHaveColon = colon != in.npos;
|
||||
bool fBracketed = fHaveColon && (in[0]=='[' && in[colon-1]==']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
|
||||
bool fMultiColon = fHaveColon && (in.find_last_of(':',colon-1) != in.npos);
|
||||
if (fHaveColon && (colon==0 || fBracketed || !fMultiColon)) {
|
||||
int32_t n;
|
||||
if (ParseInt32(in.substr(colon + 1), &n) && n > 0 && n < 0x10000) {
|
||||
bool fBracketed = fHaveColon && (in[0] == '[' && in[colon - 1] == ']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
|
||||
bool fMultiColon = fHaveColon && (in.find_last_of(':', colon - 1) != in.npos);
|
||||
if (fHaveColon && (colon == 0 || fBracketed || !fMultiColon)) {
|
||||
uint16_t n;
|
||||
if (ParseUInt16(in.substr(colon + 1), &n)) {
|
||||
in = in.substr(0, colon);
|
||||
portOut = n;
|
||||
}
|
||||
}
|
||||
if (in.size()>0 && in[0] == '[' && in[in.size()-1] == ']')
|
||||
hostOut = in.substr(1, in.size()-2);
|
||||
else
|
||||
if (in.size() > 0 && in[0] == '[' && in[in.size() - 1] == ']') {
|
||||
hostOut = in.substr(1, in.size() - 2);
|
||||
} else {
|
||||
hostOut = in;
|
||||
}
|
||||
}
|
||||
|
||||
std::string EncodeBase64(Span<const unsigned char> input)
|
||||
@ -334,6 +336,18 @@ bool ParseUInt8(const std::string& str, uint8_t *out)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseUInt16(const std::string& str, uint16_t* out)
|
||||
{
|
||||
uint32_t u32;
|
||||
if (!ParseUInt32(str, &u32) || u32 > std::numeric_limits<uint16_t>::max()) {
|
||||
return false;
|
||||
}
|
||||
if (out != nullptr) {
|
||||
*out = static_cast<uint16_t>(u32);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseUInt32(const std::string& str, uint32_t *out)
|
||||
{
|
||||
if (!ParsePrechecks(str))
|
||||
|
@ -65,7 +65,7 @@ std::string EncodeBase32(Span<const unsigned char> input, bool pad = true);
|
||||
*/
|
||||
std::string EncodeBase32(const std::string& str, bool pad = true);
|
||||
|
||||
void SplitHostPort(std::string in, int& portOut, std::string& hostOut);
|
||||
void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut);
|
||||
int64_t atoi64(const std::string& str);
|
||||
int atoi(const std::string& str);
|
||||
|
||||
@ -115,6 +115,13 @@ constexpr inline bool IsSpace(char c) noexcept {
|
||||
*/
|
||||
[[nodiscard]] bool ParseUInt8(const std::string& str, uint8_t *out);
|
||||
|
||||
/**
|
||||
* Convert decimal string to unsigned 16-bit integer with strict parse error feedback.
|
||||
* @returns true if the entire string could be parsed as valid integer,
|
||||
* false if the entire string could not be parsed or if overflow or underflow occurred.
|
||||
*/
|
||||
[[nodiscard]] bool ParseUInt16(const std::string& str, uint16_t* out);
|
||||
|
||||
/**
|
||||
* Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
|
||||
* @returns true if the entire string could be parsed as valid integer,
|
||||
|
Loading…
Reference in New Issue
Block a user