From 5b359484e144b2ff8bdc2dbaee33bb5410d02a41 Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Sun, 8 Aug 2021 23:03:01 -0700
Subject: [PATCH] Allow '*' pattern character to be used mid-string (not just
 beg or end)

Previously, the '*' matching pattern character could only be used as the beginning or ending character of a pattern string; for any other use, it was treated just as any other exact-match character.

Now, you can have exact-match characters on both the left and right sides of the '*', so pattern matching like the following is possible:

<*@gmail.com>
digital*man

Multiple '*'s are still not treated special (only the first/left-most '*" is), so, for example, "*blah*" will not likely produce the desired matching effect (use "blah~" instead for this case).
---
 src/sbbs3/str_util.c | 88 +++++++++++++++++++++++---------------------
 src/sbbs3/str_util.h |  2 +-
 2 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/src/sbbs3/str_util.c b/src/sbbs3/str_util.c
index dac22f2814..3cf15f5eab 100644
--- a/src/sbbs3/str_util.c
+++ b/src/sbbs3/str_util.c
@@ -244,64 +244,68 @@ char* strip_char(const char* str, char* dest, char ch)
 }
 
 /****************************************************************************/
-/* Pattern matching string search of 'insearchof' in 'string'.				*/
-/****************************************************************************/
-BOOL findstr_in_string(const char* insearchof, char* string)
-{
+/* Pattern matching string search of 'insearchof' in 'pattern'.				*/
+/* pattern matching is case-insensitive										*/
+/* patterns beginning with ';' are comments (never match)					*/
+/* patterns beginning with '!' are reverse-matched (returns FALSE if match)	*/
+/* patterns ending in '~' will match string anywhere (sub-string search)	*/
+/* patterns ending in '^' will match left string fragment only				*/
+/* patterns including '*' must match both left and right string fragments	*/
+/* all other patterns are exact-match checking								*/
+/****************************************************************************/
+BOOL findstr_in_string(const char* search, const char* pattern)
+{
+	char	buf[256];
 	char*	p;
-	char	str[256];
-	char	search[81];
-	int		c;
-	int		i;
-	BOOL	found=FALSE;
-
-	if(string==NULL || insearchof==NULL)
-		return(FALSE);
+	char*	last;
+	const char*	splat;
+	size_t	len;
+	BOOL	found = FALSE;
 
-	SAFECOPY(search,insearchof);
-	strupr(search);
-	SAFECOPY(str,string);
+	if(pattern == NULL || search == NULL)
+		return FALSE;
 
-	p=str;	
-//	SKIP_WHITESPACE(p);
+	SAFECOPY(buf, pattern);
+	p = buf;
 
-	if(*p==';')		/* comment */
-		return(FALSE);
+	if(*p == ';')		/* comment */
+		return FALSE;
 
-	if(*p=='!')	{	/* !match */
-		found=TRUE;
+	if(*p == '!')	{	/* reverse-match */
+		found = TRUE;
 		p++;
 	}
 
 	truncsp(p);
-	c=strlen(p);
-	if(c) {
-		c--;
-		strupr(p);
-		if(p[c]=='~') {
-			p[c]=0;
-			if(strstr(search,p))
-				found=!found; 
+	len = strlen(p);
+	if(len > 0) {
+		last = p + len - 1;
+		if(*last == '~') {
+			*last = '\0';
+			if(strcasestr(search, p) != NULL)
+				found = !found; 
 		}
 
-		else if(p[c]=='^' || p[c]=='*') {
-			p[c]=0;
-			if(!strncmp(p,search,c))
-				found=!found; 
+		else if(*last == '^') {
+			if(strnicmp(p, search, len - 1) == 0)
+				found = !found; 
 		}
 
-		else if(p[0]=='*') {
-			i=strlen(search);
-			if(i<c)
-				return(found);
-			if(!strncmp(p+1,search+(i-c),c))
-				found=!found; 
+		else if((splat = strchr(p, '*')) != NULL) {
+			int left = splat - p;
+			int right = len - (left + 1);
+			int slen = strlen(search);
+			if(slen < left + right)
+				return found;
+			if(strnicmp(search, p, left) == 0
+				&& strnicmp(p + left + 1, search + (slen - right), right) == 0)
+				found = !found;
 		}
 
-		else if(!strcmp(p,search))
-			found=!found; 
+		else if(stricmp(p, search) == 0)
+			found = !found; 
 	} 
-	return(found);
+	return found;
 }
 
 static uint32_t encode_ipv4_address(unsigned int byte[])
diff --git a/src/sbbs3/str_util.h b/src/sbbs3/str_util.h
index f8dec9b39d..010a6ea9dd 100644
--- a/src/sbbs3/str_util.h
+++ b/src/sbbs3/str_util.h
@@ -46,7 +46,7 @@ DLLEXPORT char *    replace_named_values(const char* src ,char* buf, size_t bufl
 DLLEXPORT char *	condense_whitespace(char* str);
 DLLEXPORT char		exascii_to_ascii_char(uchar ch);
 DLLEXPORT BOOL		findstr(const char *insearch, const char *fname);
-DLLEXPORT BOOL		findstr_in_string(const char* insearchof, char* string);
+DLLEXPORT BOOL		findstr_in_string(const char* insearchof, const char* pattern);
 DLLEXPORT BOOL		findstr_in_list(const char* insearchof, str_list_t list);
 DLLEXPORT str_list_t findstr_list(const char* fname);
 DLLEXPORT BOOL		trashcan(scfg_t* cfg, const char *insearch, const char *name);
-- 
GitLab