#include "quakedef.h"
#include "progsvm.h"
#include "csprogs.h"
+#include "prvm_cmds.h"
prvm_prog_t prvm_prog_list[PRVM_PROG_MAX];
if(prog->leaktest_active)
if(prog->depth > 0) // actually in QC code and not just parsing the entities block of a map/savegame
{
- buf = (char *)PRVM_Alloc(256);
- PRVM_ShortStackTrace(prog, buf, 256);
+ // bones_was_here: this is the smallest 64 multiple that avoids truncation in Xonotic (was 256)
+ buf = (char *)PRVM_Alloc(448);
+ PRVM_ShortStackTrace(prog, buf, 448);
}
return buf;
}
switch (type)
{
case ev_string:
- strlcpy (line, PRVM_GetString (prog, val->string), linelength);
+ dp_strlcpy (line, PRVM_GetString (prog, val->string), linelength);
break;
case ev_entity:
n = val->edict;
if ((unsigned int)val->function < (unsigned int)prog->progs_numfunctions)
{
f = prog->functions + val->function;
- strlcpy (line, PRVM_GetString (prog, f->s_name), linelength);
+ dp_strlcpy (line, PRVM_GetString (prog, f->s_name), linelength);
}
else
dpsnprintf (line, linelength, "bad function %" PRVM_PRIi " (invalid!)", val->function);
tempstring2[sizeof(tempstring2)-1] = 0;
name = tempstring2;
}
- strlcat(tempstring, name, sizeof(tempstring));
+ dp_strlcat(tempstring, name, sizeof(tempstring));
for (l = strlen(name);l < 14;l++)
- strlcat(tempstring, " ", sizeof(tempstring));
- strlcat(tempstring, " ", sizeof(tempstring));
+ dp_strlcat(tempstring, " ", sizeof(tempstring));
+ dp_strlcat(tempstring, " ", sizeof(tempstring));
name = PRVM_ValueString(prog, (etype_t)d->type, val, valuebuf, sizeof(valuebuf));
if (strlen(name) > sizeof(tempstring2)-4)
tempstring2[sizeof(tempstring2)-1] = 0;
name = tempstring2;
}
- strlcat(tempstring, name, sizeof(tempstring));
- strlcat(tempstring, "\n", sizeof(tempstring));
+ dp_strlcat(tempstring, name, sizeof(tempstring));
+ dp_strlcat(tempstring, "\n", sizeof(tempstring));
if (strlen(tempstring) >= sizeof(tempstring)/2)
{
Con_Print(tempstring);
if (developer_entityparsing.integer)
Con_Printf("Key: \"%s\"", com_token);
- strlcpy (keyname, com_token, sizeof(keyname));
+ dp_strlcpy (keyname, com_token, sizeof(keyname));
// parse value
if (!COM_ParseToken_Simple(&data, false, true, true))
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;
}
// and allow them to be turned into vectors. (FIXME...)
if (!strcmp(com_token, "angle"))
{
- strlcpy (com_token, "angles", sizeof(com_token));
+ dp_strlcpy (com_token, "angles", sizeof(com_token));
anglehack = true;
}
else
// FIXME: change light to _light to get rid of this hack
if (!strcmp(com_token, "light"))
- strlcpy (com_token, "light_lev", sizeof(com_token)); // hack for single light def
+ dp_strlcpy (com_token, "light_lev", sizeof(com_token)); // hack for single light def
- strlcpy (keyname, com_token, sizeof(keyname));
+ dp_strlcpy (keyname, com_token, sizeof(keyname));
// another hack to fix keynames with trailing spaces
n = strlen(keyname);
if (anglehack)
{
char temp[32];
- strlcpy (temp, com_token, sizeof(temp));
+ dp_strlcpy (temp, com_token, sizeof(temp));
dpsnprintf (com_token, sizeof(com_token), "0 %s 0", temp);
}
break;
if((size_t)(q - p) >= (size_t) sizeof(inbuf))
break;
- strlcpy(inbuf, p, q - p); // not - 1, because this adds a NUL
+ dp_strlcpy(inbuf, p, q - p); // not - 1, because this adds a NUL
PRVM_PO_ParseString(decodedbuf + decodedpos, inbuf, sizeof(decodedbuf) - decodedpos);
decodedpos += strlen(decodedbuf + decodedpos);
if(*q == '\r')
char filename[512];
FS_StripExtension( progname, filename, sizeof( filename ) );
- strlcat( filename, ".lno", sizeof( filename ) );
+ dp_strlcat( filename, ".lno", sizeof( filename ) );
lno = FS_LoadFile( filename, tempmempool, false, &filesize );
if( !lno ) {
switch(d->type & ~DEF_SAVEGLOBAL)
{
case ev_string:
- strlcat(tempstring, "string ", sizeof(tempstring));
+ dp_strlcat(tempstring, "string ", sizeof(tempstring));
break;
case ev_entity:
- strlcat(tempstring, "entity ", sizeof(tempstring));
+ dp_strlcat(tempstring, "entity ", sizeof(tempstring));
break;
case ev_function:
- strlcat(tempstring, "function ", sizeof(tempstring));
+ dp_strlcat(tempstring, "function ", sizeof(tempstring));
break;
case ev_field:
- strlcat(tempstring, "field ", sizeof(tempstring));
+ dp_strlcat(tempstring, "field ", sizeof(tempstring));
break;
case ev_void:
- strlcat(tempstring, "void ", sizeof(tempstring));
+ dp_strlcat(tempstring, "void ", sizeof(tempstring));
break;
case ev_float:
- strlcat(tempstring, "float ", sizeof(tempstring));
+ dp_strlcat(tempstring, "float ", sizeof(tempstring));
break;
case ev_vector:
- strlcat(tempstring, "vector ", sizeof(tempstring));
+ dp_strlcat(tempstring, "vector ", sizeof(tempstring));
break;
case ev_pointer:
- strlcat(tempstring, "pointer ", sizeof(tempstring));
+ dp_strlcat(tempstring, "pointer ", sizeof(tempstring));
break;
default:
dpsnprintf (tempstring2, sizeof(tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
- strlcat(tempstring, tempstring2, sizeof(tempstring));
+ dp_strlcat(tempstring, tempstring2, sizeof(tempstring));
break;
}
if (strlen(name) > sizeof(tempstring2)-4)
tempstring2[sizeof(tempstring2)-1] = 0;
name = tempstring2;
}
- strlcat(tempstring, name, sizeof(tempstring));
+ dp_strlcat(tempstring, name, sizeof(tempstring));
for (j = (int)strlen(name);j < 25;j++)
- strlcat(tempstring, " ", sizeof(tempstring));
+ dp_strlcat(tempstring, " ", sizeof(tempstring));
dpsnprintf(tempstring2, sizeof(tempstring2), "%5d", counts[i]);
- strlcat(tempstring, tempstring2, sizeof(tempstring));
- strlcat(tempstring, "\n", sizeof(tempstring));
+ dp_strlcat(tempstring, tempstring2, sizeof(tempstring));
+ dp_strlcat(tempstring, "\n", sizeof(tempstring));
if (strlen(tempstring) >= sizeof(tempstring)/2)
{
Con_Print(tempstring);
{
debug_data_t *debug = &debug_data[prog - prvm_prog_list];
- strlcpy(debug->break_statement, Cmd_Argv(cmd, 2), sizeof(debug->break_statement));
+ dp_strlcpy(debug->break_statement, Cmd_Argv(cmd, 2), sizeof(debug->break_statement));
}
PRVM_UpdateBreakpoints(prog);
}
{
debug_data_t *debug = &debug_data[prog - prvm_prog_list];
- strlcpy(debug->watch_global, Cmd_Argv(cmd, 2), sizeof(debug->watch_global));
+ dp_strlcpy(debug->watch_global, Cmd_Argv(cmd, 2), sizeof(debug->watch_global));
}
PRVM_UpdateBreakpoints(prog);
}
{
debug_data_t *debug = &debug_data[prog - prvm_prog_list];
debug->watch_edict = atoi(Cmd_Argv(cmd, 2));
- strlcpy(debug->watch_field, Cmd_Argv(cmd, 3), sizeof(debug->watch_field));
+ dp_strlcpy(debug->watch_field, Cmd_Argv(cmd, 3), sizeof(debug->watch_field));
}
PRVM_UpdateBreakpoints(prog);
}
*/
void PRVM_Init (void)
{
+ unsigned int i;
+
Cmd_AddCommand(CF_SHARED, "prvm_edict", PRVM_ED_PrintEdict_f, "print all data about an entity number in the selected VM (server, client, menu)");
Cmd_AddCommand(CF_SHARED, "prvm_edicts", PRVM_ED_PrintEdicts_f, "prints all data about all entities in the selected VM (server, client, menu)");
Cmd_AddCommand(CF_SHARED, "prvm_edictcount", PRVM_ED_Count_f, "prints number of active entities in the selected VM (server, client, menu)");
prvm_runawaycheck = !Sys_CheckParm("-norunaway");
//VM_Cmd_Init();
+
+ // LadyHavoc: report supported extensions
+ Con_DPrintf("\nQuakeC extensions for server and client:");
+ for (i = 0; vm_sv_extensions[i]; i++)
+ Con_DPrintf(" %s", vm_sv_extensions[i]);
+ Con_DPrintf("\n");
+#ifdef CONFIG_MENU
+ Con_DPrintf("\nQuakeC extensions for menu:");
+ for (i = 0; vm_m_extensions[i]; i++)
+ Con_DPrintf(" %s", vm_m_extensions[i]);
+ Con_DPrintf("\n");
+#endif
}
/*
// 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: cursize %i, size %i\n", 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: ran out of tempstring memory! (refusing to grow tempstring buffer over 256MB, cursize %i, size %i)\n", 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)
{
- Con_DPrintf("PRVM_SetTempString: enlarging tempstrings buffer (%iKB -> %iKB)\n", old.maxsize/1024, prog->tempstringsbuf.maxsize/1024);
+ Con_DPrintf("PRVM_SetTempString %s: enlarging tempstrings buffer (%iKB -> %iKB)\n", prog->name, old.maxsize/1024, prog->tempstringsbuf.maxsize/1024);
prog->tempstringsbuf.data = (unsigned char *) Mem_Alloc(prog->progs_mempool, prog->tempstringsbuf.maxsize);
if (old.data)
{
void PRVM_FreeString(prvm_prog_t *prog, int num)
{
if (num == 0)
- prog->error_cmd("PRVM_FreeString: attempt to free a NULL string");
+ prog->error_cmd("PRVM_FreeString %s: attempt to free a NULL string", prog->name);
else if (num >= 0 && num < prog->stringssize)
- prog->error_cmd("PRVM_FreeString: attempt to free a constant string");
+ prog->error_cmd("PRVM_FreeString %s: attempt to free a constant string", prog->name);
else if (num >= PRVM_KNOWNSTRINGBASE && num < PRVM_KNOWNSTRINGBASE + prog->numknownstrings)
{
num = num - PRVM_KNOWNSTRINGBASE;
if (!prog->knownstrings[num])
- prog->error_cmd("PRVM_FreeString: attempt to free a non-existent or already freed string");
+ prog->error_cmd("PRVM_FreeString %s: attempt to free a non-existent or already freed string", prog->name);
if (!prog->knownstrings_flags[num])
- prog->error_cmd("PRVM_FreeString: attempt to free a string owned by the engine");
+ prog->error_cmd("PRVM_FreeString %s: attempt to free a string owned by the engine", prog->name);
PRVM_Free((char *)prog->knownstrings[num]);
if(prog->leaktest_active)
if(prog->knownstrings_origin[num])
prog->firstfreeknownstring = min(prog->firstfreeknownstring, num);
}
else
- prog->error_cmd("PRVM_FreeString: invalid string offset %i", num);
+ prog->error_cmd("PRVM_FreeString %s: invalid string offset %i", prog->name, num);
}
static qbool PRVM_IsStringReferenced(prvm_prog_t *prog, string_t string)