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:
ac-stef
2015-05-18 14:46:03 +02:00
parent e318ecd68e
commit 786a6cdce1
8 changed files with 71 additions and 29 deletions
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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')
{
+5 -2
View File
@@ -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)
+13 -9
View File
@@ -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
View File
@@ -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);
}
+1
View File
@@ -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;