Common/Network: Add structs: IPv4Port, IPv4PortRange and functions: IPAddressToString, ParseIPv4PortRange.

This commit is contained in:
Jordan Woyak
2026-02-06 19:32:55 -06:00
parent 97ad5ad1a1
commit 5545798e00
3 changed files with 288 additions and 0 deletions

View File

@@ -6,6 +6,7 @@
#include <string>
#include <vector>
#include "Common/Network.h"
#include "Common/StringUtil.h"
#include "Common/Swap.h"
@@ -282,6 +283,96 @@ TEST(StringUtil, SplitStringIntoArray)
EXPECT_TRUE(SplitStringIntoArray<2>(subject4, '=').has_value());
}
TEST(StringUtil, StringToIPv4PortRange)
{
constexpr auto parse = Common::StringToIPv4PortRange;
constexpr Common::IPAddress ip_network = {192, 168, 0, 0};
constexpr Common::IPAddress test_ip = {192, 168, 0, 13};
constexpr Common::IPAddress last_ip = {192, 168, 0, 255};
EXPECT_FALSE(parse("").has_value());
EXPECT_FALSE(parse("1.2.3").has_value());
EXPECT_FALSE(parse("1.2.3.4-").has_value());
EXPECT_FALSE(parse("1.2.3.4.5").has_value());
EXPECT_FALSE(parse("1.2.3.256").has_value());
EXPECT_FALSE(parse("1.2.3.4/33").has_value());
EXPECT_FALSE(parse("1.2.3.4:65536").has_value());
EXPECT_FALSE(parse("1.2.3.4-1.2.3.4.5").has_value());
EXPECT_FALSE(parse("1.1.1.1:81-80").has_value());
EXPECT_FALSE(parse("1.1.1.2-1.1.1.1").has_value());
EXPECT_TRUE(parse("1.2.3.4").has_value());
EXPECT_TRUE(parse("1.2.3.4:80").has_value());
EXPECT_TRUE(parse("1.2.3.4:80-81").has_value());
EXPECT_TRUE(parse("1.2.3.4/16").has_value());
EXPECT_TRUE(parse("1.2.3.4/16:80").has_value());
EXPECT_TRUE(parse("1.2.3.4/16:80-81").has_value());
EXPECT_TRUE(parse("1.2.3.4-10").has_value());
EXPECT_TRUE(parse("1.2.3.4-10:80").has_value());
EXPECT_TRUE(parse("1.2.3.4-10:80-81").has_value());
{
const auto simple_result = parse("192.168.0.13").value();
EXPECT_EQ(simple_result.first.ip_address, test_ip);
EXPECT_EQ(simple_result.last.ip_address, test_ip);
EXPECT_EQ(simple_result.first.GetPortValue(), 0);
EXPECT_EQ(simple_result.last.GetPortValue(), u16(-1));
}
{
const auto port_result = parse("192.168.0.13:77").value();
EXPECT_EQ(port_result.first.ip_address, test_ip);
EXPECT_EQ(port_result.last.ip_address, test_ip);
EXPECT_EQ(port_result.first.GetPortValue(), 77);
EXPECT_EQ(port_result.last.GetPortValue(), 77);
}
{
const auto ip_range_result = parse("192.168.0.13-192.168.0.255:123").value();
EXPECT_EQ(ip_range_result.first.ip_address, test_ip);
EXPECT_EQ(ip_range_result.last.ip_address, last_ip);
EXPECT_EQ(ip_range_result.first.GetPortValue(), 123);
EXPECT_EQ(ip_range_result.last.GetPortValue(), 123);
}
{
const auto port_range_result = parse("192.168.29.151:5000-5010").value();
EXPECT_EQ(port_range_result.first.GetPortValue(), 5000);
EXPECT_EQ(port_range_result.last.GetPortValue(), 5010);
EXPECT_TRUE(port_range_result.IsMatch(parse("192.168.29.151:5008")->first));
EXPECT_FALSE(port_range_result.IsMatch(parse("127.0.0.1:5000")->first));
}
{
const auto ip_range_result = parse("192.168.0.13-255:123-999").value();
EXPECT_EQ(ip_range_result.first.ip_address, test_ip);
EXPECT_EQ(ip_range_result.last.ip_address, last_ip);
EXPECT_EQ(ip_range_result.first.GetPortValue(), 123);
EXPECT_EQ(ip_range_result.last.GetPortValue(), 999);
}
{
const auto ip_network_result = parse("192.168.0.13/24:123-999").value();
EXPECT_EQ(ip_network_result.first.ip_address, ip_network);
EXPECT_EQ(ip_network_result.last.ip_address, last_ip);
EXPECT_EQ(ip_network_result.first.GetPortValue(), 123);
EXPECT_EQ(ip_network_result.last.GetPortValue(), 999);
}
EXPECT_TRUE(parse("192.168.0.13/24")->IsMatch(parse("192.168.0.99")->first));
EXPECT_FALSE(parse("192.168.0.13/24")->IsMatch(parse("192.168.1.99")->first));
EXPECT_FALSE(parse("192.168.0.13/32")->IsMatch(parse("192.168.0.99")->first));
EXPECT_TRUE(parse("192.168.0.13/0")->IsMatch(parse("10.0.0.1")->first));
EXPECT_TRUE(parse("192.168.0.13")->IsMatch(parse("192.168.0.13:81")->first));
EXPECT_FALSE(parse("192.168.0.13:80")->IsMatch(parse("192.168.0.13:81")->first));
EXPECT_TRUE(parse("192.168.0.13:80")->IsMatch(parse("192.168.0.13:80")->first));
EXPECT_FALSE(parse("192.168.0.13:80-81")->IsMatch(parse("192.168.0.14:81")->first));
EXPECT_TRUE(parse("192.168.0.13-14:80-81")->IsMatch(parse("192.168.0.14:81")->first));
}
TEST(StringUtil, CharacterEncodingConversion)
{
// wstring