From 26a665ff43052862131df3c63785f91861989fc8 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Tue, 19 Dec 2023 23:19:21 +1000 Subject: [PATCH] PRVM: optimise tempstring creation No need for strlen in PRVM_SetTempString(), usually we already have that information. Signed-off-by: bones_was_here --- cl_demo.c | 6 +- cl_parse.c | 38 +++++--- client.h | 1 + clvm_cmds.c | 51 ++++++----- cmd.c | 51 ++++++----- cmd.h | 10 +-- com_msg.c | 13 ++- common.c | 108 +++++++++++++--------- common.h | 17 ++-- console.c | 5 +- csprogs.c | 50 ++++++----- csprogs.h | 8 +- keys.c | 2 +- lhnet.c | 17 ++-- lhnet.h | 1 + menu.h | 2 +- mvm_cmds.c | 62 +++++++------ netconn.c | 83 ++++++++--------- netconn.h | 9 ++ progsvm.h | 3 +- prvm_cmds.c | 249 ++++++++++++++++++++++++++++++--------------------- prvm_cmds.h | 2 +- prvm_edict.c | 21 ++--- server.h | 2 +- sv_user.c | 10 ++- svvm_cmds.c | 13 +-- 26 files changed, 486 insertions(+), 348 deletions(-) diff --git a/cl_demo.c b/cl_demo.c index e67c1ab6..a11d63b5 100644 --- a/cl_demo.c +++ b/cl_demo.c @@ -348,6 +348,7 @@ void CL_Record_f(cmd_state_t *cmd) int c, track; char name[MAX_OSPATH]; char vabuf[1024]; + int vabuf_len; c = Cmd_Argc(cmd); if (c != 2 && c != 3 && c != 4) @@ -386,7 +387,10 @@ void CL_Record_f(cmd_state_t *cmd) // start the map up if (c > 2) - Cmd_ExecuteString ( cmd, va(vabuf, sizeof(vabuf), "map %s", Cmd_Argv(cmd, 2)), src_local, false); + { + vabuf_len = dpsnprintf(vabuf, sizeof(vabuf), "map %s", Cmd_Argv(cmd, 2)); + Cmd_ExecuteString(cmd, vabuf, vabuf_len, src_local, false); + } // open the demo file Con_Printf("recording to %s.\n", name); diff --git a/cl_parse.c b/cl_parse.c index f2ec8630..f02f63e1 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -3444,6 +3444,7 @@ void CL_ParseServerMessage(void) qbool qwplayerupdatereceived; qbool strip_pqc; char vabuf[1024]; + size_t cl_readstring_len; // LadyHavoc: moved demo message writing from before the packet parse to // after the packet parse so that CL_Stop_f can be called by cl_autodemo @@ -3550,22 +3551,28 @@ void CL_ParseServerMessage(void) case qw_svc_print: i = MSG_ReadByte(&cl_message); - temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)); + cl_readstring_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + temp = cl_readstring; if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports { if (i == 3) // chat - CSQC_AddPrintText(va(vabuf, sizeof(vabuf), "\1%s", temp)); //[515]: csqc + { + cl_readstring_len = dpsnprintf(vabuf, sizeof(vabuf), "\1%s", temp); + CSQC_AddPrintText(vabuf, cl_readstring_len); //[515]: csqc + } else - CSQC_AddPrintText(temp); + CSQC_AddPrintText(temp, cl_readstring_len); } break; case qw_svc_centerprint: - CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc + cl_readstring_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + CL_VM_Parse_CenterPrint(cl_readstring, cl_readstring_len); //[515]: csqc break; case qw_svc_stufftext: - CL_VM_Parse_StuffCmd(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc + cl_readstring_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + CL_VM_Parse_StuffCmd(cl_readstring, cl_readstring_len); //[515]: csqc break; case qw_svc_damage: @@ -3708,7 +3715,7 @@ void CL_ParseServerMessage(void) break; case qw_svc_sellscreen: - Cmd_ExecuteString(cmd_local, "help", src_local, true); + Cmd_ExecuteString(cmd_local, "help", 4, src_local, true); break; case qw_svc_smallkick: @@ -3920,17 +3927,20 @@ void CL_ParseServerMessage(void) break; case svc_print: - temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)); + cl_readstring_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + temp = cl_readstring; if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports - CSQC_AddPrintText(temp); //[515]: csqc + CSQC_AddPrintText(temp, cl_readstring_len); //[515]: csqc break; case svc_centerprint: - CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc + cl_readstring_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + CL_VM_Parse_CenterPrint(cl_readstring, cl_readstring_len); //[515]: csqc break; case svc_stufftext: - temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)); + cl_readstring_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + temp = cl_readstring; /* if(utf8_enable.integer) { strip_pqc = true; @@ -3961,11 +3971,15 @@ void CL_ParseServerMessage(void) if(*temp == 0x01) { ++temp; + --cl_readstring_len; while(*temp >= 0x01 && *temp <= 0x1F) + { ++temp; + --cl_readstring_len; + } } } - CL_VM_Parse_StuffCmd(temp); //[515]: csqc + CL_VM_Parse_StuffCmd(temp, cl_readstring_len); //[515]: csqc break; case svc_damage: @@ -4204,7 +4218,7 @@ void CL_ParseServerMessage(void) break; case svc_sellscreen: - Cmd_ExecuteString(cmd_local, "help", src_local, true); + Cmd_ExecuteString(cmd_local, "help", 4, src_local, true); break; case svc_hidelmp: if (gamemode == GAME_TENEBRAE) diff --git a/client.h b/client.h index 02ac81ff..bed78636 100644 --- a/client.h +++ b/client.h @@ -1118,6 +1118,7 @@ typedef struct client_state_s qbool csqc_usecsqclistener; matrix4x4_t csqc_listenermatrix; char csqc_printtextbuf[MAX_INPUTLINE]; + size_t csqc_printtextbuf_len; ///< strlen // collision culling data world_t world; diff --git a/clvm_cmds.c b/clvm_cmds.c index 7a12027f..78039744 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -2063,6 +2063,7 @@ static void VM_CL_getstats (prvm_prog_t *prog) { int i; char t[17]; + size_t t_len; VM_SAFEPARMCOUNT(1, VM_CL_getstats); i = (int)PRVM_G_FLOAT(OFS_PARM0); if(i < 0 || i > MAX_CL_STATS-4) @@ -2071,8 +2072,8 @@ static void VM_CL_getstats (prvm_prog_t *prog) VM_Warning(prog, "VM_CL_getstats: index>MAX_CL_STATS-4 or index<0\n"); return; } - dp_strlcpy(t, (char*)&cl.stats[i], sizeof(t)); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t); + t_len = dp_strlcpy(t, (char*)&cl.stats[i], sizeof(t)); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t, t_len); } //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC) @@ -2374,9 +2375,10 @@ static void VM_CL_runplayerphysics (prvm_prog_t *prog) //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC) static void VM_CL_getplayerkey (prvm_prog_t *prog) { - int i; - char t[128]; - const char *c; + int i; + char t[128]; + size_t t_len; + const char *c; VM_SAFEPARMCOUNT(2, VM_CL_getplayerkey); @@ -2393,37 +2395,37 @@ static void VM_CL_getplayerkey (prvm_prog_t *prog) t[0] = 0; if(!strcasecmp(c, "name")) - dp_strlcpy(t, cl.scores[i].name, sizeof(t)); + t_len = dp_strlcpy(t, cl.scores[i].name, sizeof(t)); else if(!strcasecmp(c, "frags")) - dpsnprintf(t, sizeof(t), "%i", cl.scores[i].frags); + t_len = dpsnprintf(t, sizeof(t), "%i", cl.scores[i].frags); else if(!strcasecmp(c, "ping")) - dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_ping); + t_len = dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_ping); else if(!strcasecmp(c, "pl")) - dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_packetloss); + t_len = dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_packetloss); else if(!strcasecmp(c, "movementloss")) - dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_movementloss); + t_len = dpsnprintf(t, sizeof(t), "%i", cl.scores[i].qw_movementloss); else if(!strcasecmp(c, "entertime")) - dpsnprintf(t, sizeof(t), "%f", cl.scores[i].qw_entertime); + t_len = dpsnprintf(t, sizeof(t), "%f", cl.scores[i].qw_entertime); else if(!strcasecmp(c, "colors")) - dpsnprintf(t, sizeof(t), "%i", cl.scores[i].colors); + t_len = dpsnprintf(t, sizeof(t), "%i", cl.scores[i].colors); else if(!strcasecmp(c, "topcolor")) - dpsnprintf(t, sizeof(t), "%i", cl.scores[i].colors & 0xf0); + t_len = dpsnprintf(t, sizeof(t), "%i", cl.scores[i].colors & 0xf0); else if(!strcasecmp(c, "bottomcolor")) - dpsnprintf(t, sizeof(t), "%i", (cl.scores[i].colors &15)<<4); + t_len = dpsnprintf(t, sizeof(t), "%i", (cl.scores[i].colors &15)<<4); else if(!strcasecmp(c, "viewentity")) - dpsnprintf(t, sizeof(t), "%i", i+1); + t_len = dpsnprintf(t, sizeof(t), "%i", i+1); if(!t[0]) return; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t, t_len); } //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC) @@ -2491,8 +2493,11 @@ static void VM_CL_ReadAngle (prvm_prog_t *prog) //#366 string() readstring (EXT_CSQC) static void VM_CL_ReadString (prvm_prog_t *prog) { + size_t cl_readstring_len; + VM_SAFEPARMCOUNT(0, VM_CL_ReadString); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); + cl_readstring_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cl_readstring, cl_readstring_len); } //#367 float() readfloat (EXT_CSQC) @@ -2507,6 +2512,7 @@ extern cvar_t cl_readpicture_force; static void VM_CL_ReadPicture (prvm_prog_t *prog) { const char *name; + size_t name_len; unsigned char *data; unsigned char *buf; unsigned short size; @@ -2515,7 +2521,8 @@ static void VM_CL_ReadPicture (prvm_prog_t *prog) VM_SAFEPARMCOUNT(0, VM_CL_ReadPicture); - name = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)); + name_len = MSG_ReadString_len(&cl_message, cl_readstring, sizeof(cl_readstring)); + name = cl_readstring; size = (unsigned short) MSG_ReadShort(&cl_message); // check if a texture of that name exists @@ -2546,7 +2553,7 @@ static void VM_CL_ReadPicture (prvm_prog_t *prog) } } - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, name); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, name, name_len); } ////////////////////////////////////////////////////////// @@ -3409,7 +3416,7 @@ static void VM_CL_gettaginfo (prvm_prog_t *prog) Matrix4x4_ToVectors(&tag_localmatrix, forward, left, up, origin); PRVM_clientglobalfloat(gettaginfo_parent) = parentindex; - PRVM_clientglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0; + PRVM_clientglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname, strlen(tagname)) : 0; VectorCopy(forward, PRVM_clientglobalvector(gettaginfo_forward)); VectorScale(left, -1, PRVM_clientglobalvector(gettaginfo_right)); VectorCopy(up, PRVM_clientglobalvector(gettaginfo_up)); @@ -4496,7 +4503,7 @@ static void VM_CL_serverkey(prvm_prog_t *prog) char string[VM_TEMPSTRING_MAXSIZE]; VM_SAFEPARMCOUNT(1, VM_CL_serverkey); InfoString_GetValue(cl.qw_serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string)); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string, strlen(string)); } /* @@ -4657,7 +4664,7 @@ static void VM_CL_skel_get_bonename(prvm_prog_t *prog) return; if (bonenum < 0 || bonenum >= skeleton->model->num_bones) return; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, skeleton->model->data_bones[bonenum].name); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, skeleton->model->data_bones[bonenum].name, strlen(skeleton->model->data_bones[bonenum].name)); } // #267 float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) returns parent num for supplied bonenum, 0 if bonenum has no parent or bone does not exist (returned value is always less than bonenum, you can loop on this) diff --git a/cmd.c b/cmd.c index 667b9009..0dfc093d 100644 --- a/cmd.c +++ b/cmd.c @@ -348,11 +348,12 @@ Cbuf_Execute ============ */ extern qbool prvm_runawaycheck; -static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *outtext, unsigned maxoutlen, cmd_alias_t *alias ); +static size_t Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *outtext, unsigned maxoutlen, cmd_alias_t *alias); void Cbuf_Execute (cmd_buf_t *cbuf) { cmd_input_t *current; char preprocessed[MAX_INPUTLINE]; + size_t preprocessed_len; char *firstchar; unsigned int i = 0; @@ -380,16 +381,16 @@ void Cbuf_Execute (cmd_buf_t *cbuf) firstchar = current->text; while(*firstchar && ISWHITESPACE(*firstchar)) ++firstchar; - if((strncmp(firstchar, "alias", 5) || !ISWHITESPACE(firstchar[5])) && - (strncmp(firstchar, "bind", 4) || !ISWHITESPACE(firstchar[4])) && - (strncmp(firstchar, "in_bind", 7) || !ISWHITESPACE(firstchar[7]))) + if((strncmp(firstchar, "alias", 5) || !ISWHITESPACE(firstchar[5])) + && (strncmp(firstchar, "bind", 4) || !ISWHITESPACE(firstchar[4])) + && (strncmp(firstchar, "in_bind", 7) || !ISWHITESPACE(firstchar[7]))) { - if(Cmd_PreprocessString(current->source, current->text, preprocessed, sizeof(preprocessed), NULL )) - Cmd_ExecuteString(current->source, preprocessed, src_local, false); + if((preprocessed_len = Cmd_PreprocessString(current->source, current->text, preprocessed, sizeof(preprocessed), NULL))) + Cmd_ExecuteString(current->source, preprocessed, preprocessed_len, src_local, false); } else { - Cmd_ExecuteString (current->source, current->text, src_local, false); + Cmd_ExecuteString(current->source, current->text, current->length, src_local, false); } // Recycle memory so using WASD doesn't cause a malloc and free @@ -1280,12 +1281,14 @@ static const char *Cmd_GetCvarValue(cmd_state_t *cmd, const char *var, size_t va return varstr; } -/* +/** Cmd_PreprocessString Preprocesses strings and replaces $*, $param#, $cvar accordingly. Also strips comments. +Returns the number of bytes written to *outtext excluding the \0 terminator. */ -static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *outtext, unsigned maxoutlen, cmd_alias_t *alias ) { +static size_t Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *outtext, unsigned maxoutlen, cmd_alias_t *alias) +{ const char *in; size_t eat, varlen; unsigned outlen; @@ -1293,7 +1296,7 @@ static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *ou // don't crash if there's no room in the outtext buffer if( maxoutlen == 0 ) { - return false; + return 0; } maxoutlen--; // because of \0 @@ -1366,7 +1369,7 @@ static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *ou { val = Cmd_GetCvarValue(cmd, in + 1, varlen, alias); if(!val) - return false; + return 0; eat = varlen + 2; } else @@ -1379,7 +1382,7 @@ static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *ou varlen = strspn(in, "#*0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"); val = Cmd_GetCvarValue(cmd, in, varlen, alias); if(!val) - return false; + return 0; eat = varlen; } if(val) @@ -1403,8 +1406,8 @@ static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *ou else outtext[outlen++] = *in++; } - outtext[outlen] = 0; - return true; + outtext[outlen] = '\0'; + return outlen; } /* @@ -2096,7 +2099,7 @@ extern cvar_t sv_cheats; * implement that behavior that doesn't involve an #ifdef, or * making a mess of hooks. */ -qbool Cmd_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src) +qbool Cmd_Callback(cmd_state_t *cmd, cmd_function_t *func) { if (func->function) func->function(cmd); @@ -2105,13 +2108,13 @@ qbool Cmd_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd return true; } -qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src) +qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, size_t textlen, cmd_source_t src) { // TODO: Assign these functions to QC commands directly? if(func->qcfunc) { - if(((func->flags & CF_CLIENT) && CL_VM_ConsoleCommand(text)) || - ((func->flags & CF_SERVER) && SV_VM_ConsoleCommand(text))) + if(((func->flags & CF_CLIENT) && CL_VM_ConsoleCommand(text, textlen)) || + ((func->flags & CF_SERVER) && SV_VM_ConsoleCommand(text, textlen))) return true; if (func->overridden) // If this QC command overrides an engine command, @@ -2130,13 +2133,13 @@ qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, return true; } } - return Cmd_Callback(cmd, func, text, src); + return Cmd_Callback(cmd, func); } -qbool Cmd_SV_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src) +qbool Cmd_SV_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, size_t textlen, cmd_source_t src) { if(func->qcfunc && (func->flags & CF_SERVER)) - return SV_VM_ConsoleCommand(text); + return SV_VM_ConsoleCommand(text, textlen); else if (src == src_client) { if((func->flags & CF_CHEAT) && !sv_cheats.integer) @@ -2156,7 +2159,7 @@ A complete command line has been parsed, so try to execute it FIXME: lookupnoadd the token to speed search? ============ */ -void Cmd_ExecuteString (cmd_state_t *cmd, const char *text, cmd_source_t src, qbool lockmutex) +void Cmd_ExecuteString(cmd_state_t *cmd, const char *text, size_t textlen, cmd_source_t src, qbool lockmutex) { int oldpos; cmd_function_t *func; @@ -2176,12 +2179,12 @@ void Cmd_ExecuteString (cmd_state_t *cmd, const char *text, cmd_source_t src, qb // check functions for (func = cmd->userdefined->qc_functions; func; func = func->next) if (!strcasecmp(cmd->argv[0], func->name)) - if(cmd->Handle(cmd, func, text, src)) + if(cmd->Handle(cmd, func, text, textlen, src)) goto functions_done; for (func = cmd->engine_functions; func; func=func->next) if (!strcasecmp (cmd->argv[0], func->name)) - if(cmd->Handle(cmd, func, text, src)) + if(cmd->Handle(cmd, func, text, textlen, src)) goto functions_done; functions_done: diff --git a/cmd.h b/cmd.h index 614aa0a0..cc912f31 100644 --- a/cmd.h +++ b/cmd.h @@ -143,13 +143,13 @@ typedef struct cmd_state_s unsigned cvars_flagsmask; // which CVAR_* flags should be visible to this interpreter? (CF_CLIENT | CF_SERVER, or just CF_SERVER) unsigned cmd_flagsmask; // cmd flags that identify this interpreter - qbool (*Handle)(struct cmd_state_s *, struct cmd_function_s *, const char *, enum cmd_source_s); + qbool (*Handle)(struct cmd_state_s *, struct cmd_function_s *, const char *, size_t, enum cmd_source_s); } cmd_state_t; -qbool Cmd_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src); -qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src); -qbool Cmd_SV_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src); +qbool Cmd_Callback(cmd_state_t *cmd, cmd_function_t *func); +qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, size_t textlen, cmd_source_t src); +qbool Cmd_SV_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, size_t textlen, cmd_source_t src); typedef struct cmd_input_s { @@ -267,7 +267,7 @@ int Cmd_CheckParm (cmd_state_t *cmd, const char *parm); /// Parses a single line of text into arguments and tries to execute it. /// The text can come from the command buffer, a remote client, or stdin. -void Cmd_ExecuteString (cmd_state_t *cmd, const char *text, cmd_source_t src, qbool lockmutex); +void Cmd_ExecuteString(cmd_state_t *cmd, const char *text, size_t textlen, cmd_source_t src, qbool lockmutex); /// quotes a string so that it can be used as a command argument again; /// quoteset is a string that contains one or more of ", \, $ and specifies diff --git a/com_msg.c b/com_msg.c index 80503b62..fe29579e 100644 --- a/com_msg.c +++ b/com_msg.c @@ -346,9 +346,20 @@ char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring) while ((c = MSG_ReadByte(sb)) > 0) if (l < maxstring - 1) string[l++] = c; - string[l] = 0; + string[l] = '\0'; return string; } +size_t MSG_ReadString_len (sizebuf_t *sb, char *string, size_t maxstring) +{ + int c; + size_t l = 0; + // read string into sbfer, but only store as many characters as will fit + while ((c = MSG_ReadByte(sb)) > 0) + if (l < maxstring - 1) + string[l++] = c; + string[l] = '\0'; + return l; +} int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out) { diff --git a/common.c b/common.c index 05bbd7c6..0f0572d3 100644 --- a/common.c +++ b/common.c @@ -37,6 +37,7 @@ cvar_t cl_playermodel = {CF_CLIENT | CF_SERVER | CF_USERINFO | CF_ARCHIVE, "play cvar_t cl_playerskin = {CF_CLIENT | CF_SERVER | CF_USERINFO | CF_ARCHIVE, "playerskin", "", "current player skin in Nexuiz/Xonotic"}; char com_token[MAX_INPUTLINE]; +unsigned com_token_len; //=========================================================================== @@ -456,6 +457,7 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo COM_ParseToken_Simple Parse a token out of a string +Writes the token and its strlen to the com_token and com_token_len globals. ============== */ int COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments) @@ -464,8 +466,8 @@ int COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool p int c; const char *data = *datapointer; - len = 0; - com_token[0] = 0; + com_token_len = len = 0; + com_token[0] = '\0'; if (!data) { @@ -530,7 +532,8 @@ skipwhite: if (len < (int)sizeof(com_token) - 1) com_token[len++] = c; } - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; if (*data == '\"') data++; *datapointer = data; @@ -540,7 +543,8 @@ skipwhite: { // translate Mac line ending to UNIX com_token[len++] = '\n';data++; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -548,7 +552,8 @@ skipwhite: { // single character com_token[len++] = *data++; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -558,7 +563,8 @@ skipwhite: for (;!ISWHITESPACE(*data);data++) if (len < (int)sizeof(com_token) - 1) com_token[len++] = *data; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -569,6 +575,7 @@ skipwhite: COM_ParseToken_QuakeC Parse a token out of a string +Writes the token and its strlen to the com_token and com_token_len globals. ============== */ int COM_ParseToken_QuakeC(const char **datapointer, qbool returnnewline) @@ -577,8 +584,8 @@ int COM_ParseToken_QuakeC(const char **datapointer, qbool returnnewline) int c; const char *data = *datapointer; - len = 0; - com_token[0] = 0; + com_token_len = len = 0; + com_token[0] = '\0'; if (!data) { @@ -644,7 +651,8 @@ skipwhite: if (len < (int)sizeof(com_token) - 1) com_token[len++] = c; } - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; if (*data == quote) data++; *datapointer = data; @@ -654,7 +662,8 @@ skipwhite: { // translate Mac line ending to UNIX com_token[len++] = '\n';data++; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -662,7 +671,8 @@ skipwhite: { // single character com_token[len++] = *data++; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -672,7 +682,8 @@ skipwhite: for (;!ISWHITESPACE(*data) && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != ':' && *data != ',' && *data != ';';data++) if (len < (int)sizeof(com_token) - 1) com_token[len++] = *data; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -683,6 +694,7 @@ skipwhite: COM_ParseToken_VM_Tokenize Parse a token out of a string +Writes the token and its strlen to the com_token and com_token_len globals. ============== */ int COM_ParseToken_VM_Tokenize(const char **datapointer, qbool returnnewline) @@ -691,8 +703,8 @@ int COM_ParseToken_VM_Tokenize(const char **datapointer, qbool returnnewline) int c; const char *data = *datapointer; - len = 0; - com_token[0] = 0; + com_token_len = len = 0; + com_token[0] = '\0'; if (!data) { @@ -758,7 +770,8 @@ skipwhite: if (len < (int)sizeof(com_token) - 1) com_token[len++] = c; } - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; if (*data == quote) data++; *datapointer = data; @@ -768,7 +781,8 @@ skipwhite: { // translate Mac line ending to UNIX com_token[len++] = '\n';data++; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -776,7 +790,8 @@ skipwhite: { // single character com_token[len++] = *data++; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -786,7 +801,8 @@ skipwhite: for (;!ISWHITESPACE(*data) && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != ':' && *data != ',' && *data != ';';data++) if (len < (int)sizeof(com_token) - 1) com_token[len++] = *data; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; return true; } @@ -797,6 +813,7 @@ skipwhite: COM_ParseToken_Console Parse a token out of a string, behaving like the qwcl console +Writes the token and its strlen to the com_token and com_token_len globals. ============== */ int COM_ParseToken_Console(const char **datapointer) @@ -804,8 +821,8 @@ int COM_ParseToken_Console(const char **datapointer) int len; const char *data = *datapointer; - len = 0; - com_token[0] = 0; + com_token_len = len = 0; + com_token[0] = '\0'; if (!data) { @@ -843,7 +860,8 @@ skipwhite: if (len < (int)sizeof(com_token) - 1) com_token[len++] = *data; } - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; if (*data == '\"') data++; *datapointer = data; @@ -854,7 +872,8 @@ skipwhite: for (;!ISWHITESPACE(*data);data++) if (len < (int)sizeof(com_token) - 1) com_token[len++] = *data; - com_token[len] = 0; + com_token[len] = '\0'; + com_token_len = len; *datapointer = data; } @@ -1014,10 +1033,12 @@ int dpvsnprintf (char *buffer, size_t buffersize, const char *format, va_list ar //====================================== -void COM_ToLowerString (const char *in, char *out, size_t size_out) +size_t COM_ToLowerString(const char *in, char *out, size_t size_out) { + const char *out_start = out; + if (size_out == 0) - return; + return 0; if(utf8_enable.integer) { @@ -1028,12 +1049,12 @@ void COM_ToLowerString (const char *in, char *out, size_t size_out) Uchar ch = u8_getchar_utf8_enabled(in, &in); ch = u8_tolower(ch); n = u8_fromchar(ch, out, size_out); + out += n; // before the break so the return is correct if(n <= 0) break; - out += n; size_out -= n; } - return; + return out - out_start; } while (*in && size_out > 1) @@ -1045,12 +1066,15 @@ void COM_ToLowerString (const char *in, char *out, size_t size_out) size_out--; } *out = '\0'; + return out - out_start; } -void COM_ToUpperString (const char *in, char *out, size_t size_out) +size_t COM_ToUpperString(const char *in, char *out, size_t size_out) { + const char *out_start = out; + if (size_out == 0) - return; + return 0; if(utf8_enable.integer) { @@ -1061,12 +1085,12 @@ void COM_ToUpperString (const char *in, char *out, size_t size_out) Uchar ch = u8_getchar_utf8_enabled(in, &in); ch = u8_toupper(ch); n = u8_fromchar(ch, out, size_out); + out += n; // before the break so the return is correct if(n <= 0) break; - out += n; size_out -= n; } - return; + return out - out_start; } while (*in && size_out > 1) @@ -1078,6 +1102,7 @@ void COM_ToUpperString (const char *in, char *out, size_t size_out) size_out--; } *out = '\0'; + return out - out_start; } int COM_StringBeginsWith(const char *s, const char *match) @@ -1231,9 +1256,10 @@ removes color codes from a string. If escape_carets is true, the resulting string will be safe for printing. If escape_carets is false, the function will just strip color codes (for logging for example). +Returns the number of bytes written to the *out buffer excluding the \0 terminator. -If the output buffer size did not suffice for converting, the function returns -FALSE. Generally, if escape_carets is false, the output buffer needs +If the output buffer size did not suffice for converting, the function returns 0. +Generally, if escape_carets is false, the output buffer needs strlen(str)+1 bytes, and if escape_carets is true, it can need strlen(str)*1.5+2 bytes. In any case, the function makes sure that the resulting string is zero terminated. @@ -1242,20 +1268,22 @@ For size_in, specify the maximum number of characters from in to use, or 0 to us all characters until the zero terminator. ============ */ -qbool -COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qbool escape_carets) +size_t COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qbool escape_carets) { -#define APPEND(ch) do { if(--size_out) { *out++ = (ch); } else { *out++ = 0; return false; } } while(0) +#define APPEND(ch) do { if(--size_out) { *out++ = (ch); } else { *out++ = 0; return 0; } } while(0) + + const char *out_start = out; const char *end = size_in ? (in + size_in) : NULL; + if(size_out < 1) - return false; + return 0; for(;;) { switch((in == end) ? 0 : *in) { case 0: - *out++ = 0; - return true; + *out = '\0'; + return out - out_start; case STRING_COLOR_TAG: ++in; switch((in == end) ? 0 : *in) @@ -1278,8 +1306,8 @@ COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, // finish the code by appending another caret when escaping if(escape_carets) APPEND(STRING_COLOR_TAG); - *out++ = 0; - return true; + *out = '\0'; + return out - out_start; case STRING_COLOR_TAG: // escaped ^ APPEND(STRING_COLOR_TAG); // append a ^ twice when escaping diff --git a/common.h b/common.h index ff088a79..e85f43eb 100644 --- a/common.h +++ b/common.h @@ -180,6 +180,8 @@ int MSG_ReadBigLong (sizebuf_t *sb); float MSG_ReadLittleFloat (sizebuf_t *sb); float MSG_ReadBigFloat (sizebuf_t *sb); char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring); +/// Same as MSG_ReadString except it returns the number of bytes written to *string excluding the \0 terminator. +size_t MSG_ReadString_len (sizebuf_t *sb, char *string, size_t maxstring); int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out); #define MSG_ReadChar(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, -1) : (signed char)(sb)->data[(sb)->readcount++]) @@ -205,7 +207,7 @@ typedef int (*COM_LineProcessorFunc) (void *passthrough, const char *line, size_ int COM_Wordwrap(const char *string, size_t length, float continuationSize, float maxWidth, COM_WordWidthFunc_t wordWidth, void *passthroughCW, COM_LineProcessorFunc processLine, void *passthroughPL); extern char com_token[MAX_INPUTLINE]; - +extern unsigned com_token_len; int COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments); int COM_ParseToken_QuakeC(const char **datapointer, qbool returnnewline); int COM_ParseToken_VM_Tokenize(const char **datapointer, qbool returnnewline); @@ -277,16 +279,15 @@ typedef enum userdirmode_e } userdirmode_t; -void COM_ToLowerString (const char *in, char *out, size_t size_out); -void COM_ToUpperString (const char *in, char *out, size_t size_out); +/// Returns the number of bytes written to *out excluding the \0 terminator. +size_t COM_ToLowerString(const char *in, char *out, size_t size_out); +/// Returns the number of bytes written to *out excluding the \0 terminator. +size_t COM_ToUpperString(const char *in, char *out, size_t size_out); int COM_StringBeginsWith(const char *s, const char *match); - int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *tokenbuf, int tokenbufsize, const char *commentprefix); - size_t COM_StringLengthNoColors(const char *s, size_t size_s, qbool *valid); -qbool COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qbool escape_carets); -void COM_ToLowerString (const char *in, char *out, size_t size_out); -void COM_ToUpperString (const char *in, char *out, size_t size_out); +size_t COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qbool escape_carets); + #define dp_strlcpy(dst, src, dsize) dp__strlcpy(dst, src, dsize, __func__, __LINE__) diff --git a/console.c b/console.c index eefcb25e..99414a21 100644 --- a/console.c +++ b/console.c @@ -719,8 +719,9 @@ static void Con_MsgCmdMode(cmd_state_t *cmd, signed char mode) chat_mode = mode; if(Cmd_Argc(cmd) > 1) { - dpsnprintf(chat_buffer, sizeof(chat_buffer), "%s ", Cmd_Args(cmd)); - chat_bufferpos = (unsigned int)strlen(chat_buffer); + chat_bufferpos = dpsnprintf(chat_buffer, sizeof(chat_buffer), "%s ", Cmd_Args(cmd)); + if (chat_bufferpos < 0) + chat_bufferpos = 0; } } diff --git a/csprogs.c b/csprogs.c index f7e6fd00..c060ee14 100644 --- a/csprogs.c +++ b/csprogs.c @@ -529,10 +529,10 @@ qbool CL_VM_UpdateView (double frametime) return true; } -qbool CL_VM_ConsoleCommand (const char *text) +qbool CL_VM_ConsoleCommand(const char *text, size_t textlen) { prvm_prog_t *prog = CLVM_prog; - return PRVM_ConsoleCommand(prog, text, &prog->funcoffsets.CSQC_ConsoleCommand, false, cl.csqc_server2csqcentitynumber[cl.playerentity], cl.time, cl.csqc_loaded, "QC function CSQC_ConsoleCommand is missing"); + return PRVM_ConsoleCommand(prog, text, textlen, &prog->funcoffsets.CSQC_ConsoleCommand, false, cl.csqc_server2csqcentitynumber[cl.playerentity], cl.time, cl.csqc_loaded, "QC function CSQC_ConsoleCommand is missing"); } qbool CL_VM_Parse_TempEntity (void) @@ -560,7 +560,7 @@ qbool CL_VM_Parse_TempEntity (void) return r; } -void CL_VM_Parse_StuffCmd (const char *msg) +void CL_VM_Parse_StuffCmd(const char *msg, size_t msg_len) { prvm_prog_t *prog = CLVM_prog; int restorevm_tempstringsbuf_cursize; @@ -575,7 +575,7 @@ void CL_VM_Parse_StuffCmd (const char *msg) int crcflags = csqc_progcrc.flags; csqc_progcrc.flags &= ~CF_READONLY; csqc_progsize.flags &= ~CF_READONLY; - Cmd_ExecuteString(cmd_local, msg, src_local, true); + Cmd_ExecuteString(cmd_local, msg, msg_len, src_local, true); csqc_progcrc.flags = csqc_progsize.flags = crcflags; return; } @@ -591,7 +591,7 @@ void CL_VM_Parse_StuffCmd (const char *msg) PRVM_clientglobalfloat(time) = cl.time; PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; - PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg, msg_len); prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Parse_StuffCmd), "QC function CSQC_Parse_StuffCmd is missing"); prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } @@ -600,48 +600,54 @@ void CL_VM_Parse_StuffCmd (const char *msg) CSQC_END } -static void CL_VM_Parse_Print (const char *msg) +static void CL_VM_Parse_Print(const char *msg, size_t msg_len) { prvm_prog_t *prog = CLVM_prog; int restorevm_tempstringsbuf_cursize; PRVM_clientglobalfloat(time) = cl.time; PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; - PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg, msg_len); prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Parse_Print), "QC function CSQC_Parse_Print is missing"); prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } -void CSQC_AddPrintText (const char *msg) +void CSQC_AddPrintText(const char *msg, size_t msg_len) { prvm_prog_t *prog = CLVM_prog; - size_t i; + char *start = cl.csqc_printtextbuf + cl.csqc_printtextbuf_len; + size_t writebytes = min(msg_len + 1, MAX_INPUTLINE - cl.csqc_printtextbuf_len); + CSQC_BEGIN if(cl.csqc_loaded && PRVM_clientfunction(CSQC_Parse_Print)) { - // FIXME: is this bugged? - i = strlen(msg)-1; - if(msg[i] != '\n' && msg[i] != '\r') + if(msg[msg_len - 1] != '\n' && msg[msg_len - 1] != '\r') { - if(strlen(cl.csqc_printtextbuf)+i >= MAX_INPUTLINE) + if(cl.csqc_printtextbuf_len + msg_len + 1 >= MAX_INPUTLINE) { - CL_VM_Parse_Print(cl.csqc_printtextbuf); - cl.csqc_printtextbuf[0] = 0; + CL_VM_Parse_Print(cl.csqc_printtextbuf, cl.csqc_printtextbuf_len); + cl.csqc_printtextbuf[0] = '\0'; + cl.csqc_printtextbuf_len = 0; } else - dp_strlcat(cl.csqc_printtextbuf, msg, MAX_INPUTLINE); + { + memcpy(start, msg, writebytes); + cl.csqc_printtextbuf_len += msg_len; + } return; } - dp_strlcat(cl.csqc_printtextbuf, msg, MAX_INPUTLINE); - CL_VM_Parse_Print(cl.csqc_printtextbuf); - cl.csqc_printtextbuf[0] = 0; + memcpy(start, msg, writebytes); + cl.csqc_printtextbuf_len += msg_len; + CL_VM_Parse_Print(cl.csqc_printtextbuf, cl.csqc_printtextbuf_len); + cl.csqc_printtextbuf[0] = '\0'; + cl.csqc_printtextbuf_len = 0; } else Con_Print(msg); CSQC_END } -void CL_VM_Parse_CenterPrint (const char *msg) +void CL_VM_Parse_CenterPrint(const char *msg, size_t msg_len) { prvm_prog_t *prog = CLVM_prog; int restorevm_tempstringsbuf_cursize; @@ -651,7 +657,7 @@ void CL_VM_Parse_CenterPrint (const char *msg) PRVM_clientglobalfloat(time) = cl.time; PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; - PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg, msg_len); prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Parse_CenterPrint), "QC function CSQC_Parse_CenterPrint is missing"); prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } @@ -693,7 +699,7 @@ qbool CL_VM_Event_Sound(int sound_num, float fvolume, int channel, float attenua PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity]; PRVM_G_FLOAT(OFS_PARM0) = ent; PRVM_G_FLOAT(OFS_PARM1) = CHAN_ENGINE2USER(channel); - PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(prog, cl.sound_name[sound_num] ); + PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(prog, cl.sound_name[sound_num], strlen(cl.sound_name[sound_num])); PRVM_G_FLOAT(OFS_PARM3) = fvolume; PRVM_G_FLOAT(OFS_PARM4) = attenuation; VectorCopy(pos, PRVM_G_VECTOR(OFS_PARM5) ); diff --git a/csprogs.h b/csprogs.h index 4760a7f3..1900f91c 100644 --- a/csprogs.h +++ b/csprogs.h @@ -111,20 +111,20 @@ void CL_VM_ShutDown(void); void CL_VM_UpdateIntermissionState(int intermission); void CL_VM_UpdateShowingScoresState(int showingscores); qbool CL_VM_InputEvent(int eventtype, float x, float y); -qbool CL_VM_ConsoleCommand(const char *text); +qbool CL_VM_ConsoleCommand(const char *text, size_t textlen); void CL_VM_UpdateDmgGlobals(int dmg_take, int dmg_save, vec3_t dmg_origin); void CL_VM_UpdateIntermissionState(int intermission); qbool CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos, int flags, float speed); qbool CL_VM_Parse_TempEntity(void); -void CL_VM_Parse_StuffCmd(const char *msg); -void CL_VM_Parse_CenterPrint(const char *msg); +void CL_VM_Parse_StuffCmd(const char *msg, size_t msg_len); +void CL_VM_Parse_CenterPrint(const char *msg, size_t msg_len); int CL_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent); int CL_GetTagMatrix(prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex, prvm_vec_t *shadingorigin); void CL_GetEntityMatrix(prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qbool viewmatrix); void QW_CL_StartUpload(unsigned char *data, int size); void CSQC_UpdateNetworkTimes(double newtime, double oldtime); -void CSQC_AddPrintText(const char *msg); +void CSQC_AddPrintText(const char *msg, size_t msg_len); void CSQC_ReadEntities(void); void CSQC_RelinkAllEntities(int drawmask); void CSQC_RelinkCSQCEntities(void); diff --git a/keys.c b/keys.c index 739d26bb..a3a6d926 100644 --- a/keys.c +++ b/keys.c @@ -1308,7 +1308,7 @@ Key_Message (cmd_state_t *cmd, int key, int ascii) if (key == K_ENTER || key == K_KP_ENTER || ascii == 10 || ascii == 13) { if(chat_mode < 0) - Cmd_ExecuteString(cmd, chat_buffer, src_local, true); // not Cbuf_AddText to allow semiclons in args; however, this allows no variables then. Use aliases! + Cmd_ExecuteString(cmd, chat_buffer, strlen(chat_buffer), src_local, true); // not Cbuf_AddText to allow semiclons in args; however, this allows no variables then. Use aliases! else CL_ForwardToServer(va(vabuf, sizeof(vabuf), "%s %s", chat_mode ? "say_team" : "say ", chat_buffer)); diff --git a/lhnet.c b/lhnet.c index 05fd9802..e6a688de 100644 --- a/lhnet.c +++ b/lhnet.c @@ -553,8 +553,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stri { if (stringbuffersize >= 12) { - dpsnprintf(string, stringbuffersize, "local:%d", address->port); - return 1; + return dpsnprintf(string, stringbuffersize, "local:%d", address->port); } } else @@ -562,7 +561,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stri if (stringbuffersize >= 6) { memcpy(string, "local", 6); - return 1; + return 5; } } break; @@ -572,16 +571,14 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stri { if (stringbuffersize >= 22) { - dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d:%d", a[0], a[1], a[2], a[3], address->port); - return 1; + return dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d:%d", a[0], a[1], a[2], a[3], address->port); } } else { if (stringbuffersize >= 16) { - dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); - return 1; + return dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); } } break; @@ -592,16 +589,14 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stri { if (stringbuffersize >= 88) { - dpsnprintf(string, stringbuffersize, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15], address->port); - return 1; + return dpsnprintf(string, stringbuffersize, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15], address->port); } } else { if (stringbuffersize >= 80) { - dpsnprintf(string, stringbuffersize, "%x:%x:%x:%x:%x:%x:%x:%x", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15]); - return 1; + return dpsnprintf(string, stringbuffersize, "%x:%x:%x:%x:%x:%x:%x:%x", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15]); } } break; diff --git a/lhnet.h b/lhnet.h index e7ac0e48..d368940d 100644 --- a/lhnet.h +++ b/lhnet.h @@ -26,6 +26,7 @@ lhnetaddress_t; int LHNETADDRESS_FromPort(lhnetaddress_t *address, lhnetaddresstype_t addresstype, int port); int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int defaultport); +/// Returns the number of bytes written to *string excluding the \0 terminator. int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int stringbuffersize, int includeport); static inline lhnetaddresstype_t LHNETADDRESS_GetAddressType(const lhnetaddress_t *address) { diff --git a/menu.h b/menu.h index 6dd0b37c..2344f444 100644 --- a/menu.h +++ b/menu.h @@ -71,7 +71,7 @@ void MP_Draw (void); void MP_ToggleMenu (int mode); void MP_Shutdown (void);*/ -qbool MP_ConsoleCommand(const char *text); +qbool MP_ConsoleCommand(const char *text, size_t textlen); // // menu router diff --git a/mvm_cmds.c b/mvm_cmds.c index 218b0c8d..ba785d59 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -53,10 +53,10 @@ const char *vm_m_extensions[] = { NULL }; -qbool MP_ConsoleCommand(const char *text) +qbool MP_ConsoleCommand(const char *text, size_t textlen) { prvm_prog_t *prog = MVM_prog; - return PRVM_ConsoleCommand(prog, text, &prog->funcoffsets.GameCommand, false, -1, 0, prog->loaded, "QC function GameCommand is missing"); + return PRVM_ConsoleCommand(prog, text, textlen, &prog->funcoffsets.GameCommand, false, -1, 0, prog->loaded, "QC function GameCommand is missing"); } /* @@ -220,9 +220,9 @@ static void VM_M_getgamedirinfo(prvm_prog_t *prog) if(nr >= 0 && nr < fs_all_gamedirs_count) { if(item == 0) - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, fs_all_gamedirs[nr].name ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, fs_all_gamedirs[nr].name, strlen(fs_all_gamedirs[nr].name)); else if(item == 1) - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, fs_all_gamedirs[nr].description ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, fs_all_gamedirs[nr].description, strlen(fs_all_gamedirs[nr].description)); } } @@ -331,25 +331,25 @@ static void VM_M_setserverlistmaskstring(prvm_prog_t *prog) switch( field ) { case SLIF_CNAME: - dp_strlcpy( mask->info.cname, str, sizeof(mask->info.cname) ); + mask->info.cname_len = dp_strlcpy(mask->info.cname, str, sizeof(mask->info.cname)); break; case SLIF_NAME: - dp_strlcpy( mask->info.name, str, sizeof(mask->info.name) ); + mask->info.name_len = dp_strlcpy(mask->info.name, str, sizeof(mask->info.name)); break; case SLIF_QCSTATUS: - dp_strlcpy( mask->info.qcstatus, str, sizeof(mask->info.qcstatus) ); + mask->info.qcstatus_len = dp_strlcpy(mask->info.qcstatus, str, sizeof(mask->info.qcstatus)); break; case SLIF_PLAYERS: - dp_strlcpy( mask->info.players, str, sizeof(mask->info.players) ); + mask->info.players_len = dp_strlcpy(mask->info.players, str, sizeof(mask->info.players)); break; case SLIF_MAP: - dp_strlcpy( mask->info.map, str, sizeof(mask->info.map) ); + mask->info.map_len = dp_strlcpy(mask->info.map, str, sizeof(mask->info.map)); break; case SLIF_MOD: - dp_strlcpy( mask->info.mod, str, sizeof(mask->info.mod) ); + mask->info.mod_len = dp_strlcpy(mask->info.mod, str, sizeof(mask->info.mod)); break; case SLIF_GAME: - dp_strlcpy( mask->info.game, str, sizeof(mask->info.game) ); + mask->info.game_len = dp_strlcpy(mask->info.game, str, sizeof(mask->info.game)); break; default: VM_Warning(prog, "VM_M_setserverlistmaskstring: Bad field number %i passed!\n", field ); @@ -476,32 +476,32 @@ static void VM_M_getserverliststring(prvm_prog_t *prog) } switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) { case SLIF_CNAME: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.cname ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.cname, cache->info.cname_len); break; case SLIF_NAME: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.name ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.name, cache->info.name_len); break; case SLIF_QCSTATUS: - PRVM_G_INT (OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.qcstatus ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.qcstatus, cache->info.qcstatus_len); break; case SLIF_PLAYERS: - PRVM_G_INT (OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.players ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.players, cache->info.players_len); break; case SLIF_GAME: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.game ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.game, cache->info.game_len); break; case SLIF_MOD: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.mod ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.mod, cache->info.mod_len); break; case SLIF_MAP: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.map ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->info.map, cache->info.map_len); break; // TODO remove this again case 1024: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->line1 ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->line1, cache->line1_len); break; case 1025: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->line2 ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cache->line2, cache->line2_len); break; default: Con_Print("VM_M_getserverliststring: bad field number passed!\n"); @@ -810,7 +810,7 @@ static void VM_M_crypto_getkeyfp(prvm_prog_t *prog) VM_CheckEmptyString( prog, s ); if(LHNETADDRESS_FromString(&addr, s, 26000) && Crypto_RetrieveHostKey(&addr, NULL, keyfp, sizeof(keyfp), NULL, 0, NULL, NULL)) - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, keyfp ); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, keyfp, strlen(keyfp)); else PRVM_G_INT( OFS_RETURN ) = OFS_NULL; } @@ -826,7 +826,7 @@ static void VM_M_crypto_getidfp(prvm_prog_t *prog) VM_CheckEmptyString( prog, s ); if(LHNETADDRESS_FromString(&addr, s, 26000) && Crypto_RetrieveHostKey(&addr, NULL, NULL, 0, idfp, sizeof(idfp), NULL, NULL)) - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, idfp ); + PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, idfp, strlen(idfp)); else PRVM_G_INT( OFS_RETURN ) = OFS_NULL; } @@ -859,7 +859,15 @@ static void VM_M_crypto_getencryptlevel(prvm_prog_t *prog) VM_CheckEmptyString( prog, s ); if(LHNETADDRESS_FromString(&addr, s, 26000) && Crypto_RetrieveHostKey(&addr, NULL, NULL, 0, NULL, 0, &aeslevel, NULL)) - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, aeslevel ? va(vabuf, sizeof(vabuf), "%d AES128", aeslevel) : "0"); + { + if (aeslevel) + { + size_t vabuf_len = dpsnprintf(vabuf, sizeof(vabuf), "%d AES128", aeslevel); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, vabuf, vabuf_len); + } + else + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "0", 1); + } else PRVM_G_INT( OFS_RETURN ) = OFS_NULL; } @@ -874,14 +882,14 @@ static void VM_M_crypto_getmykeyfp(prvm_prog_t *prog) switch(Crypto_RetrieveLocalKey(i, keyfp, sizeof(keyfp), NULL, 0, NULL)) { case -1: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, ""); + PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, "", 0); break; case 0: PRVM_G_INT( OFS_RETURN ) = OFS_NULL; break; default: case 1: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, keyfp); + PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, keyfp, strlen(keyfp)); break; } } @@ -896,14 +904,14 @@ static void VM_M_crypto_getmyidfp(prvm_prog_t *prog) switch(Crypto_RetrieveLocalKey(i, NULL, 0, idfp, sizeof(idfp), NULL)) { case -1: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, ""); + PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, "", 0); break; case 0: PRVM_G_INT( OFS_RETURN ) = OFS_NULL; break; default: case 1: - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, idfp); + PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, idfp, strlen(idfp)); break; } } diff --git a/netconn.c b/netconn.c index c1e8bb96..c21e1484 100644 --- a/netconn.c +++ b/netconn.c @@ -1725,7 +1725,7 @@ static int NetConn_ClientParsePacket_ServerList_ProcessReply(const char *address entry = &serverlist_cache[n]; memset(entry, 0, sizeof(*entry)); - dp_strlcpy(entry->info.cname, addressstring, sizeof(entry->info.cname)); + entry->info.cname_len = dp_strlcpy(entry->info.cname, addressstring, sizeof(entry->info.cname)); // use the broadcast as the first query, NetConn_QueryQueueFrame() will send more entry->querytime = masterquerytime; @@ -1785,14 +1785,14 @@ static void NetConn_ClientParsePacket_ServerList_UpdateCache(int n) serverlist_info_t *info = &entry->info; // update description strings for engine menu and console output - dpsnprintf(entry->line1, sizeof(serverlist_cache[n].line1), "^%c%5.0f^7 ^%c%3u^7/%3u %-65.65s", + entry->line1_len = dpsnprintf(entry->line1, sizeof(serverlist_cache[n].line1), "^%c%5.0f^7 ^%c%3u^7/%3u %-65.65s", info->ping >= 300 ? '1' : (info->ping >= 200 ? '3' : '7'), info->ping ?: INFINITY, // display inf when a listed server times out and net_slist_pause blocks its removal ((info->numhumans > 0 && info->numhumans < info->maxplayers) ? (info->numhumans >= 4 ? '7' : '3') : '1'), info->numplayers, info->maxplayers, info->name); - dpsnprintf(entry->line2, sizeof(serverlist_cache[n].line2), "^4%-21.21s %-19.19s ^%c%-17.17s^4 %-20.20s", info->cname, info->game, + entry->line2_len = dpsnprintf(entry->line2, sizeof(serverlist_cache[n].line2), "^4%-21.21s %-19.19s ^%c%-17.17s^4 %-20.20s", info->cname, info->game, ( info->gameversion != gameversion.integer && @@ -1842,7 +1842,7 @@ static qbool NetConn_ClientParsePacket_ServerList_PrepareQuery(int protocol, con entry = &serverlist_cache[n]; memset(entry, 0, sizeof(*entry)); entry->protocol = protocol; - dp_strlcpy(entry->info.cname, ipstring, sizeof(entry->info.cname)); + entry->info.cname_len = dp_strlcpy(entry->info.cname, ipstring, sizeof(entry->info.cname)); entry->info.isfavorite = isfavorite; serverlist_cachecount++; @@ -2175,15 +2175,15 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat return true; info = &serverlist_cache[n].info; - info->game[0] = 0; - info->mod[0] = 0; - info->map[0] = 0; - info->name[0] = 0; - info->qcstatus[0] = 0; - info->players[0] = 0; - info->protocol = -1; - info->numplayers = 0; - info->numbots = -1; + info->game[0] = '\0'; info->game_len = 0; + info->mod[0] = '\0'; info->mod_len = 0; + info->map[0] = '\0'; info->map_len = 0; + info->name[0] = '\0'; info->name_len = 0; + info->qcstatus[0] = '\0'; info->qcstatus_len = 0; + info->players[0] = '\0'; info->players_len = 0; + info->protocol = -1; + info->numplayers = 0; + info->numbots = -1; info->maxplayers = 0; info->gameversion = 0; @@ -2196,17 +2196,17 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat else Con_Printf("statusResponse without players block?\n"); - if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->game, s, sizeof (info->game)); - if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->mod , s, sizeof (info->mod )); - if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->map , s, sizeof (info->map )); - if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->name, s, sizeof (info->name)); + if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) info->game_len = dp_strlcpy(info->game, s, sizeof(info->game)); + if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) info->mod_len = dp_strlcpy(info->mod, s, sizeof(info->mod)); + if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) info->map_len = dp_strlcpy(info->map, s, sizeof(info->map)); + if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) info->name_len = dp_strlcpy(info->name, s, sizeof(info->name)); if ((s = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s); if ((s = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s); if ((s = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s); if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s); if ((s = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s); - if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->qcstatus, s, sizeof(info->qcstatus)); - if (p != NULL) dp_strlcpy(info->players, p, sizeof(info->players)); + if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) info->qcstatus_len = dp_strlcpy(info->qcstatus, s, sizeof(info->qcstatus)); + if (p != NULL) info->players_len = dp_strlcpy(info->players, p, sizeof(info->players)); info->numhumans = info->numplayers - max(0, info->numbots); info->freeslots = info->maxplayers - info->numplayers; @@ -2228,28 +2228,28 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat return true; info = &serverlist_cache[n].info; - info->game[0] = 0; - info->mod[0] = 0; - info->map[0] = 0; - info->name[0] = 0; - info->qcstatus[0] = 0; - info->players[0] = 0; - info->protocol = -1; - info->numplayers = 0; - info->numbots = -1; + info->game[0] = '\0'; info->game_len = 0; + info->mod[0] = '\0'; info->mod_len = 0; + info->map[0] = '\0'; info->map_len = 0; + info->name[0] = '\0'; info->name_len = 0; + info->qcstatus[0] = '\0'; info->qcstatus_len = 0; + info->players[0] = '\0'; info->players_len = 0; + info->protocol = -1; + info->numplayers = 0; + info->numbots = -1; info->maxplayers = 0; info->gameversion = 0; - if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->game, s, sizeof (info->game)); - if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->mod , s, sizeof (info->mod )); - if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->map , s, sizeof (info->map )); - if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->name, s, sizeof (info->name)); + if ((s = InfoString_GetValue(string, "gamename" , infostringvalue, sizeof(infostringvalue))) != NULL) info->game_len = dp_strlcpy(info->game, s, sizeof(info->game)); + if ((s = InfoString_GetValue(string, "modname" , infostringvalue, sizeof(infostringvalue))) != NULL) info->mod_len = dp_strlcpy(info->mod, s, sizeof(info->mod)); + if ((s = InfoString_GetValue(string, "mapname" , infostringvalue, sizeof(infostringvalue))) != NULL) info->map_len = dp_strlcpy(info->map, s, sizeof(info->map)); + if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) info->name_len = dp_strlcpy(info->name, s, sizeof(info->name)); if ((s = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s); if ((s = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s); if ((s = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s); if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s); if ((s = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s); - if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->qcstatus, s, sizeof(info->qcstatus)); + if ((s = InfoString_GetValue(string, "qcstatus" , infostringvalue, sizeof(infostringvalue))) != NULL) info->qcstatus_len = dp_strlcpy(info->qcstatus, s, sizeof(info->qcstatus)); info->numhumans = info->numplayers - max(0, info->numbots); info->freeslots = info->maxplayers - info->numplayers; @@ -2348,9 +2348,12 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat info = &serverlist_cache[n].info; dp_strlcpy(info->game, "QuakeWorld", sizeof(info->game)); - if ((s = InfoString_GetValue(string, "*gamedir" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->mod , s, sizeof (info->mod ));else info->mod[0] = 0; - if ((s = InfoString_GetValue(string, "map" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->map , s, sizeof (info->map ));else info->map[0] = 0; - if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) dp_strlcpy(info->name, s, sizeof (info->name));else info->name[0] = 0; + if ((s = InfoString_GetValue(string, "*gamedir" , infostringvalue, sizeof(infostringvalue))) != NULL) info->mod_len = dp_strlcpy(info->mod, s, sizeof(info->mod)); + else { info->mod[0] = '\0'; info->mod_len = 0; } + if ((s = InfoString_GetValue(string, "map" , infostringvalue, sizeof(infostringvalue))) != NULL) info->map_len = dp_strlcpy(info->map, s, sizeof(info->map)); + else { info->map[0] = '\0'; info->map_len = 0; } + if ((s = InfoString_GetValue(string, "hostname" , infostringvalue, sizeof(infostringvalue))) != NULL) info->name_len = dp_strlcpy(info->name, s, sizeof(info->name)); + else { info->name[0] = '\0'; info->name_len = 0; } info->protocol = 0; info->numplayers = 0; // updated below info->numhumans = 0; // updated below @@ -2470,10 +2473,10 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat break; info = &serverlist_cache[n].info; - dp_strlcpy(info->game, "Quake", sizeof(info->game)); - dp_strlcpy(info->mod , "", sizeof(info->mod)); // mod name is not specified - dp_strlcpy(info->name, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->name)); - dp_strlcpy(info->map , MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->map)); + info->game_len = dp_strlcpy(info->game, "Quake", sizeof(info->game)); + info->mod_len = dp_strlcpy(info->mod, "", sizeof(info->mod)); // mod name is not specified + info->name_len = dp_strlcpy(info->name, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->name)); + info->map_len = dp_strlcpy(info->map, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->map)); info->numplayers = MSG_ReadByte(&cl_message); info->maxplayers = MSG_ReadByte(&cl_message); info->protocol = MSG_ReadByte(&cl_message); diff --git a/netconn.h b/netconn.h index a70bf5b4..a7ef91d2 100755 --- a/netconn.h +++ b/netconn.h @@ -274,20 +274,27 @@ typedef struct serverlist_info_s { /// address for connecting char cname[128]; + unsigned cname_len; /// ping time for sorting servers, in milliseconds, 0 means no data unsigned ping; /// name of the game char game[32]; + unsigned game_len; /// name of the mod char mod[32]; + unsigned mod_len; /// name of the map char map[32]; + unsigned map_len; /// name of the session char name[128]; + unsigned name_len; /// qc-defined short status string char qcstatus[128]; + unsigned qcstatus_len; /// frags/ping/name list (if they fit in the packet) char players[2800]; + unsigned players_len; /// max client number int maxplayers; /// number of currently connected players (including bots) @@ -352,7 +359,9 @@ typedef struct serverlist_entry_s // legacy stuff char line1[128]; + unsigned line1_len; char line2[128]; + unsigned line2_len; } serverlist_entry_t; typedef struct serverlist_mask_s diff --git a/progsvm.h b/progsvm.h index 92ead5dc..4c6a7f4d 100644 --- a/progsvm.h +++ b/progsvm.h @@ -901,7 +901,8 @@ void PRVM_ED_PrintNum (prvm_prog_t *prog, int ent, const char *wildcard_fieldnam const char *PRVM_GetString(prvm_prog_t *prog, int num); int PRVM_SetEngineString(prvm_prog_t *prog, const char *s); const char *PRVM_ChangeEngineString(prvm_prog_t *prog, int i, const char *s); -int PRVM_SetTempString(prvm_prog_t *prog, const char *s); +/// Takes an strlen (not a buffer size). +int PRVM_SetTempString(prvm_prog_t *prog, const char *s, size_t slen); int PRVM_AllocString(prvm_prog_t *prog, size_t bufferlength, char **pointer); void PRVM_FreeString(prvm_prog_t *prog, int num); diff --git a/prvm_cmds.c b/prvm_cmds.c index dcf2dccf..aefac672 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -65,7 +65,7 @@ void VM_CheckEmptyString(prvm_prog_t *prog, const char *s) prog->error_cmd("%s: Bad string", prog->name); } -qbool PRVM_ConsoleCommand (prvm_prog_t *prog, const char *text, int *func, qbool preserve_self, int curself, double ptime, qbool prog_loaded, const char *error_message) +qbool PRVM_ConsoleCommand(prvm_prog_t *prog, const char *text, size_t textlen, int *func, qbool preserve_self, int curself, double ptime, qbool prog_loaded, const char *error_message) { int restorevm_tempstringsbuf_cursize; int save_self = 0; // hush compiler warning @@ -82,7 +82,7 @@ qbool PRVM_ConsoleCommand (prvm_prog_t *prog, const char *text, int *func, qbool PRVM_gameglobalfloat(time) = ptime; PRVM_gameglobaledict(self) = curself; restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; - PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, text); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, text, textlen); prog->ExecuteProgram(prog, *func, error_message); prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; if(preserve_self) @@ -778,11 +778,18 @@ const string VM_cvar_string (string, ...) */ void VM_cvar_string(prvm_prog_t *prog) { - char string[VM_TEMPSTRING_MAXSIZE]; + char cvar_name[VM_TEMPSTRING_MAXSIZE]; + VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_string); - VM_VarString(prog, 0, string, sizeof(string)); - VM_CheckEmptyString(prog, string); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_Cvar_ReadOk(prog, string) ? Cvar_VariableString(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask) : ""); + VM_VarString(prog, 0, cvar_name, sizeof(cvar_name)); + VM_CheckEmptyString(prog, cvar_name); + if (PRVM_Cvar_ReadOk(prog, cvar_name)) + { + const char *cvar_string = Cvar_VariableString(prog->console_cmd->cvars, cvar_name, prog->console_cmd->cvars_flagsmask); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cvar_string, strlen(cvar_string)); + } + else + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "", 0); } @@ -795,11 +802,14 @@ const string VM_cvar_defstring (string, ...) */ void VM_cvar_defstring(prvm_prog_t *prog) { - char string[VM_TEMPSTRING_MAXSIZE]; + char cvar_name[VM_TEMPSTRING_MAXSIZE]; + const char *cvar_defstring; + VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_defstring); - VM_VarString(prog, 0, string, sizeof(string)); - VM_CheckEmptyString(prog, string); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDefString(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask)); + VM_VarString(prog, 0, cvar_name, sizeof(cvar_name)); + VM_CheckEmptyString(prog, cvar_name); + cvar_defstring = Cvar_VariableDefString(prog->console_cmd->cvars, cvar_name, prog->console_cmd->cvars_flagsmask); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cvar_defstring, strlen(cvar_defstring)); } /* @@ -811,11 +821,14 @@ const string VM_cvar_description (string, ...) */ void VM_cvar_description(prvm_prog_t *prog) { - char string[VM_TEMPSTRING_MAXSIZE]; + char cvar_name[VM_TEMPSTRING_MAXSIZE]; + const char *cvar_desc; + VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_description); - VM_VarString(prog, 0, string, sizeof(string)); - VM_CheckEmptyString(prog, string); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDescription(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask)); + VM_VarString(prog, 0, cvar_name, sizeof(cvar_name)); + VM_CheckEmptyString(prog, cvar_name); + cvar_desc = Cvar_VariableDescription(prog->console_cmd->cvars, cvar_name, prog->console_cmd->cvars_flagsmask); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cvar_desc, strlen(cvar_desc)); } /* ================= @@ -879,16 +892,17 @@ void VM_ftos(prvm_prog_t *prog) { prvm_vec_t v; char s[128]; + size_t slen; VM_SAFEPARMCOUNT(1, VM_ftos); v = PRVM_G_FLOAT(OFS_PARM0); if ((prvm_vec_t)((prvm_int_t)v) == v) - dpsnprintf(s, sizeof(s), "%.0f", v); + slen = dpsnprintf(s, sizeof(s), "%.0f", v); else - dpsnprintf(s, sizeof(s), "%f", v); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s); + slen = dpsnprintf(s, sizeof(s), "%f", v); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s, slen); } /* @@ -920,11 +934,12 @@ string vtos(vector) void VM_vtos(prvm_prog_t *prog) { char s[512]; + size_t slen; VM_SAFEPARMCOUNT(1,VM_vtos); - dpsnprintf (s, sizeof(s), "'%5.1f %5.1f %5.1f'", PRVM_G_VECTOR(OFS_PARM0)[0], PRVM_G_VECTOR(OFS_PARM0)[1], PRVM_G_VECTOR(OFS_PARM0)[2]); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s); + slen = dpsnprintf(s, sizeof(s), "'%5.1f %5.1f %5.1f'", PRVM_G_VECTOR(OFS_PARM0)[0], PRVM_G_VECTOR(OFS_PARM0)[1], PRVM_G_VECTOR(OFS_PARM0)[2]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s, slen); } /* @@ -938,11 +953,12 @@ string etos(entity) void VM_etos(prvm_prog_t *prog) { char s[128]; + size_t slen; VM_SAFEPARMCOUNT(1, VM_etos); - dpsnprintf (s, sizeof(s), "entity %i", PRVM_G_EDICTNUM(OFS_PARM0)); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s); + slen = dpsnprintf(s, sizeof(s), "entity %i", PRVM_G_EDICTNUM(OFS_PARM0)); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s, slen); } /* @@ -1023,6 +1039,8 @@ void VM_strftime(prvm_prog_t *prog) #endif char fmt[VM_TEMPSTRING_MAXSIZE]; char result[VM_TEMPSTRING_MAXSIZE]; + size_t result_len; + VM_SAFEPARMCOUNTRANGE(2, 8, VM_strftime); VM_VarString(prog, 1, fmt, sizeof(fmt)); t = time(NULL); @@ -1044,11 +1062,11 @@ void VM_strftime(prvm_prog_t *prog) return; } #if _MSC_VER >= 1400 - strftime(result, sizeof(result), fmt, &tm); + result_len = strftime(result, sizeof(result), fmt, &tm); #else - strftime(result, sizeof(result), fmt, tm); + result_len = strftime(result, sizeof(result), fmt, tm); #endif - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, result); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, result, result_len); } /* @@ -2023,7 +2041,7 @@ void VM_fgets(prvm_prog_t *prog) if (end < VM_TEMPSTRING_MAXSIZE - 1) string[end++] = c; } - string[end] = 0; + string[end] = '\0'; // remove \n following \r if (c == '\r') { @@ -2034,7 +2052,7 @@ void VM_fgets(prvm_prog_t *prog) if (developer_extra.integer) Con_DPrintf("fgets: %s: %s\n", prog->name, string); if (c >= 0 || end) - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string, end); } /* @@ -2133,7 +2151,7 @@ void VM_entityfieldname(prvm_prog_t *prog) if (i < 0 || i >= prog->numfielddefs) { VM_Warning(prog, "VM_entityfieldname: %s: field index out of bounds\n", prog->name); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ""); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "", 0); return; } @@ -2185,8 +2203,8 @@ void VM_getentityfieldstring(prvm_prog_t *prog) if (i < 0 || i >= prog->numfielddefs) { - VM_Warning(prog, "VM_entityfielddata: %s: field index out of bounds\n", prog->name); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ""); + VM_Warning(prog, "VM_entityfielddata: %s: field index out of bounds\n", prog->name); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "", 0); return; } @@ -2196,7 +2214,7 @@ void VM_getentityfieldstring(prvm_prog_t *prog) ent = PRVM_G_EDICT(OFS_PARM1); if(ent->free) { - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ""); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "", 0); VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent)); return; } @@ -2209,11 +2227,12 @@ void VM_getentityfieldstring(prvm_prog_t *prog) break; if (j == prvm_type_size[type]) { - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ""); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "", 0); return; } - - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_UglyValueString(prog, (etype_t)d->type, val, valuebuf, sizeof(valuebuf))); + + PRVM_UglyValueString(prog, (etype_t)d->type, val, valuebuf, sizeof(valuebuf)); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, valuebuf, strlen(valuebuf)); } // KrimZon - DP_QC_ENTITYDATA @@ -2280,13 +2299,14 @@ string strdecolorize(string s) void VM_strdecolorize(prvm_prog_t *prog) { char szNewString[VM_TEMPSTRING_MAXSIZE]; + size_t szNewString_len; const char *szString; // Prepare Strings VM_SAFEPARMCOUNT(1,VM_strdecolorize); szString = PRVM_G_STRING(OFS_PARM0); - COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), true); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString); + szNewString_len = COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), true); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString, szNewString_len); } // DRESK - String Length (not counting color codes) @@ -2326,15 +2346,16 @@ string strtolower(string s) void VM_strtolower(prvm_prog_t *prog) { char szNewString[VM_TEMPSTRING_MAXSIZE]; + size_t szNewString_len; const char *szString; // Prepare Strings VM_SAFEPARMCOUNT(1,VM_strtolower); szString = PRVM_G_STRING(OFS_PARM0); - COM_ToLowerString(szString, szNewString, sizeof(szNewString) ); + szNewString_len = COM_ToLowerString(szString, szNewString, sizeof(szNewString) ); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString, szNewString_len); } /* @@ -2348,15 +2369,16 @@ string strtoupper(string s) void VM_strtoupper(prvm_prog_t *prog) { char szNewString[VM_TEMPSTRING_MAXSIZE]; + size_t szNewString_len; const char *szString; // Prepare Strings VM_SAFEPARMCOUNT(1,VM_strtoupper); szString = PRVM_G_STRING(OFS_PARM0); - COM_ToUpperString(szString, szNewString, sizeof(szNewString) ); + szNewString_len = COM_ToUpperString(szString, szNewString, sizeof(szNewString) ); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString, szNewString_len); } /* @@ -2372,10 +2394,12 @@ string strcat(string s, string...) void VM_strcat(prvm_prog_t *prog) { char s[VM_TEMPSTRING_MAXSIZE]; + size_t slen; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_strcat); - VM_VarString(prog, 0, s, sizeof(s)); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s); + slen = VM_VarString(prog, 0, s, sizeof(s)); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s, slen); } /* @@ -2439,7 +2463,7 @@ void VM_substring(prvm_prog_t *prog) u_start = u8_byteofs(s, start, NULL); if (u_start < 0) { - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ""); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "", 0); return; } u_length = u8_bytelen(s + u_start, length); @@ -2447,8 +2471,8 @@ void VM_substring(prvm_prog_t *prog) u_length = sizeof(string)-1; memcpy(string, s + u_start, u_length); - string[u_length] = 0; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string); + string[u_length] = '\0'; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string, u_length); } /* @@ -2515,7 +2539,7 @@ void VM_strreplace(prvm_prog_t *prog) string[si++] = subject[i]; string[si] = '\0'; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string, si); } /* @@ -2582,7 +2606,7 @@ void VM_strireplace(prvm_prog_t *prog) string[si++] = subject[i]; string[si] = '\0'; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string, si); } /* @@ -2676,7 +2700,7 @@ void VM_tokenize (prvm_prog_t *prog) if(!COM_ParseToken_VM_Tokenize(&p, false)) break; tokens_endpos[num_tokens] = p - tokenize_string; - tokens[num_tokens] = PRVM_SetTempString(prog, com_token); + tokens[num_tokens] = PRVM_SetTempString(prog, com_token, com_token_len); ++num_tokens; } @@ -2707,7 +2731,7 @@ void VM_tokenize_console (prvm_prog_t *prog) if(!COM_ParseToken_Console(&p)) break; tokens_endpos[num_tokens] = p - tokenize_string; - tokens[num_tokens] = PRVM_SetTempString(prog, com_token); + tokens[num_tokens] = PRVM_SetTempString(prog, com_token, com_token_len); ++num_tokens; } @@ -2783,8 +2807,8 @@ void VM_tokenizebyseparator (prvm_prog_t *prog) tokens_endpos[num_tokens] = p0 - tokenize_string; if (j >= (int)sizeof(tokentext)) break; - tokentext[j++] = 0; - tokens[num_tokens++] = PRVM_SetTempString(prog, token); + tokentext[j++] = '\0'; + tokens[num_tokens++] = PRVM_SetTempString(prog, token, j - 1); if (!*p) break; } @@ -3259,6 +3283,7 @@ string search_getfilename(float handle, float num) void VM_search_getfilename(prvm_prog_t *prog) { int handle, filenum; + VM_SAFEPARMCOUNT(2, VM_search_getfilename); handle = (int)PRVM_G_FLOAT(OFS_PARM0); @@ -3280,7 +3305,9 @@ void VM_search_getfilename(prvm_prog_t *prog) return; } - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, prog->opensearches[handle]->filenames[filenum]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, + prog->opensearches[handle]->filenames[filenum], + strlen(prog->opensearches[handle]->filenames[filenum])); } /* @@ -3304,11 +3331,11 @@ void VM_chr(prvm_prog_t *prog) char tmp[8]; int len; - VM_SAFEPARMCOUNT(1, VM_chr); + VM_SAFEPARMCOUNT(1, VM_chr); len = u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0), tmp, sizeof(tmp)); - tmp[len] = 0; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp); + tmp[len] = '\0'; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp, len); } /* @@ -3321,9 +3348,11 @@ string keynumtostring(float keynum) void VM_keynumtostring (prvm_prog_t *prog) { char tinystr[TINYSTR_LEN]; - VM_SAFEPARMCOUNT(1, VM_keynumtostring); + const char *str; // Key_KeynumToString doesn't always return tinystr - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Key_KeynumToString((int)PRVM_G_FLOAT(OFS_PARM0), tinystr, TINYSTR_LEN)); + VM_SAFEPARMCOUNT(1, VM_keynumtostring); + str = Key_KeynumToString((int)PRVM_G_FLOAT(OFS_PARM0), tinystr, sizeof(tinystr)); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, str, strlen(str)); } /* @@ -3341,6 +3370,7 @@ void VM_findkeysforcommand(prvm_prog_t *prog) { const char *cmd; char ret[VM_TEMPSTRING_MAXSIZE]; + size_t ret_len; int keys[FKFC_NUMKEYS]; int i; int bindmap; @@ -3360,9 +3390,9 @@ void VM_findkeysforcommand(prvm_prog_t *prog) ret[0] = 0; for(i = 0; i < FKFC_NUMKEYS; i++) - dp_strlcat(ret, va(vabuf, sizeof(vabuf), " \'%i\'", keys[i]), sizeof(ret)); + ret_len = dp_strlcat(ret, va(vabuf, sizeof(vabuf), " \'%i\'", keys[i]), sizeof(ret)); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ret); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ret, ret_len); } /* @@ -3389,13 +3419,15 @@ string getkeybind(float key, float bindmap) void VM_getkeybind (prvm_prog_t *prog) { int bindmap; + const char *bind; + VM_SAFEPARMCOUNTRANGE(1, 2, VM_getkeybind); if(prog->argc == 2) bindmap = bound(-1, PRVM_G_FLOAT(OFS_PARM1), MAX_BINDMAPS-1); else bindmap = 0; // consistent to "bind" - - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0), bindmap)); + bind = Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0), bindmap); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, bind, strlen(bind)); } /* @@ -3653,9 +3685,9 @@ void VM_altstr_prepare(prvm_prog_t *prog) else outstr[outpos++] = *in; } - outstr[outpos] = 0; - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, outstr ); + outstr[outpos] = '\0'; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outstr, outpos); } /* @@ -3702,8 +3734,8 @@ void VM_altstr_get(prvm_prog_t *prog) else *out = *pos; - *out = 0; - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, outstr ); + *out = '\0'; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outstr, out - outstr); } /* @@ -3746,8 +3778,8 @@ void VM_altstr_set(prvm_prog_t *prog) if( *in == '\'' || (*in == '\\' && !*++in) ) break; - dp_strlcpy(out, in, outstr + sizeof(outstr) - out); - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, outstr ); + out += dp_strlcpy(out, in, outstr + sizeof(outstr) - out); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outstr, out - outstr); } /* @@ -3785,8 +3817,8 @@ void VM_altstr_ins(prvm_prog_t *prog) for( ; *set ; *out++ = *set++ ); *out++ = '\''; - dp_strlcpy(out, in, outstr + sizeof(outstr) - out); - PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, outstr ); + out += dp_strlcpy(out, in, outstr + sizeof(outstr) - out); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outstr, out - outstr); } @@ -4113,10 +4145,12 @@ string buf_implode(float bufhandle, string glue) = #465; void VM_buf_implode (prvm_prog_t *prog) { prvm_stringbuffer_t *stringbuffer; - char k[VM_TEMPSTRING_MAXSIZE]; - const char *sep; - int i; - size_t l; + char k[VM_TEMPSTRING_MAXSIZE]; + size_t k_len; + const char *sep; + int i; + size_t l; + VM_SAFEPARMCOUNT(2, VM_buf_implode); stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0)); @@ -4129,7 +4163,8 @@ void VM_buf_implode (prvm_prog_t *prog) if(!stringbuffer->num_strings) return; sep = PRVM_G_STRING(OFS_PARM1); - k[0] = 0; + k[0] = '\0'; + k_len = 0; for(l = i = 0;i < stringbuffer->num_strings;i++) { if(stringbuffer->strings[i]) @@ -4138,10 +4173,10 @@ void VM_buf_implode (prvm_prog_t *prog) if (l >= sizeof(k) - 1) break; dp_strlcat(k, sep, sizeof(k)); - dp_strlcat(k, stringbuffer->strings[i], sizeof(k)); + k_len = dp_strlcat(k, stringbuffer->strings[i], sizeof(k)); } } - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, k); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, k, k_len); } /* @@ -4171,7 +4206,7 @@ void VM_bufstr_get (prvm_prog_t *prog) return; } if (strindex < stringbuffer->num_strings && stringbuffer->strings[strindex]) - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, stringbuffer->strings[strindex]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, stringbuffer->strings[strindex], strlen(stringbuffer->strings[strindex])); } /* @@ -4839,14 +4874,14 @@ void VM_changepitch (prvm_prog_t *prog) void VM_uncolorstring (prvm_prog_t *prog) { char szNewString[VM_TEMPSTRING_MAXSIZE]; + size_t szNewString_len; const char *szString; // Prepare Strings VM_SAFEPARMCOUNT(1, VM_uncolorstring); szString = PRVM_G_STRING(OFS_PARM0); - COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), true); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString); - + szNewString_len = COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), true); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString, szNewString_len); } // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS) @@ -4911,11 +4946,12 @@ void VM_chr2str (prvm_prog_t *prog) char t[9 * 4 + 1]; int i; size_t len = 0; + VM_SAFEPARMCOUNTRANGE(0, 8, VM_chr2str); for(i = 0; i < prog->argc && len < sizeof(t)-1; ++i) len += u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0+i*3), t + len, sizeof(t)-1); - t[len] = 0; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t); + t[len] = '\0'; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t, len); } static int chrconv_number(int i, int base, int conv) @@ -5044,7 +5080,7 @@ void VM_strconv (prvm_prog_t *prog) } *result = '\0'; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, (char *) resbuf); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, (char *)resbuf, result - resbuf); } // #225 string(float chars, string s, ...) strpad (FTE_STRINGS) @@ -5052,16 +5088,18 @@ void VM_strpad (prvm_prog_t *prog) { char src[VM_TEMPSTRING_MAXSIZE]; char destbuf[VM_TEMPSTRING_MAXSIZE]; + size_t destbuf_len; int pad; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_strpad); pad = (int) PRVM_G_FLOAT(OFS_PARM0); VM_VarString(prog, 1, src, sizeof(src)); // note: < 0 = left padding, > 0 = right padding, // this is reverse logic of printf! - dpsnprintf(destbuf, sizeof(destbuf), "%*s", -pad, src); + destbuf_len = dpsnprintf(destbuf, sizeof(destbuf), "%*s", -pad, src); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, destbuf); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, destbuf, destbuf_len); } // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS) @@ -5081,7 +5119,7 @@ void VM_infoadd (prvm_prog_t *prog) InfoString_SetValue(temp, VM_TEMPSTRING_MAXSIZE, key, value); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, temp); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, temp, strlen(temp)); } // #227 string(string info, string key) infoget (FTE_STRINGS) @@ -5098,7 +5136,7 @@ void VM_infoget (prvm_prog_t *prog) InfoString_GetValue(info, key, value, VM_TEMPSTRING_MAXSIZE); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, value); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, value, strlen(value)); } //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS) @@ -5191,8 +5229,8 @@ void VM_digest_hex(prvm_prog_t *prog) outhex[2*i] = hexmap[(out[i] >> 4) & 15]; outhex[2*i+1] = hexmap[(out[i] >> 0) & 15]; } - outhex[2*i] = 0; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outhex); + outhex[2*i] = '\0'; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outhex, 2*i); } else PRVM_G_INT(OFS_RETURN) = 0; @@ -5218,7 +5256,7 @@ void VM_SetTraceGlobals(prvm_prog_t *prog, const trace_t *trace) PRVM_gameglobalfloat(trace_dpstartcontents) = trace->startsupercontents; PRVM_gameglobalfloat(trace_dphitcontents) = trace->hitsupercontents; PRVM_gameglobalfloat(trace_dphitq3surfaceflags) = trace->hitq3surfaceflags; - PRVM_gameglobalstring(trace_dphittexturename) = trace->hittexture ? PRVM_SetTempString(prog, trace->hittexture->name) : 0; + PRVM_gameglobalstring(trace_dphittexturename) = trace->hittexture ? PRVM_SetTempString(prog, trace->hittexture->name, strlen(trace->hittexture->name)) : 0; } void VM_ClearTraceGlobals(prvm_prog_t *prog) @@ -5286,9 +5324,9 @@ void VM_uri_escape (prvm_prog_t *prog) *q++ = hex[ *(unsigned char *)p & 0xF]; } } - *q++ = 0; + *q = '\0'; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, dest); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, dest, q - dest); } // #510 string(string input, ...) uri_unescape (DP_QC_URI_ESCAPE) @@ -5333,9 +5371,9 @@ nohex: // otherwise: *q++ = *p++; } - *q++ = 0; + *q = '\0'; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, dest); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, dest, q - dest); } // #502 string(string filename) whichpack (DP_QC_WHICHPACK) @@ -5348,7 +5386,7 @@ void VM_whichpack (prvm_prog_t *prog) fn = PRVM_G_STRING(OFS_PARM0); pack = FS_WhichPack(fn); - PRVM_G_INT(OFS_RETURN) = pack ? PRVM_SetTempString(prog, pack) : 0; + PRVM_G_INT(OFS_RETURN) = pack ? PRVM_SetTempString(prog, pack, strlen(pack)) : 0; } typedef struct @@ -5386,11 +5424,11 @@ static void uri_to_string_callback(int status, size_t length_received, unsigned { if(length_received >= sizeof(handle->buffer)) length_received = sizeof(handle->buffer) - 1; - handle->buffer[length_received] = 0; + handle->buffer[length_received] = '\0'; PRVM_G_FLOAT(OFS_PARM0) = handle->id; PRVM_G_FLOAT(OFS_PARM1) = status; - PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(prog, handle->buffer); + PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(prog, handle->buffer, length_received); prog->ExecuteProgram(prog, PRVM_allfunction(URI_Get_Callback), "QC function URI_Get_Callback is missing"); } @@ -5570,6 +5608,7 @@ void VM_netaddress_resolve (prvm_prog_t *prog) { const char *ip; char normalized[128]; + size_t normalized_len; int port; lhnetaddress_t addr; @@ -5580,10 +5619,10 @@ void VM_netaddress_resolve (prvm_prog_t *prog) if(prog->argc > 1) port = (int) PRVM_G_FLOAT(OFS_PARM1); - if(LHNETADDRESS_FromString(&addr, ip, port) && LHNETADDRESS_ToString(&addr, normalized, sizeof(normalized), prog->argc > 1)) - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, normalized); + if(LHNETADDRESS_FromString(&addr, ip, port) && (normalized_len = LHNETADDRESS_ToString(&addr, normalized, sizeof(normalized), prog->argc > 1))) + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, normalized, normalized_len); else - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ""); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "", 0); } //string(prvm_prog_t *prog) getextresponse = #624; // returns the next extResponse packet that was sent to this client @@ -5598,7 +5637,7 @@ void VM_CL_getextresponse (prvm_prog_t *prog) int first; --cl_net_extresponse_count; first = (cl_net_extresponse_last + NET_EXTRESPONSE_MAX - cl_net_extresponse_count) % NET_EXTRESPONSE_MAX; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cl_net_extresponse[first]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cl_net_extresponse[first], strlen(cl_net_extresponse[first])); } } @@ -5613,7 +5652,7 @@ void VM_SV_getextresponse (prvm_prog_t *prog) int first; --sv_net_extresponse_count; first = (sv_net_extresponse_last + NET_EXTRESPONSE_MAX - sv_net_extresponse_count) % NET_EXTRESPONSE_MAX; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, sv_net_extresponse[first]); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, sv_net_extresponse[first], strlen(sv_net_extresponse[first])); } } @@ -6066,9 +6105,10 @@ verbatim: break; } } + finished: - *o = 0; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outbuf); + *o = '\0'; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outbuf, o - outbuf); } @@ -6394,11 +6434,12 @@ void VM_getsurfacetexture(prvm_prog_t *prog) { model_t *model; msurface_t *surface; + VM_SAFEPARMCOUNT(2, VM_getsurfacetexture); PRVM_G_INT(OFS_RETURN) = OFS_NULL; if (!(model = getmodel(prog, PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, surface->texture->name); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, surface->texture->name, strlen(surface->texture->name)); } //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438; void VM_getsurfacenearpoint(prvm_prog_t *prog) diff --git a/prvm_cmds.h b/prvm_cmds.h index 46bab5d2..24fe4a91 100644 --- a/prvm_cmds.h +++ b/prvm_cmds.h @@ -218,7 +218,7 @@ float getserverlistindexforkey(string key) void VM_CheckEmptyString (prvm_prog_t *prog, const char *s); /// Returns the length of the *out string excluding the \0 terminator. size_t VM_VarString(prvm_prog_t *prog, int first, char *out, size_t outsize); -qbool PRVM_ConsoleCommand (prvm_prog_t *prog, const char *text, int *func, qbool preserve_self, int curself, double ptime, qbool prog_loaded, const char *error_message); +qbool PRVM_ConsoleCommand(prvm_prog_t *prog, const char *text, size_t textlen, int *func, qbool preserve_self, int curself, double ptime, qbool prog_loaded, const char *error_message); prvm_stringbuffer_t *BufStr_FindCreateReplace (prvm_prog_t *prog, int bufindex, int flags, const char *format); void BufStr_Set(prvm_prog_t *prog, prvm_stringbuffer_t *stringbuffer, int strindex, const char *str); void BufStr_Del(prvm_prog_t *prog, prvm_stringbuffer_t *stringbuffer); diff --git a/prvm_edict.c b/prvm_edict.c index 36a44e48..aa05028f 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "progsvm.h" #include "csprogs.h" +#include "prvm_cmds.h" prvm_prog_t prvm_prog_list[PRVM_PROG_MAX]; @@ -1123,7 +1124,7 @@ static void PRVM_GameCommand(cmd_state_t *cmd, const char *whichprogs, const cha s = Cmd_Args(cmd); restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; - PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s ? s : ""); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s ? s : "", s ? strlen(s) : 0); prog->ExecuteProgram(prog, PRVM_allfunction(GameCommand), "QC function GameCommand is missing"); prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } @@ -3366,23 +3367,23 @@ int PRVM_SetEngineString(prvm_prog_t *prog, const char *s) // restores it on return, so multiple recursive calls can share the same // buffer) // the buffer size is automatically grown as needed - -int PRVM_SetTempString(prvm_prog_t *prog, const char *s) +int PRVM_SetTempString(prvm_prog_t *prog, const char *s, size_t slen) { - int size; + size_t size; char *t; - if (!s) + + if (!s || slen >= VM_TEMPSTRING_MAXSIZE) return 0; - size = (int)strlen(s) + 1; + size = slen + 1; if (developer_insane.integer) - Con_DPrintf("PRVM_SetTempString %s: cursize %i, size %i\n", prog->name, prog->tempstringsbuf.cursize, size); - if (prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size) + Con_DPrintf("PRVM_SetTempString %s: cursize %i, size %zu\n", prog->name, prog->tempstringsbuf.cursize, size); + if ((size_t)prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size) { sizebuf_t old = prog->tempstringsbuf; if (prog->tempstringsbuf.cursize + size >= 1<<28) - prog->error_cmd("PRVM_SetTempString %s: ran out of tempstring memory! (refusing to grow tempstring buffer over 256MB, cursize %i, size %i)\n", prog->name, prog->tempstringsbuf.cursize, size); + prog->error_cmd("PRVM_SetTempString %s: ran out of tempstring memory! (refusing to grow tempstring buffer over 256MB, cursize %i, size %zu)\n", prog->name, prog->tempstringsbuf.cursize, size); prog->tempstringsbuf.maxsize = max(prog->tempstringsbuf.maxsize, 65536); - while (prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size) + while ((size_t)prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size) prog->tempstringsbuf.maxsize *= 2; if (prog->tempstringsbuf.maxsize != old.maxsize || prog->tempstringsbuf.data == NULL) { diff --git a/server.h b/server.h index 729418d9..22b6a1f8 100644 --- a/server.h +++ b/server.h @@ -625,6 +625,6 @@ void SV_PreSpawn_f(cmd_state_t *cmd); void SV_Spawn_f(cmd_state_t *cmd); void SV_Begin_f(cmd_state_t *cmd); -qbool SV_VM_ConsoleCommand (const char *text); +qbool SV_VM_ConsoleCommand(const char *text, size_t textlen); #endif diff --git a/sv_user.c b/sv_user.c index 6a621bac..58bef9bf 100644 --- a/sv_user.c +++ b/sv_user.c @@ -987,6 +987,7 @@ void SV_ReadClientMessage(void) prvm_prog_t *prog = SVVM_prog; int netcmd, num, start; char *s, *p, *q; + size_t slen; if(sv_autodemo_perclient.integer >= 2) SV_WriteDemoMessage(host_client, &(host_client->netconnection->message), true); @@ -1035,7 +1036,8 @@ void SV_ReadClientMessage(void) // allow reliable messages now as the client is done with initial loading if (host_client->sendsignon == 2) host_client->sendsignon = 0; - s = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring)); + slen = MSG_ReadString_len(&sv_message, sv_readstring, sizeof(sv_readstring)); + s = sv_readstring; q = NULL; for(p = s; *p; ++p) switch(*p) { @@ -1054,19 +1056,19 @@ void SV_ReadClientMessage(void) if (strncasecmp(s, "spawn", 5) == 0 || strncasecmp(s, "begin", 5) == 0 || strncasecmp(s, "prespawn", 8) == 0) - Cmd_ExecuteString (cmd_serverfromclient, s, src_client, true); + Cmd_ExecuteString(cmd_serverfromclient, s, slen, src_client, true); else if (PRVM_serverfunction(SV_ParseClientCommand)) { int restorevm_tempstringsbuf_cursize; restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; - PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s, slen); PRVM_serverglobalfloat(time) = sv.time; PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); prog->ExecuteProgram(prog, PRVM_serverfunction(SV_ParseClientCommand), "QC function SV_ParseClientCommand is missing"); prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } else - Cmd_ExecuteString (cmd_serverfromclient, s, src_client, true); + Cmd_ExecuteString(cmd_serverfromclient, s, slen, src_client, true); break; clc_stringcmd_invalid: diff --git a/svvm_cmds.c b/svvm_cmds.c index 3f595f21..278786ea 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -2433,7 +2433,7 @@ static void VM_SV_clientcommand(prvm_prog_t *prog) temp_client = host_client; host_client = svs.clients + i; - Cmd_ExecuteString(cmd_serverfromclient, PRVM_G_STRING(OFS_PARM1), src_client, true); + Cmd_ExecuteString(cmd_serverfromclient, PRVM_G_STRING(OFS_PARM1), strlen(PRVM_G_STRING(OFS_PARM1)), src_client, true); host_client = temp_client; } @@ -2686,7 +2686,7 @@ static void VM_SV_gettaginfo(prvm_prog_t *prog) Matrix4x4_ToVectors(&tag_localmatrix, forward, left, up, origin); PRVM_serverglobalfloat(gettaginfo_parent) = parentindex; - PRVM_serverglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0; + PRVM_serverglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname, strlen(tagname)) : 0; VectorCopy(forward, PRVM_serverglobalvector(gettaginfo_forward)); VectorNegate(left, PRVM_serverglobalvector(gettaginfo_right)); VectorCopy(up, PRVM_serverglobalvector(gettaginfo_up)); @@ -2785,9 +2785,10 @@ string(string key) serverkey static void VM_SV_serverkey(prvm_prog_t *prog) { char string[VM_TEMPSTRING_MAXSIZE]; + VM_SAFEPARMCOUNT(1, VM_SV_serverkey); InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string)); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string, strlen(string)); } //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC) @@ -2924,10 +2925,10 @@ static void VM_SV_pointparticles(prvm_prog_t *prog) SV_FlushBroadcastMessages(); } -qbool SV_VM_ConsoleCommand (const char *text) +qbool SV_VM_ConsoleCommand(const char *text, size_t textlen) { prvm_prog_t *prog = SVVM_prog; - return PRVM_ConsoleCommand(prog, text, &prog->funcoffsets.ConsoleCmd, true, PRVM_EDICT_TO_PROG(sv.world.prog->edicts), sv.time, !(!sv.active || !prog || !prog->loaded), "QC function ConsoleCmd is missing"); + return PRVM_ConsoleCommand(prog, text, textlen, &prog->funcoffsets.ConsoleCmd, true, PRVM_EDICT_TO_PROG(sv.world.prog->edicts), sv.time, !(!sv.active || !prog || !prog->loaded), "QC function ConsoleCmd is missing"); } // #352 void(string cmdname) registercommand (EXT_CSQC) @@ -3043,7 +3044,7 @@ static void VM_SV_skel_get_bonename(prvm_prog_t *prog) return; if (bonenum < 0 || bonenum >= skeleton->model->num_bones) return; - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, skeleton->model->data_bones[bonenum].name); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, skeleton->model->data_bones[bonenum].name, strlen(skeleton->model->data_bones[bonenum].name)); } // #267 float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) returns parent num for supplied bonenum, 0 if bonenum has no parent or bone does not exist (returned value is always less than bonenum, you can loop on this) -- 2.39.2