@@ -15,6 +15,8 @@ static std::unique_ptr<const CChainParams> g_main_params{nullptr};
1515static std::once_flag g_main_params_flag;
1616static const CService empty_service{CService ()};
1717
18+ static constexpr std::string_view SAFE_CHARS_IPV4{" 1234567890." };
19+
1820bool IsNodeOnMainnet () { return Params ().NetworkIDString () == CBaseChainParams::MAIN; }
1921const CChainParams& MainParams ()
2022{
@@ -23,6 +25,11 @@ const CChainParams& MainParams()
2325 [&]() { g_main_params = CreateChainParams (ArgsManager{}, CBaseChainParams::MAIN); });
2426 return *Assert (g_main_params);
2527}
28+
29+ bool MatchCharsFilter (std::string_view input, std::string_view filter)
30+ {
31+ return std::all_of (input.begin (), input.end (), [&filter](char c) { return filter.find (c) != std::string_view::npos; });
32+ }
2633} // anonymous namespace
2734
2835bool NetInfoEntry::operator ==(const NetInfoEntry& rhs) const
@@ -175,7 +182,16 @@ NetInfoStatus MnNetInfo::AddEntry(const std::string& input)
175182 if (!IsEmpty ()) {
176183 return NetInfoStatus::MaxLimit;
177184 }
178- if (auto service_opt{Lookup (input, /* portDefault=*/ Params ().GetDefaultPort (), /* fAllowLookup=*/ false )}) {
185+
186+ std::string addr;
187+ uint16_t port{Params ().GetDefaultPort ()};
188+ SplitHostPort (input, port, addr);
189+ // Contains invalid characters, unlikely to pass Lookup(), fast-fail
190+ if (!MatchCharsFilter (addr, SAFE_CHARS_IPV4)) {
191+ return NetInfoStatus::BadInput;
192+ }
193+
194+ if (auto service_opt{Lookup (addr, /* portDefault=*/ port, /* fAllowLookup=*/ false )}) {
179195 const auto ret{ValidateService (*service_opt)};
180196 if (ret == NetInfoStatus::Success) {
181197 m_addr = NetInfoEntry{*service_opt};
0 commit comments