filename filtering for media files
No more spaces in filenames. The only allowed chars are a-z, A-Z, 0-9 and "-_.()". An exception are texture filenames, which may also have a prefix command like "<decal>" included. Also fixed some memory leaks in media download.
This commit is contained in:
@@ -811,6 +811,7 @@ COMMANDF(registersound, "siii", (char *name, int *vol, int *loop, int *audiblera
|
||||
|
||||
COMMANDF(mapsound, "si", (char *name, int *maxuses)
|
||||
{
|
||||
filtertext(name, name, FTXT__MEDIAFILEPATH);
|
||||
audiomgr.addsound(name, 255, *maxuses, true, mapsounds, false, 0);
|
||||
intret(mapconfigdata.mapsoundlines.length());
|
||||
copystring(mapconfigdata.mapsoundlines.add().name, name);
|
||||
|
||||
+10
-7
@@ -1146,21 +1146,24 @@ int downloadpackages()
|
||||
|
||||
bool requirepackage(int type, const char *path)
|
||||
{
|
||||
if(!havecurl || canceldownloads || type < 0 || type >= PCK_NUM || pendingpackages.access(path)) return false;
|
||||
pckserver *source = NULL;
|
||||
loopv(pckservers) if(pckservers[i]->responsive) { source = pckservers[i]; break; }
|
||||
if(!source) { conoutf(_("\f3no responsive source server found, can't download")); return false; }
|
||||
|
||||
char *cleanpath = unixpath(newstring(path));
|
||||
filtertext(cleanpath, cleanpath, FTXT__MEDIAFILEPATH);
|
||||
if(strcmp(path, cleanpath)) { conoutf("refuse to download \"%s\": illegal characters", path); delstring(cleanpath); return false; }
|
||||
if(!havecurl || canceldownloads || type < 0 || type >= PCK_NUM || pendingpackages.access(cleanpath)) { delstring(cleanpath); return false; }
|
||||
|
||||
package *pck = new package;
|
||||
pck->name = unixpath(newstring(path));
|
||||
pck->name = cleanpath;
|
||||
pck->type = type;
|
||||
loopv(pckservers) if(pckservers[i]->responsive) { pck->source = pckservers[i]; break; }
|
||||
if(!pck->source) { conoutf(_("\f3no responsive source server found, can't download")); return false; }
|
||||
pck->source = source;
|
||||
pck->pending = true;
|
||||
|
||||
pendingpackages.access(pck->name, pck);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void writepcksourcecfg()
|
||||
{
|
||||
if(pckservers.length())
|
||||
|
||||
+2
-1
@@ -255,6 +255,7 @@ struct md3 : vertmodel
|
||||
void md3load(char *model)
|
||||
{
|
||||
if(!loadingmd3) { conoutf("not loading an md3"); return; };
|
||||
filtertext(model, model, FTXT__MEDIAFILEPATH);
|
||||
defformatstring(filename)("%s/%s", md3dir, model);
|
||||
md3::md3part &mdl = *new md3::md3part;
|
||||
loadingmd3->parts.add(&mdl);
|
||||
@@ -265,7 +266,7 @@ void md3load(char *model)
|
||||
|
||||
void md3skin(char *objname, char *skin)
|
||||
{
|
||||
if(!objname || !skin) return;
|
||||
filtertext(skin, skin, FTXT__MEDIAFILEPATH);
|
||||
if(!loadingmd3 || loadingmd3->parts.empty()) { conoutf("not loading an md3"); return; };
|
||||
md3::part &mdl = *loadingmd3->parts.last();
|
||||
bool used = false;
|
||||
|
||||
+19
-8
@@ -123,6 +123,8 @@ void getstring(char *text, ucharbuf &p, int len)
|
||||
// dst can be identical to src; dst needs to be of size "min(len, strlen(s)) + 1"
|
||||
// returns dst
|
||||
|
||||
//#define FILENAMESALLLOWERCASE
|
||||
|
||||
char *filtertext(char *dst, const char *src, int flags, int len)
|
||||
{
|
||||
char *res = dst;
|
||||
@@ -137,7 +139,8 @@ char *filtertext(char *dst, const char *src, int flags, int len)
|
||||
leet = (flags & FTXT_LEET) != 0, // translates leetspeak
|
||||
toupp = (flags & FTXT_TOUPPER) != 0, // translates to all-uppercase
|
||||
tolow = (flags & FTXT_TOLOWER) != 0, // translates to all-lowercase
|
||||
filename = (flags & FTXT_FILENAME) != 0, // removes characters, that are not allowed in filenames on all supported systems - does not filter COM, PRN, etc.
|
||||
filename = (flags & FTXT_FILENAME) != 0, // strict a-z, 0-9 and "-_.()" (also translates "[]" and "{}" to "()"), removes everything between '<' and '>'
|
||||
allowslash = (flags & FTXT_ALLOWSLASH) != 0, // only in combination with FTXT_FILENAME
|
||||
mapname = (flags & FTXT_MAPNAME) != 0, // only allows lowercase chars, digits, '_', '-' and '.'; probably should be used in combination with TOLOWER
|
||||
cropwhite = (flags & FTXT_CROPWHITE) != 0, // removes leading and trailing whitespace
|
||||
pass = false;
|
||||
@@ -153,9 +156,13 @@ char *filtertext(char *dst, const char *src, int flags, int len)
|
||||
}
|
||||
#endif
|
||||
if(leet || mapname) nocolor = true;
|
||||
#ifdef FILENAMESALLLOWERCASE
|
||||
if(filename) tolow = true;
|
||||
#endif
|
||||
bool trans = toupp || tolow || leet || filename || fillblanks;
|
||||
bool leadingwhite = cropwhite;
|
||||
char *lastwhite = NULL;
|
||||
bool insidepointybrackets = false;
|
||||
for(int c = *src; c; c = *++src)
|
||||
{
|
||||
c &= 0x7F; // 7-bit ascii. not negotiable.
|
||||
@@ -171,19 +178,23 @@ char *filtertext(char *dst, const char *src, int flags, int len)
|
||||
}
|
||||
if(filename)
|
||||
{
|
||||
const char *org = "*?![]{};:/\\",
|
||||
*asc = "__o()()__oo", // 'o' -> ignore
|
||||
if(c == '>') insidepointybrackets = false;
|
||||
else if(c == '<') insidepointybrackets = true;
|
||||
if(insidepointybrackets || c == '>') continue; // filter anything between '<' and '>' as this may contain commands for texture loading
|
||||
const char *org = "[]{}\\",
|
||||
*asc = "()()/",
|
||||
*a = strchr(org, c);
|
||||
if(a)
|
||||
{
|
||||
c = asc[a - org];
|
||||
if(c == 'o') continue;
|
||||
}
|
||||
if(a) c = asc[a - org];
|
||||
}
|
||||
if(tolow) c = tolower(c);
|
||||
else if(toupp) c = toupper(c);
|
||||
if(fillblanks && c == ' ') c = '_';
|
||||
}
|
||||
if(filename && !(islower(c)
|
||||
#ifndef FILENAMESALLLOWERCASE
|
||||
|| isupper(c)
|
||||
#endif
|
||||
|| isdigit(c) || strchr("._-()", c) || (allowslash && c == '/'))) continue;
|
||||
if(safecs && strchr("($)\"", c)) continue;
|
||||
if(c == '\t')
|
||||
{
|
||||
|
||||
@@ -150,8 +150,9 @@ enum
|
||||
#define FTXT_TOUPPER (1<<17)
|
||||
#define FTXT_TOLOWER (1<<18)
|
||||
#define FTXT_FILENAME (1<<19)
|
||||
#define FTXT_MAPNAME (1<<20)
|
||||
#define FTXT_CROPWHITE (1<<21)
|
||||
#define FTXT_ALLOWSLASH (1<<20)
|
||||
#define FTXT_MAPNAME (1<<21)
|
||||
#define FTXT_CROPWHITE (1<<22)
|
||||
// character classes
|
||||
#define FTXT__SERVDESC (FTXT_NOWHITE | FTXT_ALLOWBLANKS | FTXT_TABTOBLANK)
|
||||
#define FTXT__MAPMSG (FTXT_NOWHITE | FTXT_ALLOWBLANKS | FTXT_TABTOBLANK)
|
||||
@@ -169,4 +170,6 @@ enum
|
||||
#define FTXT__KICKBANREASON (FTXT_NOWHITE | FTXT_ALLOWBLANKS | FTXT_NOCOLOR | FTXT_TABTOBLANK)
|
||||
#define FTXT__FAVCATEGORY (FTXT_NOWHITE | FTXT_ALLOWBLANKS | FTXT_NOCOLOR)
|
||||
#define FTXT__GLOBALNAME (FTXT_NOWHITE | FTXT_NOCOLOR | FTXT_FILLBLANKS)
|
||||
#define FTXT__MEDIAFILENAME (FTXT_FILENAME)
|
||||
#define FTXT__MEDIAFILEPATH (FTXT_FILENAME | FTXT_ALLOWSLASH)
|
||||
|
||||
|
||||
@@ -111,15 +111,19 @@ const char *mmshortname(const char *name) { return !strncmp(name, mmpath, strlen
|
||||
|
||||
void mapmodel(int *rad, int *h, int *zoff, char *snap, char *name)
|
||||
{
|
||||
intret(mapmodels.length());
|
||||
mapmodelinfo &mmi = mapmodels.add();
|
||||
mmi.rad = *rad;
|
||||
mmi.h = *h;
|
||||
mmi.zoff = *zoff;
|
||||
mmi.m = NULL;
|
||||
formatstring(mmi.name)("%s%s", mmpath, name);
|
||||
mapmodelchanged = 1;
|
||||
flagmapconfigchange();
|
||||
if(*snap && *name) // ignore "mapmodel" commands with insufficient parameters
|
||||
{
|
||||
intret(mapmodels.length());
|
||||
mapmodelinfo &mmi = mapmodels.add();
|
||||
mmi.rad = *rad;
|
||||
mmi.h = *h;
|
||||
mmi.zoff = *zoff;
|
||||
mmi.m = NULL;
|
||||
filtertext(name, name, FTXT__MEDIAFILEPATH);
|
||||
formatstring(mmi.name)("%s%s", mmpath, name);
|
||||
mapmodelchanged = 1;
|
||||
flagmapconfigchange();
|
||||
}
|
||||
}
|
||||
COMMAND(mapmodel, "iiiss");
|
||||
|
||||
|
||||
+20
-2
@@ -501,7 +501,23 @@ void texture(float *scale, char *name)
|
||||
{
|
||||
intret(slots.length());
|
||||
Slot &s = slots.add();
|
||||
copystring(s.name, name);
|
||||
filtertext(s.name, parentdir(name), FTXT__MEDIAFILEPATH); // filter parts separately, because filename may (legally) contain "<decal>"
|
||||
if(*s.name) concatstring(s.name, "/");
|
||||
name = (char *)behindpath(name);
|
||||
if(*name == '<')
|
||||
{
|
||||
char *endcmd = strchr(name, '>');
|
||||
if(endcmd)
|
||||
{
|
||||
*endcmd = '\0';
|
||||
concatstring(s.name, name);
|
||||
concatstring(s.name, ">");
|
||||
name = endcmd + 1;
|
||||
}
|
||||
}
|
||||
filtertext(name, name, FTXT__MEDIAFILENAME);
|
||||
concatstring(s.name, name);
|
||||
|
||||
s.tex = NULL;
|
||||
s.loaded = false;
|
||||
s.orgscale = *scale;
|
||||
@@ -586,6 +602,7 @@ void loadskymap(bool reload)
|
||||
if(!reload)
|
||||
{
|
||||
int n = strlen(legacyprefix);
|
||||
filtertext(loadsky, loadsky, FTXT__MEDIAFILEPATH);
|
||||
if(!strncmp(loadsky, legacyprefix, n))
|
||||
{ // remove the prefix
|
||||
char *t = loadsky;
|
||||
@@ -613,7 +630,8 @@ void loadnotexture(char *c)
|
||||
*mapconfigdata.notexturename = '\0';
|
||||
if(c[0])
|
||||
{
|
||||
defformatstring(p)("packages/textures/%s", c);
|
||||
filtertext(mapconfigdata.notexturename, c, FTXT__MEDIAFILEPATH);
|
||||
defformatstring(p)("packages/textures/%s", mapconfigdata.notexturename);
|
||||
noworldtexture = textureload(p);
|
||||
if(noworldtexture==notexture) conoutf("could not load alternative texture '%s'.", p);
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ bool extractzipfile(ziparchive *a, zipfile *f, const char *name);
|
||||
|
||||
bool fitspackage(char *filename, int type)
|
||||
{
|
||||
if(strchr(filename, ' ')) return false; // refuse all filenames with spaces
|
||||
char *extension = strrchr(filename, '.');
|
||||
if(!extension) return false;
|
||||
++extension;
|
||||
|
||||
Reference in New Issue
Block a user