validate the ip address octets better

Wed, 27 Jan 2021 19:01:37 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 27 Jan 2021 19:01:37 +0200
changeset 188
5fc32e4b2a8c
parent 187
53f9c7b2c068
child 189
248d0b85cbda

validate the ip address octets better

sources/network/ipaddress.cpp file | annotate | diff | comparison | revisions
sources/network/ipaddress.h file | annotate | diff | comparison | revisions
--- a/sources/network/ipaddress.cpp	Wed Jan 27 18:55:14 2021 +0200
+++ b/sources/network/ipaddress.cpp	Wed Jan 27 19:01:37 2021 +0200
@@ -120,19 +120,6 @@
 	}
 }
 
-std::optional<net::ip_address> net::ip_scan_octets(const char* address_string)
-{
-	std::optional<net::ip_address> value;
-	net::octet_t parts[4];
-	if (std::sscanf(address_string, "%hhu.%hhu.%hhu.%hhu", &parts[0], &parts[1], &parts[2], &parts[3]))
-	{
-		value = net::ip_address{};
-		for (unsigned char i = 0; i < 4; i += 1)
-			ip_set_octet(&*value, i, parts[i]);
-	}
-	return value;
-}
-
 std::optional<net::ip_address> net::ip_resolve_hostname(const std::string& node, std::ostream& errorStream)
 {
 	AddrInfo hints;
@@ -160,8 +147,25 @@
 	std::string addressString = colonpos == -1 ? input_string : mid(input_string, 0, colonpos);
 	std::optional<net::ip_address> value;
 	// Try scanf the IPv4 host first
-	value = ip_scan_octets(addressString.data());
-	if (not value.has_value())
+	int parts[4];
+	if (std::sscanf(addressString.data(), "%d.%d.%d.%d", &parts[0], &parts[1], &parts[2], &parts[3]))
+	{
+		value = net::ip_address{};
+		for (unsigned char i = 0; i < 4; i += 1)
+		{
+			if (parts[i] >= 0 and parts[i] < 256)
+			{
+				ip_set_octet(&*value, i, parts[i]);
+			}
+			else
+			{
+				value.reset();
+				errorStream << "IP address value out of range";
+				break;
+			}
+		}
+	}
+	else
 	{
 		// Possibly a hostname, try resolve it
 		value = ip_resolve_hostname(addressString, errorStream);
--- a/sources/network/ipaddress.h	Wed Jan 27 18:55:14 2021 +0200
+++ b/sources/network/ipaddress.h	Wed Jan 27 19:01:37 2021 +0200
@@ -51,7 +51,6 @@
 	int ip_compare(const ip_address& one, const ip_address& other);
 	net::octet_t ip_octet(const ip_address& address, unsigned char n);
 	void ip_set_octet(ip_address* address, unsigned char n, net::octet_t octet);
-	std::optional<ip_address> ip_scan_octets(const char* address_string);
 	std::optional<unsigned short> ip_parse_port(const char* port_string, std::ostream& errorStream);
 	std::optional<ip_address> ip_resolve_hostname(const std::string& node, std::ostream& errorStream);
 	std::optional<ip_address> ip_resolve(const std::string& input_string, std::ostream &errorStream);

mercurial