diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index c16faa565..0b2e0d4d6 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -2482,6 +2482,8 @@ Allow clients to change userinfo */ void CL_SetInfo_f (void) { + char *key, *val; + size_t keysize, valsize; cvar_t *var; int pnum = CL_TargettedSplit(true); if (Cmd_Argc() == 1) @@ -2524,7 +2526,17 @@ void CL_SetInfo_f (void) return; } - CL_SetInfo(pnum, Cmd_Argv(1), Cmd_Argv(2)); + key = Cmd_Argv(1); + val = Cmd_Argv(2); + + key = InfoBuf_DecodeString(key, key+strlen(key), &keysize); + val = InfoBuf_DecodeString(val, val+strlen(val), &valsize); + if (keysize != strlen(key)) + Con_Printf ("setinfo: ignoring key name with embedded null\n"); + else + CL_SetInfoBlob(pnum, key, val, valsize); + Z_Free(key); + Z_Free(val); } #if 1//def _DEBUG diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 55637b317..45e2da887 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -943,6 +943,8 @@ qboolean CL_CheckOrEnqueDownloadFile (const char *filename, const char *localnam if (cls.demorecording) { Con_TPrintf ("Unable to download %s in record mode.\n", filename); + if (sv_demoAutoRecord.ival) + Con_TPrintf ("Note that ^[%s\\cmd\\%s 0\\^] is enabled.\n", sv_demoAutoRecord.name, sv_demoAutoRecord.name); return true; } //ZOID - can't download when playback diff --git a/engine/client/client.h b/engine/client/client.h index be85f3f37..78fd869ad 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1463,8 +1463,8 @@ void CSQC_CvarChanged(cvar_t *var); #define CSQC_UnconnectedInit() false #define CSQC_UseGamecodeLoadingScreen() false #define CSQC_Parse_SetAngles(seat,newangles,wasdelta) false -#define CSQC_ServerInfoChanged() false -#define CSQC_PlayerInfoChanged(player) false +#define CSQC_ServerInfoChanged() +#define CSQC_PlayerInfoChanged(player) #endif // diff --git a/engine/client/image.c b/engine/client/image.c index c2f04d86c..6e267cae9 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -2710,7 +2710,7 @@ static qbyte *ReadICOFile(const char *fname, qbyte *buf, int length, int *width, size_t cc = img->wBitCount; size_t px = (img->bWidth?img->bWidth:256) * (img->bHeight?img->bHeight:256); if (!cc) //if that was omitted, try and guess it based on raw image size. this is an over estimate. - cc = 8 * (bestimg->dwSize_low | (bestimg->dwSize_high<<16)) / px; + cc = 8 * (img->dwSize_low | (img->dwSize_high<<16)) / px; if (!bestimg || cc > bestdepth || (cc == bestdepth && px > bestpixels)) { @@ -9031,6 +9031,7 @@ void Image_List_f(void) } if (tex->subpath) Con_Printf("^h(%s)^h", tex->subpath); + Con_DLPrintf(1, " %x", tex->flags); if (Image_LocateHighResTexture(tex, &loc, fname, sizeof(fname), &loadflags)) { diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 1f9872e97..0ee067205 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -232,8 +232,8 @@ void M_Menu_Options_f (void) extern cvar_t sv_demoAutoRecord; static const char *autorecordopts[] = { "Off", - "Singleview", - "Multiview", + "Clientside Only", + "Prefer Serverside", NULL }; static const char *autorecordvals[] = { diff --git a/engine/common/cmd.c b/engine/common/cmd.c index cf9e7d52d..d61ddf845 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -443,7 +443,7 @@ void Cbuf_ExecuteLevel (int level) { int i; char *text; - char line[65536]; + char linebuf[65536], *line; qboolean comment; int quotes; @@ -503,8 +503,10 @@ void Cbuf_ExecuteLevel (int level) break; // don't break if inside a quoted string } - if (i >= sizeof(line)) - i = sizeof(line)-1; + if (i >= sizeof(linebuf)) + line = malloc(i+1); //might leak if the command longjmps. :( + else + line = linebuf; memcpy (line, text, i); line[i] = 0; @@ -523,6 +525,8 @@ void Cbuf_ExecuteLevel (int level) // execute the command line Cmd_ExecuteString (line, level); + if (line != linebuf) + free(line); } } @@ -2682,7 +2686,7 @@ static void Cmd_ExecuteStringGlobalsAreEvil (const char *text, int level) cmd_function_t *cmd; cmdalias_t *a; - char dest[8192]; + char dest[65536]; Cmd_ExecLevel = level; while (*text == ' ' || *text == '\n') diff --git a/engine/common/common.c b/engine/common/common.c index ce7f5a47d..6986fc181 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -6734,6 +6734,13 @@ void InfoBuf_WriteToFile(vfsfile_t *f, infobuf_t *info, const char *commandname, continue; //this is saved via a cvar. } + //blobs over a certain size cannot safely be parsed (due to Cmd_ExecuteString and com_token having limits) + //so just don't write them. + //if someone forces a write then the blob will get truncated. + //note that blobs are limited im size serverside anyway, so this is probably higher than it needs to be. + if (info->keys[k].size > 48000) + continue; + key = InfoBuf_EncodeString_Malloc(key, strlen(key)); val = InfoBuf_EncodeString_Malloc(val, info->keys[k].size); if (!commandname) diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 8e293388e..85375b593 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -2303,20 +2303,20 @@ static void Shader_HLSL11ProgramName (parsestate_t *ps, char **ptr) static void Shader_ReflectCube(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, IF_CUBEMAP); ps->s->defaulttextures->reflectcube = Shader_FindImage(ps, token, flags); } static void Shader_ReflectMask(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, 0); ps->s->defaulttextures->reflectmask = Shader_FindImage(ps, token, flags); } static void Shader_DiffuseMap(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, 0); ps->s->defaulttextures->base = Shader_FindImage(ps, token, flags); @@ -2324,37 +2324,37 @@ static void Shader_DiffuseMap(parsestate_t *ps, char **ptr) } static void Shader_SpecularMap(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, 0); ps->s->defaulttextures->specular = Shader_FindImage(ps, token, flags); } static void Shader_NormalMap(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, IF_TRYBUMP|IF_NOSRGB); ps->s->defaulttextures->bump = Shader_FindImage(ps, token, flags); } static void Shader_FullbrightMap(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, 0); ps->s->defaulttextures->fullbright = Shader_FindImage(ps, token, flags); } static void Shader_UpperMap(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, 0); ps->s->defaulttextures->upperoverlay = Shader_FindImage(ps, token, flags); } static void Shader_LowerMap(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, 0); ps->s->defaulttextures->loweroverlay = Shader_FindImage(ps, token, flags); } static void Shader_DisplacementMap(parsestate_t *ps, char **ptr) { - char *token = Shader_ParseString(ptr); + char *token = Shader_ParseSensString(ptr); unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, IF_NOSRGB); ps->s->defaulttextures->displacement = Shader_FindImage(ps, token, flags); } @@ -2375,7 +2375,7 @@ static void Shaderpass_QF_Material(parsestate_t *ps, char **ptr) else ps->pass->prog = Shader_FindGeneric(progname, qrenderer); - token = Shader_ParseString(ptr); + token = Shader_ParseSensString(ptr); if (*token && strcmp(token, "-")) { flags = Shader_SetImageFlags (ps, ps->pass, &token, 0); @@ -2393,7 +2393,7 @@ static void Shaderpass_QF_Material(parsestate_t *ps, char **ptr) } if (*token) - token = Shader_ParseString(ptr); + token = Shader_ParseSensString(ptr); if (*token && strcmp(token, "-")) { flags = Shader_SetImageFlags (ps, NULL, &token, IF_TRYBUMP|IF_NOSRGB); @@ -2401,7 +2401,7 @@ static void Shaderpass_QF_Material(parsestate_t *ps, char **ptr) } if (*token) - token = Shader_ParseString(ptr); + token = Shader_ParseSensString(ptr); if (*token && strcmp(token, "-")) { flags = Shader_SetImageFlags (ps, NULL, &token, 0); @@ -2906,7 +2906,7 @@ static void Shaderpass_Map (parsestate_t *ps, char **ptr) pass->anim_frames[0] = r_nulltex; - token = Shader_ParseString (ptr); + token = Shader_ParseSensString (ptr); flags = Shader_SetImageFlags (ps, pass, &token, 0); if (!Shaderpass_MapGen(ps, pass, token)) @@ -3005,7 +3005,7 @@ static void Shaderpass_ClampMap (parsestate_t *ps, char **ptr) int flags; char *token; - token = Shader_ParseString (ptr); + token = Shader_ParseSensString (ptr); flags = Shader_SetImageFlags (ps, pass, &token, IF_CLAMP); if (!Shaderpass_MapGen(ps, pass, token)) diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 2496c7240..536802966 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -33,7 +33,7 @@ void SV_MVDStop_f (void); static void QDECL SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue); -cvar_t sv_demoAutoRecord = CVARAD("sv_demoAutoRecord", "0", "cl_autodemo", "If set, automatically record demos.\n-1: record on client connection.\n1+: record once there's this many active players on the server."); +cvar_t sv_demoAutoRecord = CVARAD("sv_demoAutoRecord", "0", "cl_autodemo", "If set, automatically record demos.\n-1: record on client connection only.\n1+: record once there's this many active players on the server (or if connected to a remote server)."); cvar_t sv_demoUseCache = CVARD("sv_demoUseCache", "", "If set, demo data will be flushed only periodically"); cvar_t sv_demoCacheSize = CVAR("sv_demoCacheSize", "0x80000"); //half a meg cvar_t sv_demoMaxDirSize = CVARD("sv_demoMaxDirSize", "100mb", "Maximum allowed serverside storage space for mvds. set to blank to remove the limit. New demos cannot be recorded once this size is reached."); //so ktpro autorecords. diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 64214d0c4..cbd1637d1 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -4505,7 +4505,7 @@ void SV_SetInfo_f (void) SV_ClientPrintf(host_client, PRINT_HIGH, "setinfo: %s may not be changed mid-game\n", key); else if (sv_userinfo_keylimit.ival >= 0 && host_client->userinfo.numkeys >= sv_userinfo_keylimit.ival && !offset && *val && !InfoBuf_FindKey(&host_client->userinfo, key, &k)) //when the limit is hit, allow people to freely change existing keys, but not new ones. they can also silently remove any that don't exist yet, too. SV_ClientPrintf(host_client, PRINT_MEDIUM, "setinfo: userinfo is limited to %i keys. Ignoring setting %s\n", sv_userinfo_keylimit.ival, key); - else if (valsize && sv_userinfo_bytelimit.ival >= 0 && host_client->userinfo.totalsize-cursize+(keysize+2+valsize) >= sv_userinfo_bytelimit.ival) + else if (offset+valsize > cursize && sv_userinfo_bytelimit.ival >= 0 && host_client->userinfo.totalsize+(keysize+2+valsize) >= sv_userinfo_bytelimit.ival) { SV_ClientPrintf(host_client, PRINT_MEDIUM, "setinfo: userinfo is limited to %i bytes. Ignoring setting %s\n", sv_userinfo_bytelimit.ival, key); if (offset) //kill it if they're part way through sending one, so that they're not penalised by the presence of partials that will never complete.