Don't try to clean up .. segments in fteqcc's include paths. Its buggy, and doesn't handle symlink weirdness properly.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5805 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-02-08 10:59:53 +00:00
parent 193d14a931
commit e26f26e170
2 changed files with 28 additions and 51 deletions

View File

@ -9,7 +9,7 @@
#include <dirent.h>
#include <sys/stat.h>
#endif
void QCC_Canonicalize(char *fullname, size_t fullnamesize, const char *newfile, const char *base);
void QCC_JoinPaths(char *fullname, size_t fullnamesize, const char *newfile, const char *base);
//package formats:
//pakzip - files are uncompressed, with both a pak header and a zip trailer, allowing it to be read as either type of file.
@ -376,7 +376,7 @@ static void PKG_CreateOutput(struct pkgctx_s *ctx, struct dataset_s *s, const ch
memset(o, 0, sizeof(*o));
strcpy(o->code, code);
o->usediffs = diff;
QCC_Canonicalize(o->filename, sizeof(o->filename), path, ctx->gamepath);
QCC_JoinPaths(o->filename, sizeof(o->filename), path, ctx->gamepath);
o->next = s->outputs;
s->outputs = o;
@ -679,7 +679,7 @@ static void PKG_AddClassFiles(struct pkgctx_s *ctx, struct class_s *c, const cha
char basepath[MAX_OSPATH], tmppath[MAX_OSPATH];
struct stat statbuf;
QCC_Canonicalize(basepath, sizeof(basepath), fname, ctx->sourcepath);
QCC_JoinPaths(basepath, sizeof(basepath), fname, ctx->sourcepath);
QC_strlcat(basepath, "/", sizeof(basepath));
dir = opendir(basepath);
if (!dir)
@ -691,8 +691,8 @@ static void PKG_AddClassFiles(struct pkgctx_s *ctx, struct class_s *c, const cha
{
if (*ent->d_name == '.')
continue;
QCC_Canonicalize(basepath, sizeof(basepath), ent->d_name, fname);
QCC_Canonicalize(tmppath, sizeof(tmppath), basepath, ctx->sourcepath);
QCC_JoinPaths(basepath, sizeof(basepath), ent->d_name, fname);
QCC_JoinPaths(tmppath, sizeof(tmppath), basepath, ctx->sourcepath);
if (stat(tmppath, &statbuf)!=0)
continue;
@ -958,7 +958,7 @@ static void *PKG_OpenSourceFile(struct pkgctx_s *ctx, struct file_s *file, size_
*fsize = 0;
QCC_Canonicalize(fullname, sizeof(fullname), file->name, ctx->sourcepath);
QCC_JoinPaths(fullname, sizeof(fullname), file->name, ctx->sourcepath);
strcpy(file->write.name, file->name);
//WIN32 FIXME: use the utf16 version because microsoft suck and don't allow utf-8
@ -996,7 +996,7 @@ static void *PKG_OpenSourceFile(struct pkgctx_s *ctx, struct file_s *file, size_
//delete temp file...
fclose(f);
QCC_Canonicalize(tempname, sizeof(tempname), file->write.name, ctx->sourcepath);
QCC_JoinPaths(tempname, sizeof(tempname), file->write.name, ctx->sourcepath);
f = fopen(tempname, "rb");
if (f)
{
@ -1702,7 +1702,7 @@ void Packager_ParseText(struct pkgctx_s *ctx, char *scripttext)
if (PKG_GetStringToken(ctx, cmd, sizeof(cmd)))
{
QC_strlcat(cmd, "/", sizeof(cmd));
QCC_Canonicalize(ctx->sourcepath, sizeof(ctx->sourcepath), cmd, old);
QCC_JoinPaths(ctx->sourcepath, sizeof(ctx->sourcepath), cmd, old);
}
}
else if (!strcmp(cmd, "rule"))

View File

@ -218,56 +218,33 @@ pbool QCC_PR_UnInclude(void)
return true;
}
void QCC_Canonicalize(char *fullname, size_t fullnamesize, const char *newfile, const char *base)
//expresses a relative path relative to an existing FILEname. any directories in base must be / terminated properly.
void QCC_JoinPaths(char *fullname, size_t fullnamesize, const char *newfile, const char *base)
{
int doubledots;
char *end = fullname;
doubledots = 0;
char *end;
/*count how far up we need to go*/
while(1)
{
if (!strncmp(newfile, "./", 2) || !strncmp(newfile, ".\\", 2))
newfile+=2;
else if(!strncmp(newfile, "../", 3) || !strncmp(newfile, "..\\", 3))
{
newfile+=3;
doubledots++;
}
else
break;
if (*newfile == '/' || *newfile == '\\')
{ //its an absolute path...
QC_strlcpy(fullname, newfile, fullnamesize);
return;
}
//FIXME: length validation!
if (base)
strcpy(fullname, base);
else
*fullname = 0;
QC_strlcpy(fullname, base, fullnamesize);
end = fullname+strlen(fullname);
while (end > fullname)
{
end--;
/*stop at the slash, unless we're meant to go further*/
if (*end == '/' || *end == '\\')
{
if (!doubledots)
{
end++;
break;
}
doubledots--;
end++;
break;
}
}
QC_strlcpy(end, newfile, fullnamesize - (end-fullname));
while (doubledots-- > 0)
{
strcpy(end, "../");
end += 3;
}
strcpy(end, newfile);
//FIXME: do we want to convert /segment/../ into just / ?
//fteqw might insist on it for its filesystem sandboxing.
//but it breaks symlink weirdness (itself a possible security hole).
//should probably be a separate function.
}
extern char qccmsourcedir[];
@ -291,7 +268,7 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, pbool verbose)
currentfile = qccincludedir[includepath-1];
}
QCC_Canonicalize(fullname, sizeof(fullname), newfile, currentfile);
QCC_JoinPaths(fullname, sizeof(fullname), newfile, currentfile);
{
extern progfuncs_t *qccprogfuncs;
@ -954,7 +931,7 @@ static pbool QCC_PR_Precompiler(void)
QCC_ImportProgs(pr_token);
if (!*destfile && !destfile_explicit)
{
QCC_Canonicalize(destfile, sizeof(destfile), pr_token, compilingfile);
QCC_JoinPaths(destfile, sizeof(destfile), pr_token, compilingfile);
externs->Printf("Outputfile: %s\n", destfile);
}
@ -1079,7 +1056,7 @@ static pbool QCC_PR_Precompiler(void)
QCC_PR_SimpleGetString();
if (!destfile_explicit)
{
QCC_Canonicalize(destfile, sizeof(destfile), pr_token, compilingfile);
QCC_JoinPaths(destfile, sizeof(destfile), pr_token, compilingfile);
externs->Printf("Outputfile: %s\n", pr_token);
}
@ -1213,7 +1190,7 @@ static pbool QCC_PR_Precompiler(void)
QC_strlcat(qcc_token, "/", sizeof(qcc_token));
}
QCC_Canonicalize(newinc, sizeof(newinc), qcc_token, compilingfile);
QCC_JoinPaths(newinc, sizeof(newinc), qcc_token, compilingfile);
QCC_PR_AddIncludePath(newinc);
}
else if (!QC_strcasecmp(qcc_token, "noref"))
@ -1332,7 +1309,7 @@ static pbool QCC_PR_Precompiler(void)
QCC_COM_Parse(msg);
if (!destfile_explicit) //if output file is named on the commandline, don't change it mid-compile
QCC_Canonicalize(destfile, sizeof(destfile), qcc_token, compilingfile);
QCC_JoinPaths(destfile, sizeof(destfile), qcc_token, compilingfile);
if (strcmp(destfile, olddest))
externs->Printf("Outputfile: %s\n", destfile);