Set MAX_OSPATH to 4096 for !Windows + fixes for that

sounds easy, right?
Except some genius decided to save CVAR_LATCH cvars in buffers of
MAX_OSPATH length into savegames.. so just changing MAX_OSPATH
breaks savegame compatibility.
Fortunately, this assumption only matters in SV_WriteServerFile() and
SV_ReadServerFile() so I worked around it by introducing a
platform-specific LATCH_CVAR_SAVELENGTH (because MAX_OSPATH was 256 on
Windows but 128 on other systems..)
This commit is contained in:
Daniel Gibson 2015-05-23 01:50:21 +02:00
parent 41ea8879e7
commit d19cace026
4 changed files with 27 additions and 10 deletions

View file

@ -445,9 +445,11 @@ CL_CheckOrDownloadFile(char *filename)
char name[MAX_OSPATH];
char *ptr;
// FIXME: we should probably also forbid paths starting with '/' or '\\' or "C:\"
// (or any other drive name) because in the end FS_LoadFile() will fallback to fopen()!
if (strstr(filename, ".."))
{
Com_Printf("Refusing to download a path with ..\n");
Com_Printf("Refusing to download a path with ..: %s\n", filename);
return true;
}

View file

@ -221,7 +221,7 @@ typedef struct
/* > cls.disable_servercount, clear disable_screen */
/* connection information */
char servername[MAX_OSPATH]; /* name of server from original connect */
char servername[256]; /* name of server from original connect */
float connect_time; /* for connection retransmits */
int quakePort; /* a 16 bit value that allows quake servers */

View file

@ -64,10 +64,24 @@ typedef unsigned char byte;
#define MAX_QPATH 64 /* max length of a quake game pathname */
/*
* DG: For some stupid reason, SV_WriteServerFile() and SV_ReadeServerFile() used
* MAX_OSPATH as buffer length for CVAR_LATCH CVARS and saved the whole buffer
* into $game/save/current/server.ssv, so changing MAX_OSPATH breaks savegames...
* Unfortunately, for some other fucking reason MAX_OSPATH was 128 for non-Windows
* which is just horrible.. so I introduced LATCH_CVAR_SAVELENGTH with the stupid
* values so I could bump MAX_OSPATH.
* TODO: whenever you break savegame compatibility next, make
* LATCH_CVAR_SAVELENGTH system-independent (or remove it and hardcode a
* sensible value in the two functions)
*/
#ifdef _WIN32
#define MAX_OSPATH 256 /* max length of a filesystem pathname (same as MAX_PATH) */
#define LATCH_CVAR_SAVELENGTH 256
#else
#define MAX_OSPATH 128 /* max length of a filesystem pathname */
#define MAX_OSPATH 4096 /* max length of a filesystem pathname */
#define LATCH_CVAR_SAVELENGTH 128
#endif
/* per-level limits */

View file

@ -262,23 +262,23 @@ SV_WriteServerFile(qboolean autosave)
skill, deathmatch, etc */
for (var = cvar_vars; var; var = var->next)
{
char cvarname[LATCH_CVAR_SAVELENGTH] = {0};
if (!(var->flags & CVAR_LATCH))
{
continue;
}
if ((strlen(var->name) >= sizeof(name) - 1) ||
if ((strlen(var->name) >= sizeof(cvarname) - 1) ||
(strlen(var->string) >= sizeof(string) - 1))
{
Com_Printf("Cvar too long: %s = %s\n", var->name, var->string);
continue;
}
memset(name, 0, sizeof(name));
memset(string, 0, sizeof(string));
strcpy(name, var->name);
strcpy(cvarname, var->name);
strcpy(string, var->string);
fwrite(name, 1, sizeof(name), f);
fwrite(cvarname, 1, sizeof(cvarname), f);
fwrite(string, 1, sizeof(string), f);
}
@ -319,14 +319,15 @@ SV_ReadServerFile(void)
coop, skill, deathmatch, etc */
while (1)
{
if (!FS_FRead(name, 1, sizeof(name), f))
char cvarname[LATCH_CVAR_SAVELENGTH] = {0};
if (!FS_FRead(cvarname, 1, sizeof(cvarname), f))
{
break;
}
FS_Read(string, sizeof(string), f);
Com_DPrintf("Set %s = %s\n", name, string);
Cvar_ForceSet(name, string);
Com_DPrintf("Set %s = %s\n", cvarname, string);
Cvar_ForceSet(cvarname, string);
}
FS_FCloseFile(f);