From b7aaac27ff15c8152f071f552dfe5b5b597785f7 Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Mon, 16 Sep 2024 18:09:00 -0700
Subject: [PATCH] Only use liberal file pattern matching in the terminal server
 listfile funcs

Commit 3a3c889b (2 years ago now) changed loadfiles() to use liberal file
matching (e.g. "syncterm.exe" matched both "syncterm.exe" and
"syncterm_v1.2b.exe").

This could produce surprising results when doing file list querieis/operations
with the FileBase methods via JS (e.g. jsexec utils) and (now that I look at
it), the FTP server too.

So we should not have been doing liberal file matching *everywhere* loadfiles
is used, just where it was a usability issue (due to displayed filenames being
truncated to 12 chars for <=80 column terminals).

Now solved by add/use of new liberal_filepattern() function only in the
built-in file listing methods: sbbs_t::listfiles() and sbbs_t::listfileinfo().

Note: Custom JS file searching/listing scripts may now need their own
work-arounds for this usability issue, if they have it.
---
 src/sbbs3/filedat.c    | 37 ++++++++++++++++++++-----------------
 src/sbbs3/filedat.h    |  1 +
 src/sbbs3/listfile.cpp |  5 +++--
 3 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/src/sbbs3/filedat.c b/src/sbbs3/filedat.c
index af02ef8920..021263288c 100644
--- a/src/sbbs3/filedat.c
+++ b/src/sbbs3/filedat.c
@@ -187,26 +187,29 @@ str_list_t loadfilenames(smb_t* smb, const char* filespec, time_t t, enum file_s
 	return file_list;
 }
 
+// Liberal filespec matching when filespec does not contain wildcards and is at least 12 chars in length
+char* liberal_filepattern(const char* filespec, char* buf, size_t size)
+{
+	char newfilespec[SMB_FILEIDX_NAMELEN + 1] = "";
+	size_t len = strlen(filespec);
+	if (len <  12 || strcspn(filespec, "*?") != len)
+		return (char*)filespec;
+	SAFECOPY(newfilespec, filespec);
+	char* ext = getfext(filespec);
+	char* newext = getfext(newfilespec);
+	if(ext != NULL && newext != NULL) {
+		*newext = 0;
+		SAFECAT(newfilespec, "*");
+		SAFECAT(newfilespec, ext);
+	} else
+		SAFECAT(newfilespec, "*");
+	strlcpy(buf, newfilespec, size);
+	return buf;
+}
+
 // Load and optionally-sort files from an open filebase into a dynamically-allocated list of "objects"
 file_t* loadfiles(smb_t* smb, const char* filespec, time_t t, enum file_detail detail, enum file_sort order, size_t* count)
 {
-	// Liberal filespec matching when filespec does not contain wildcards and is at least 12 chars in length
-	char newfilespec[SMB_FILEIDX_NAMELEN + 1] = "";
-	if(filespec != NULL) {
-		size_t len = strlen(filespec);
-		if(len >= 12 && strcspn(filespec, "*?") == len) {
-			SAFECOPY(newfilespec, filespec);
-			char* ext = getfext(filespec);
-			char* newext = getfext(newfilespec);
-			if(ext != NULL && newext != NULL) {
-				*newext = 0;
-				SAFECAT(newfilespec, "*");
-				SAFECAT(newfilespec, ext);
-			} else
-				SAFECAT(newfilespec, "*");
-			filespec = newfilespec;
-		}
-	}
 	*count = 0;
 
 	long start = 0;	
diff --git a/src/sbbs3/filedat.h b/src/sbbs3/filedat.h
index 0a87c2b93c..cc43827193 100644
--- a/src/sbbs3/filedat.h
+++ b/src/sbbs3/filedat.h
@@ -66,6 +66,7 @@ DLLEXPORT char*			format_diz(const char* src, char* dest, size_t maxlen, int wid
 DLLEXPORT char*			prep_file_desc(const char *src, char* dst);
 DLLEXPORT int			file_client_hfields(file_t*, client_t*);
 DLLEXPORT int			file_sauce_hfields(file_t*, struct sauce_charinfo*);
+DLLEXPORT char*			liberal_filepattern(const char* filespec, char* buf, size_t size);
 
 DLLEXPORT str_list_t	directory(const char* path);
 DLLEXPORT long			create_archive(const char* archive, const char* format
diff --git a/src/sbbs3/listfile.cpp b/src/sbbs3/listfile.cpp
index ca1323f0be..7217757dba 100644
--- a/src/sbbs3/listfile.cpp
+++ b/src/sbbs3/listfile.cpp
@@ -36,6 +36,7 @@ int extdesclines(char *str);
 int sbbs_t::listfiles(const int dirnum, const char *filespec, FILE* tofile, const int mode)
 {
 	char	hdr[256],letter='A';
+	char	filepattern[SMB_FILEIDX_NAMELEN + 1] = "";
 	uchar	flagprompt=0;
 	int		c, d;
 	int		i,j;
@@ -72,7 +73,7 @@ int sbbs_t::listfiles(const int dirnum, const char *filespec, FILE* tofile, cons
 
 	size_t file_count = 0;
 	file_t* file_list = loadfiles(&smb
-		, (mode & FL_FIND) ? NULL : filespec
+		, (mode & FL_FIND) ? NULL : liberal_filepattern(filespec, filepattern, sizeof filepattern)
 		, (mode & FL_ULTIME) ? ns_time : 0
 		, tofile == NULL ? file_detail_extdesc : file_detail_normal
 		, (enum file_sort)cfg.dir[dirnum]->sort
@@ -766,7 +767,7 @@ int sbbs_t::listfileinfo(const int dirnum, const char *filespec, const int mode)
 
 	size_t file_count = 0;
 	file_t* file_list = loadfiles(&smb
-		, filespec
+		, liberal_filepattern(filespec, str, sizeof str)
 		, /* time_t */0
 		, file_detail_extdesc
 		, (enum file_sort)cfg.dir[dirnum]->sort
-- 
GitLab