forbidden dirs: allow wildcard patterns

This commit is contained in:
Rudolf Polzer 2011-07-01 11:27:15 +02:00
parent 4cd61dfa7d
commit c75ae4296b
5 changed files with 88 additions and 4 deletions

View File

@ -506,6 +506,7 @@ $(INSTALLDIR)/q3map2.$(EXE): \
tools/quake3/q3map2/vis.o \
tools/quake3/q3map2/writebsp.o \
libddslib.$(A) \
libfilematch.$(A) \
libjpeg6.$(A) \
libl_net.$(A) \
libmathlib.$(A) \
@ -693,6 +694,7 @@ $(INSTALLDIR)/radiant.$(EXE): \
radiant/xmlstuff.o \
radiant/xywindow.o \
libcmdlib.$(A) \
libfilematch.$(A) \
libgtkutil.$(A) \
libl_net.$(A) \
libmathlib.$(A) \
@ -700,6 +702,10 @@ $(INSTALLDIR)/radiant.$(EXE): \
libxmllib.$(A) \
$(if $(findstring $(OS),Win32),icons/radiant.o,) \
libfilematch.$(A): CPPFLAGS_EXTRA := -Ilibs
libfilematch.$(A): \
libs/filematch.o \
libcmdlib.$(A): CPPFLAGS_EXTRA := -Ilibs
libcmdlib.$(A): \
libs/cmdlib/cmdlib.o \

7
include/filematch.h Normal file
View File

@ -0,0 +1,7 @@
#if !defined(INCLUDED_FILEMATCH_H)
#define INCLUDED_FILEMATCH_H
int matchpattern(const char *in, const char *pattern, int caseinsensitive);
int matchpattern_with_separator(const char *in, const char *pattern, int caseinsensitive, const char *separators, int wildcard_least_one);
#endif

68
libs/filematch.c Normal file
View File

@ -0,0 +1,68 @@
#include "matchpattern.h"
// LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such...
int matchpattern(const char *in, const char *pattern, int caseinsensitive)
{
return matchpattern_with_separator(in, pattern, caseinsensitive, "/\\:", false);
}
// wildcard_least_one: if true * matches 1 or more characters
// if false * matches 0 or more characters
int matchpattern_with_separator(const char *in, const char *pattern, int caseinsensitive, const char *separators, int wildcard_least_one)
{
int c1, c2;
while (*pattern)
{
switch (*pattern)
{
case 0:
return 1; // end of pattern
case '?': // match any single character
if (*in == 0 || strchr(separators, *in))
return 0; // no match
in++;
pattern++;
break;
case '*': // match anything until following string
if(wildcard_least_one)
{
if (*in == 0 || strchr(separators, *in))
return 0; // no match
in++;
}
pattern++;
while (*in)
{
if (strchr(separators, *in))
break;
// see if pattern matches at this offset
if (matchpattern_with_separator(in, pattern, caseinsensitive, separators, wildcard_least_one))
return 1;
// nope, advance to next offset
in++;
}
break;
default:
if (*in != *pattern)
{
if (!caseinsensitive)
return 0; // no match
c1 = *in;
if (c1 >= 'A' && c1 <= 'Z')
c1 += 'a' - 'A';
c2 = *pattern;
if (c2 >= 'A' && c2 <= 'Z')
c2 += 'a' - 'A';
if (c1 != c2)
return 0; // no match
}
in++;
pattern++;
break;
}
}
if (*in)
return 0; // reached end of pattern but not end of input
return 1; // success
}

View File

@ -315,8 +315,9 @@ void InitDirectory(const char* directory, ArchiveModules& archiveModules)
for(j = 0; j < g_numForbiddenDirs; ++j)
{
if(!string_compare_nocase_upper(directory, g_strForbiddenDirs[j])
|| (string_length(directory) > string_length(g_strForbiddenDirs[j]) && directory[string_length(directory) - string_length(g_strForbiddenDirs[j]) - 1] == '/' && !string_compare_nocase_upper(directory + string_length(directory) - string_length(g_strForbiddenDirs[j]), g_strForbiddenDirs[j])))
const char *p = strrchr(directory, '/');
p = (p ? (p+1) : path);
if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
break;
}
if(j < g_numForbiddenDirs)

View File

@ -46,6 +46,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/stat.h>
#include "cmdlib.h"
#include "filematch.h"
#include "mathlib.h"
#include "inout.h"
#include "vfs.h"
@ -160,8 +161,9 @@ void vfsInitDirectory (const char *path)
for(j = 0; j < g_numForbiddenDirs; ++j)
{
if(!Q_stricmp(path, g_strForbiddenDirs[j])
|| (strlen(path) > strlen(g_strForbiddenDirs[j]) && path[strlen(path) - strlen(g_strForbiddenDirs[j]) - 1] == '/' && !Q_stricmp(path + strlen(path) - strlen(g_strForbiddenDirs[j]), g_strForbiddenDirs[j])))
const char *p = strrchr(path, '/');
p = (p ? (p+1) : path);
if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
break;
}
if(j < g_numForbiddenDirs)