From 7f1471af5ea70306a93c95a661ca3368248595af Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Wed, 13 Mar 2019 08:43:39 +0000
Subject: [PATCH] More strict FidoNet address detection (e.g. so IPv6 addresses
 aren't detected as net_type NET_FIDO).

---
 src/smblib/smbstr.c | 74 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 53 insertions(+), 21 deletions(-)

diff --git a/src/smblib/smbstr.c b/src/smblib/smbstr.c
index 37bf085b48..b95d2f8591 100644
--- a/src/smblib/smbstr.c
+++ b/src/smblib/smbstr.c
@@ -343,8 +343,9 @@ enum smb_net_type SMBCALL smb_netaddr_type(const char* str)
 		SKIP_WHITESPACE(p);
 		if(*p == 0)
 			return NET_NONE;
-		if(strspn(p, "1234567890:/.") != strlen(p))
-			return NET_NONE;
+		if(smb_get_net_type_by_addr(p) == NET_FIDO)
+			return NET_FIDO;
+		return NET_NONE;
 	}
 	else
 		p++;
@@ -359,11 +360,15 @@ enum smb_net_type SMBCALL smb_netaddr_type(const char* str)
 /* Returns net_type for passed network address 								*/
 /* The only addresses expected with an '@' are Internet/SMTP addresses		*/
 /* Examples:																*/
+/*  ""					= NET_NONE											*/
+/*	"@"					= NET_NONE											*/
 /*	"VERT"				= NET_QWK											*/
+/*	"VERT/NIX"			= NET_QWK											*/
 /*	"1:103/705"			= NET_FIDO											*/
 /*	"705.0"				= NET_FIDO											*/
 /*	"705"				= NET_FIDO											*/
 /*	"192.168.1.0"		= NET_INTERNET										*/
+/*  "::1"				= NET_INTERNET										*/
 /*	"some.host"			= NET_INTERNET										*/
 /*	"someone@anywhere"	= NET_INTERNET										*/
 /*	"someone@some.host"	= NET_INTERNET										*/
@@ -372,28 +377,55 @@ enum smb_net_type SMBCALL smb_get_net_type_by_addr(const char* addr)
 {
 	const char*	p = addr;
 	const char*	tp;
-	char*	firstdot;
-	char*	lastdot;
-
-	if(strchr(p,'@') != NULL)
-		return(NET_INTERNET);
-
-	firstdot=strchr(p,'.');
-	lastdot=strrchr(p,'.');
-
-	if(isalpha(*p) && firstdot==NULL)
-		return(NET_QWK);
 
-	for(tp=p;*tp;tp++) {
-		if(!isdigit(*tp) && *tp!=':' && *tp!='/' && *tp!='.')
-			break;
+	char* at = strchr(p,'@');
+	if(at != NULL)
+		p = at + 1;
+
+	if(*p == 0)
+		return NET_NONE;
+
+	char* dot = strchr(p,'.');
+	char* colon = strchr(p,':');
+	char* slash = strchr(p,'/');
+
+	if(at == NULL && isalpha(*p) && dot == NULL && colon == NULL)
+		return NET_QWK;
+
+	char last = 0;
+	for(tp = p; *tp != '\0'; tp++) {
+		last = *tp;
+		if(isdigit(*tp))
+			continue;
+		if(*tp == ':') {
+			if(tp != colon)
+				break;
+			if(dot != NULL && tp > dot)
+				break;
+			if(slash != NULL && tp > slash)
+				break;
+			continue;
+		}
+		if(*tp == '/') {
+			if(tp != slash)
+				break;
+			if(dot != NULL && tp > dot)
+				break;
+			continue;
+		}
+		if(*tp == '.') {
+			if(tp != dot)
+				break;
+			continue;
+		}
+		break;
 	}
-	if(isdigit(*p) && *tp==0 && firstdot==lastdot)
-		return(NET_FIDO);
-	if(isalnum(*p))
-		return(NET_INTERNET);
+	if(at == NULL && isdigit(*p) && *tp == '\0' && isdigit(last))
+		return NET_FIDO;
+	if(slash == NULL && (isalnum(*p) || p == colon))
+		return NET_INTERNET;
 
-	return(NET_UNKNOWN);
+	return NET_UNKNOWN;
 }
 
 char* SMBCALL smb_nettype(enum smb_net_type type)
-- 
GitLab