mirror of
https://github.com/libretro/libretro-tyrquake.git
synced 2025-02-17 06:19:05 +00:00
common: make COM_StripExtension and COM_DefaultExtension check buffers
Pass an input and output buffer in (can be the same pointer) and ensure that no more is written to the output buffer than will fit. COM_DefaultExtension now returns an error if it ran out of space adding the extension. Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
parent
4d0773d6a1
commit
376f9a7de5
35
NQ/cl_demo.c
35
NQ/cl_demo.c
@ -203,9 +203,8 @@ record <demoname> <map> [cd track]
|
||||
void
|
||||
CL_Record_f(void)
|
||||
{
|
||||
int c;
|
||||
int c, track, length, err;
|
||||
char name[MAX_OSPATH];
|
||||
int track;
|
||||
|
||||
if (cmd_source != src_command)
|
||||
return;
|
||||
@ -234,22 +233,22 @@ CL_Record_f(void)
|
||||
} else
|
||||
track = -1;
|
||||
|
||||
sprintf(name, "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
/* Grab the filename before our cmd args disappear */
|
||||
length = snprintf(name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
err = COM_DefaultExtension(name, ".dem", name, sizeof(name));
|
||||
if (length >= sizeof(name) || err) {
|
||||
Con_Printf("Error: demo path name too long.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// start the map up
|
||||
//
|
||||
/* start the map up */
|
||||
if (c > 2) {
|
||||
Cmd_ExecuteString(va("map %s", Cmd_Argv(2)), src_command);
|
||||
if (cls.state != ca_connected)
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// open the demo file
|
||||
//
|
||||
COM_DefaultExtension(name, ".dem");
|
||||
|
||||
/* open the demo file */
|
||||
Con_Printf("recording to %s.\n", name);
|
||||
cls.demofile = fopen(name, "wb");
|
||||
if (!cls.demofile) {
|
||||
@ -273,8 +272,8 @@ play [demoname]
|
||||
void
|
||||
CL_PlayDemo_f(void)
|
||||
{
|
||||
char name[256], forcetrack[12];
|
||||
int i, c;
|
||||
char name[MAX_QPATH], forcetrack[12];
|
||||
int i, c, err;
|
||||
|
||||
if (cmd_source != src_command)
|
||||
return;
|
||||
@ -291,14 +290,18 @@ CL_PlayDemo_f(void)
|
||||
//
|
||||
// open the demo file
|
||||
//
|
||||
strcpy(name, Cmd_Argv(1));
|
||||
COM_DefaultExtension(name, ".dem");
|
||||
err = COM_DefaultExtension(Cmd_Argv(1), ".dem", name, sizeof(name));
|
||||
if (err) {
|
||||
Con_Printf("Error: demo filename too long\n");
|
||||
cls.demonum = -1; /* stop demo loop */
|
||||
return;
|
||||
}
|
||||
|
||||
Con_Printf("Playing demo from %s.\n", name);
|
||||
COM_FOpenFile(name, &cls.demofile);
|
||||
if (!cls.demofile) {
|
||||
Con_Printf("ERROR: couldn't open.\n");
|
||||
cls.demonum = -1; // stop demo loop
|
||||
cls.demonum = -1; /* stop demo loop */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -346,8 +346,7 @@ CL_ParseServerInfo(void)
|
||||
|
||||
// copy the naked name of the map file to the cl structure
|
||||
mapname = COM_SkipPath(model_precache[1]);
|
||||
snprintf(cl.mapname, sizeof(cl.mapname), "%s", mapname);
|
||||
COM_StripExtension(cl.mapname);
|
||||
COM_StripExtension(mapname, cl.mapname, sizeof(cl.mapname));
|
||||
|
||||
//
|
||||
// now we try to load everything else until a cache allocation fails
|
||||
|
@ -276,9 +276,9 @@ Host_Savegame_f
|
||||
static void
|
||||
Host_Savegame_f(void)
|
||||
{
|
||||
char name[256];
|
||||
char name[MAX_OSPATH];
|
||||
FILE *f;
|
||||
int i;
|
||||
int i, length, err;
|
||||
char comment[SAVEGAME_COMMENT_LENGTH + 1];
|
||||
|
||||
if (cmd_source != src_command)
|
||||
@ -316,8 +316,12 @@ Host_Savegame_f(void)
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(name, "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
COM_DefaultExtension(name, ".sav");
|
||||
length = snprintf(name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
err = COM_DefaultExtension(name, ".sav", name, sizeof(name));
|
||||
if (length >= sizeof(name) || err) {
|
||||
Con_Printf("ERROR: couldn't save, filename too long.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Con_Printf("Saving game to %s...\n", name);
|
||||
f = fopen(name, "w");
|
||||
@ -364,13 +368,13 @@ static void
|
||||
Host_Loadgame_f(void)
|
||||
{
|
||||
char name[MAX_OSPATH];
|
||||
FILE *f;
|
||||
char mapname[MAX_QPATH];
|
||||
FILE *f;
|
||||
float time, tfloat;
|
||||
char str[32768];
|
||||
char *lightstyle;
|
||||
const char *start;
|
||||
int i, r;
|
||||
int i, r, length, err;
|
||||
edict_t *ent;
|
||||
int entnum;
|
||||
int version;
|
||||
@ -386,8 +390,12 @@ Host_Loadgame_f(void)
|
||||
|
||||
cls.demonum = -1; // stop demo loop in case this fails
|
||||
|
||||
sprintf(name, "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
COM_DefaultExtension(name, ".sav");
|
||||
length = snprintf(name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
err = COM_DefaultExtension(name, ".sav", name, sizeof(name));
|
||||
if (length >= sizeof(name) || err) {
|
||||
Con_Printf("ERROR: couldn't open save game, filename too long.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// we can't call SCR_BeginLoadingPlaque, because too much stack space has
|
||||
// been used. The menu calls it before stuffing loadgame command
|
||||
|
@ -389,7 +389,7 @@ CL_Record_f(void)
|
||||
char name[MAX_OSPATH];
|
||||
sizebuf_t buf;
|
||||
byte buf_data[MAX_MSGLEN];
|
||||
int n, i, j;
|
||||
int n, i, j, length, err;
|
||||
char *s;
|
||||
const entity_t *ent;
|
||||
entity_state_t *es, blankes;
|
||||
@ -410,13 +410,14 @@ CL_Record_f(void)
|
||||
if (cls.demorecording)
|
||||
CL_Stop_f();
|
||||
|
||||
sprintf(name, "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
|
||||
//
|
||||
// open the demo file
|
||||
//
|
||||
COM_DefaultExtension(name, ".qwd");
|
||||
length = snprintf(name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
err = COM_DefaultExtension(name, ".qwd", name, sizeof(name));
|
||||
if (length >= sizeof(name) || err) {
|
||||
Con_Printf("ERROR: couldn't open demo, filename too long.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* open the demo file */
|
||||
cls.demofile = fopen(name, "wb");
|
||||
if (!cls.demofile) {
|
||||
Con_Printf("ERROR: couldn't open.\n");
|
||||
@ -672,7 +673,7 @@ record <demoname>
|
||||
void
|
||||
CL_ReRecord_f(void)
|
||||
{
|
||||
int c;
|
||||
int c, length, err;
|
||||
char name[MAX_OSPATH];
|
||||
|
||||
c = Cmd_Argc();
|
||||
@ -689,13 +690,14 @@ CL_ReRecord_f(void)
|
||||
if (cls.demorecording)
|
||||
CL_Stop_f();
|
||||
|
||||
sprintf(name, "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
|
||||
//
|
||||
// open the demo file
|
||||
//
|
||||
COM_DefaultExtension(name, ".qwd");
|
||||
length = snprintf(name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||
err = COM_DefaultExtension(name, ".qwd", name, sizeof(name));
|
||||
if (length >= sizeof(name) || err) {
|
||||
Con_Printf("ERROR: open demo file, filename too long.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* open the demo file */
|
||||
cls.demofile = fopen(name, "wb");
|
||||
if (!cls.demofile) {
|
||||
Con_Printf("ERROR: couldn't open.\n");
|
||||
@ -720,7 +722,8 @@ play [demoname]
|
||||
void
|
||||
CL_PlayDemo_f(void)
|
||||
{
|
||||
char name[256];
|
||||
int err;
|
||||
char name[MAX_QPATH];
|
||||
|
||||
if (Cmd_Argc() != 2) {
|
||||
Con_Printf("play <demoname> : plays a demo\n");
|
||||
@ -731,17 +734,19 @@ CL_PlayDemo_f(void)
|
||||
//
|
||||
CL_Disconnect();
|
||||
|
||||
//
|
||||
// open the demo file
|
||||
//
|
||||
strcpy(name, Cmd_Argv(1));
|
||||
COM_DefaultExtension(name, ".qwd");
|
||||
err = COM_DefaultExtension(Cmd_Argv(1), ".qwd", name, sizeof(name));
|
||||
if (err) {
|
||||
Con_Printf("ERROR: couldn't open demo, filename too long.\n");
|
||||
cls.demonum = -1; /* stop demo loop */
|
||||
return;
|
||||
}
|
||||
|
||||
/* open the demo file */
|
||||
Con_Printf("Playing demo from %s.\n", name);
|
||||
COM_FOpenFile(name, &cls.demofile);
|
||||
if (!cls.demofile) {
|
||||
Con_Printf("ERROR: couldn't open.\n");
|
||||
cls.demonum = -1; // stop demo loop
|
||||
cls.demonum = -1; /* stop demo loop */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ qboolean
|
||||
CL_CheckOrDownloadFile(char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int maxlen;
|
||||
int err;
|
||||
|
||||
if (strstr(filename, "..")) {
|
||||
Con_Printf("Refusing to download a path with ..\n");
|
||||
@ -200,16 +200,12 @@ CL_CheckOrDownloadFile(char *filename)
|
||||
* download to a temp name, and only rename to the real name when
|
||||
* done, so if interrupted a runt file wont be left
|
||||
*/
|
||||
strcpy(cls.downloadtempname, cls.downloadname); /* same size */
|
||||
COM_StripExtension(cls.downloadtempname);
|
||||
|
||||
/* make sure the .tmp extension fits... */
|
||||
maxlen = sizeof(cls.downloadtempname);
|
||||
if (strlen(cls.downloadtempname) + strlen(".tmp") > maxlen - 1) {
|
||||
err = COM_DefaultExtension(cls.downloadname, ".tmp", cls.downloadtempname,
|
||||
sizeof(cls.downloadtempname));
|
||||
if (err) {
|
||||
Con_Printf("Refusing download, pathname too long\n");
|
||||
return true;
|
||||
}
|
||||
strcat(cls.downloadtempname, ".tmp");
|
||||
|
||||
MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteStringf(&cls.netchan.message, "download %s", cls.downloadname);
|
||||
@ -897,15 +893,16 @@ CL_NewTranslation(int slot)
|
||||
int top, bottom;
|
||||
byte *dest, *source;
|
||||
player_info_t *player;
|
||||
char *skin;
|
||||
const char *skin_key;
|
||||
char skin[MAX_QPATH];
|
||||
|
||||
if (slot > MAX_CLIENTS)
|
||||
Sys_Error("%s: slot > MAX_CLIENTS", __func__);
|
||||
|
||||
player = &cl.players[slot];
|
||||
|
||||
skin = Info_ValueForKey(player->userinfo, "skin");
|
||||
COM_StripExtension(skin);
|
||||
skin_key = Info_ValueForKey(player->userinfo, "skin");
|
||||
COM_StripExtension(skin_key, skin, sizeof(skin));
|
||||
|
||||
if (player->skin && !strcasecmp(skin, player->skin->name))
|
||||
player->skin = NULL;
|
||||
|
@ -48,7 +48,7 @@ Skin_Find(player_info_t * sc)
|
||||
{
|
||||
skin_t *skin;
|
||||
int i;
|
||||
char name[128];
|
||||
char name[MAX_QPATH];
|
||||
const char *skinname;
|
||||
|
||||
skinname = allskins;
|
||||
@ -60,8 +60,7 @@ Skin_Find(player_info_t * sc)
|
||||
if (strstr(skinname, "..") || skinname[0] == '.')
|
||||
skinname = "base";
|
||||
|
||||
snprintf(name, sizeof(name), "%s", skinname);
|
||||
COM_StripExtension(name);
|
||||
COM_StripExtension(skinname, name, sizeof(name));
|
||||
|
||||
for (i = 0; i < numskins; i++) {
|
||||
if (!strcmp(name, skins[i].name)) {
|
||||
|
@ -942,14 +942,22 @@ COM_StripExtension
|
||||
============
|
||||
*/
|
||||
void
|
||||
COM_StripExtension(char *filename)
|
||||
COM_StripExtension(const char *filename, char *out, size_t buflen)
|
||||
{
|
||||
const char *start;
|
||||
const char *start, *pos;
|
||||
size_t copylen;
|
||||
|
||||
start = COM_SkipPath(filename);
|
||||
char *pos = strrchr(start, '.');
|
||||
if (pos && *pos)
|
||||
*pos = 0;
|
||||
pos = strrchr(start, '.');
|
||||
if (out == filename) {
|
||||
if (pos && *pos)
|
||||
out[pos - filename] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
copylen = qmin((size_t)(pos - filename), buflen - 1);
|
||||
memcpy(out, filename, copylen);
|
||||
out[copylen] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1005,24 +1013,21 @@ COM_FileBase(const char *in, char *out, size_t buflen)
|
||||
/*
|
||||
==================
|
||||
COM_DefaultExtension
|
||||
Returns non-zero if the extension wouldn't fit in the output buffer
|
||||
==================
|
||||
*/
|
||||
void
|
||||
COM_DefaultExtension(char *path, const char *extension)
|
||||
int
|
||||
COM_DefaultExtension(const char *path, const char *extension, char *out,
|
||||
size_t buflen)
|
||||
{
|
||||
const char *src;
|
||||
COM_StripExtension(path, out, buflen);
|
||||
if (strlen(out) + strlen(extension) + 1 > buflen)
|
||||
return -1;
|
||||
|
||||
//
|
||||
// if path doesn't have a .EXT, append extension
|
||||
// (extension should include the .)
|
||||
//
|
||||
src = path + strlen(path) - 1;
|
||||
while (*src != '/' && src != path) {
|
||||
if (*src == '.')
|
||||
return; // it has an extension
|
||||
src--;
|
||||
}
|
||||
strcat(path, extension);
|
||||
/* Copy extension, including terminating null */
|
||||
memcpy(out + strlen(out), extension, strlen(extension) + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -328,7 +328,7 @@ void
|
||||
GL_LoadMeshData(const model_t *model, aliashdr_t *hdr, const mtriangle_t *tris,
|
||||
const stvert_t *stverts, const trivertx_t **poseverts)
|
||||
{
|
||||
int i, j, tmp;
|
||||
int i, j, tmp, err;
|
||||
int *cmds;
|
||||
trivertx_t *verts;
|
||||
char cache[MAX_QPATH];
|
||||
@ -341,10 +341,9 @@ GL_LoadMeshData(const model_t *model, aliashdr_t *hdr, const mtriangle_t *tris,
|
||||
//
|
||||
name = COM_SkipPath(model->name);
|
||||
snprintf(cache, sizeof(cache), "%s/glquake/%s", com_gamedir, name);
|
||||
COM_StripExtension(cache);
|
||||
if (strlen(cache) + strlen(".ms2") + 1 > sizeof(cache))
|
||||
err = COM_DefaultExtension(cache, ".ms2", cache, sizeof(cache));
|
||||
if (err)
|
||||
Sys_Error("%s: model pathname too long (%s)", __func__, model->name);
|
||||
strncat(cache, ".ms2", 4);
|
||||
|
||||
f = fopen(cache, "rb");
|
||||
if (f) {
|
||||
|
@ -367,7 +367,8 @@ R_TranslatePlayerSkin(int playernum)
|
||||
const entity_t *e;
|
||||
#endif
|
||||
#ifdef QW_HACK
|
||||
char *skin;
|
||||
const char *skin_key;
|
||||
char skin[MAX_QPATH];
|
||||
#endif
|
||||
|
||||
GL_DisableMultitexture();
|
||||
@ -380,8 +381,8 @@ R_TranslatePlayerSkin(int playernum)
|
||||
if (!player->name[0])
|
||||
return;
|
||||
|
||||
skin = Info_ValueForKey(player->userinfo, "skin");
|
||||
COM_StripExtension(skin);
|
||||
skin_key = Info_ValueForKey(player->userinfo, "skin");
|
||||
COM_StripExtension(skin_key, skin, sizeof(skin));
|
||||
if (player->skin && !strcasecmp(skin, player->skin->name))
|
||||
player->skin = NULL;
|
||||
|
||||
|
@ -183,9 +183,10 @@ void COM_Init(void);
|
||||
void COM_InitArgv(int argc, const char **argv);
|
||||
|
||||
const char *COM_SkipPath(const char *pathname);
|
||||
void COM_StripExtension(char *filename);
|
||||
void COM_StripExtension(const char *filename, char *out, size_t buflen);
|
||||
void COM_FileBase(const char *in, char *out, size_t buflen);
|
||||
void COM_DefaultExtension(char *path, const char *extension);
|
||||
int COM_DefaultExtension(const char *path, const char *extension,
|
||||
char *out, size_t buflen);
|
||||
int COM_CheckExtension(const char *path, const char *extn);
|
||||
|
||||
char *va(const char *format, ...) __attribute__((format(printf,1,2)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user