Skip to content

Commit a0a621a

Browse files
committed
GH-1091 Improve logic. Make sure it doesn't throw for use on incoming addresses.
1 parent a654723 commit a0a621a

File tree

1 file changed

+23
-32
lines changed

1 file changed

+23
-32
lines changed

plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp

+23-32
Original file line numberDiff line numberDiff line change
@@ -41,38 +41,48 @@ namespace detail {
4141
}
4242

4343
/// @return host, port, remainder
44-
inline std::tuple<std::string, std::string, std::string> split_host_port_remainder(const std::string& peer_add) {
44+
inline std::tuple<std::string, std::string, std::string> split_host_port_remainder(const std::string& peer_add, bool should_throw) {
4545
using std::string;
4646
// host:port[:trx|:blk][:<rate>]
4747
if (peer_add.empty()) return {};
4848

49-
string::size_type p = peer_add[0] == '[' ? peer_add.find(']') : 0;
50-
if (p == 0) {
51-
if( auto colon_count = std::count(peer_add.begin(), peer_add.end(), ':'); colon_count >= 7 ) {
52-
EOS_ASSERT( colon_count <= 2, chain::plugin_config_exception,
53-
"Invalid address specification ${a}; IPv6 addresses must be enclosed in square brackets.", ("a", peer_add));
49+
auto colon_count = std::count(peer_add.begin(), peer_add.end(), ':');
50+
string::size_type end_bracket = 0;
51+
if (peer_add[0] == '[') {
52+
end_bracket = peer_add.find(']');
53+
if (end_bracket == string::npos) {
54+
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
55+
"Invalid address specification ${a}, IPv6 no closing square bracket", ("a", peer_add) );
56+
return {};
5457
}
58+
} else if (colon_count >= 7) {
59+
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
60+
"Invalid address specification ${a}; IPv6 addresses must be enclosed in square brackets.", ("a", peer_add));
61+
return {};
62+
5563
}
56-
string::size_type colon = p != string::npos ? peer_add.find(':', p) : string::npos;
64+
string::size_type colon = peer_add.find(':', end_bracket+1);
5765
if (colon == string::npos || colon == 0) {
5866
return {};
5967
}
6068
string::size_type colon2 = peer_add.find(':', colon + 1);
61-
string host = (p > 0) ? peer_add.substr( 0, p+1 ) : peer_add.substr( 0, colon );
69+
string host = (end_bracket > 0) ? peer_add.substr( 0, end_bracket+1 ) : peer_add.substr( 0, colon );
6270
string port = peer_add.substr( colon + 1, colon2 == string::npos ? string::npos : colon2 - (colon + 1));
6371
string remainder = colon2 == string::npos ? "" : peer_add.substr( colon2 + 1 );
6472
return {std::move(host), std::move(port), std::move(remainder)};
6573
}
6674

6775
} // namespace detail
6876

69-
/// @return host, port, type
77+
/// @return host, port, type. returns empty on invalid peer_add, does not throw
7078
inline std::tuple<std::string, std::string, std::string> split_host_port_type(const std::string& peer_add) {
79+
7180
using std::string;
7281
// host:port[:trx|:blk][:<rate>] // rate is discarded
7382
if (peer_add.empty()) return {};
7483

75-
auto [host, port, remainder] = detail::split_host_port_remainder(peer_add);
84+
constexpr bool should_throw = false;
85+
auto [host, port, remainder] = detail::split_host_port_remainder(peer_add, should_throw);
7686
if (host.empty()) return {};
7787

7888
string::size_type end = remainder.find_first_of( " :+=.,<>!$%^&(*)|-#@\t" ); // future proof by including most symbols without using regex
@@ -82,9 +92,10 @@ namespace detail {
8292
}
8393

8494
/// @return listen address, type [trx|blk], and block sync rate limit (in bytes/sec) of address string
95+
/// @throws chain::plugin_config_exception on invalid address
8596
inline std::tuple<std::string, size_t> parse_listen_address( const std::string& address ) {
86-
87-
auto [host, port, remainder] = detail::split_host_port_remainder(address);
97+
constexpr bool should_throw = true;
98+
auto [host, port, remainder] = detail::split_host_port_remainder(address, should_throw);
8899
auto listen_addr = host + ":" + port;
89100
auto limit = remainder;
90101
auto last_colon_location = remainder.rfind(':');
@@ -96,24 +107,4 @@ namespace detail {
96107
return {std::move(listen_addr), block_sync_rate_limit};
97108
}
98109

99-
inline std::tuple<std::string, std::string, std::string> split_host_xport_type(const std::string& peer_add) {
100-
using std::string;
101-
// host:port:[<trx>|<blk>]
102-
if (peer_add.empty()) return {};
103-
104-
string::size_type p = peer_add[0] == '[' ? peer_add.find(']') : 0;
105-
string::size_type colon = p != string::npos ? peer_add.find(':', p) : string::npos;
106-
if (colon == string::npos || colon == 0) {
107-
return {};
108-
}
109-
string::size_type colon2 = peer_add.find(':', colon + 1);
110-
string::size_type end = colon2 == string::npos
111-
? string::npos : peer_add.find_first_of( " :+=.,<>!$%^&(*)|-#@\t", colon2 + 1 ); // future proof by including most symbols without using regex
112-
string host = (p > 0) ? peer_add.substr( 1, p-1 ) : peer_add.substr( 0, colon );
113-
string port = peer_add.substr( colon + 1, colon2 == string::npos ? string::npos : colon2 - (colon + 1));
114-
string type = colon2 == string::npos ? "" : end == string::npos ?
115-
peer_add.substr( colon2 + 1 ) : peer_add.substr( colon2 + 1, end - (colon2 + 1) );
116-
return {std::move(host), std::move(port), std::move(type)};
117-
}
118-
119110
} // namespace eosio::net_utils

0 commit comments

Comments
 (0)