PRVM_GCALL(init_edict)(e);
}
-const char *PRVM_AllocationOrigin()
+const char *PRVM_AllocationOrigin(void)
{
char *buf = NULL;
if(prog->leaktest_active)
prog->fieldoffsets.viewmodelforclient = PRVM_ED_FindFieldOffset("viewmodelforclient");
prog->fieldoffsets.viewzoom = PRVM_ED_FindFieldOffset("viewzoom");
prog->fieldoffsets.yaw_speed = PRVM_ED_FindFieldOffset("yaw_speed");
+ prog->fieldoffsets.bouncefactor = PRVM_ED_FindFieldOffset("bouncefactor");
+ prog->fieldoffsets.bouncestop = PRVM_ED_FindFieldOffset("bouncestop");
prog->funcoffsets.CSQC_ConsoleCommand = PRVM_ED_FindFunctionOffset("CSQC_ConsoleCommand");
prog->funcoffsets.CSQC_Ent_Remove = PRVM_ED_FindFunctionOffset("CSQC_Ent_Remove");
prog->funcoffsets.CSQC_Ent_Spawn = PRVM_ED_FindFunctionOffset("CSQC_Ent_Spawn");
===============
*/
-void PRVM_LeakTest();
-void PRVM_ResetProg()
+void PRVM_LeakTest(void);
+void PRVM_ResetProg(void)
{
PRVM_LeakTest();
PRVM_GCALL(reset_cmd)();
prog->progs = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false, &filesize);
if (prog->progs == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME);
+ // TODO bounds check header fields (e.g. numstatements), they must never go behind end of file
Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, (int)(filesize/1024));
prog->functions[i].numparms = LittleLong (dfunctions[i].numparms);
prog->functions[i].locals = LittleLong (dfunctions[i].locals);
memcpy(prog->functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
+ if(prog->functions[i].first_statement >= prog->progs->numstatements)
+ PRVM_ERROR("PRVM_LoadProgs: out of bounds function statement (function %d) in %s", i, PRVM_NAME);
+ // TODO bounds check parm_start, s_name, s_file, numparms, locals, parm_size
}
for (i=0 ; i<prog->progs->numglobaldefs ; i++)
prog->globaldefs[i].type = LittleShort (prog->globaldefs[i].type);
prog->globaldefs[i].ofs = LittleShort (prog->globaldefs[i].ofs);
prog->globaldefs[i].s_name = LittleLong (prog->globaldefs[i].s_name);
+ // TODO bounds check ofs, s_name
}
// copy the progs fields to the new fields list
PRVM_ERROR ("PRVM_LoadProgs: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", PRVM_NAME);
prog->fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
prog->fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
+ // TODO bounds check ofs, s_name
}
// append the required fields
prog->fielddefs[prog->progs->numfielddefs].type = required_field[i].type;
prog->fielddefs[prog->progs->numfielddefs].ofs = prog->progs->entityfields;
prog->fielddefs[prog->progs->numfielddefs].s_name = PRVM_SetEngineString(required_field[i].name);
+ // TODO bounds check ofs, s_name
if (prog->fielddefs[prog->progs->numfielddefs].type == ev_vector)
prog->progs->entityfields += 3;
else
break;
}
}
+ if(prog->progs->numstatements < 1)
+ {
+ PRVM_ERROR("PRVM_LoadProgs: empty program in %s", PRVM_NAME);
+ }
+ else switch(prog->statements[prog->progs->numstatements - 1].op)
+ {
+ case OP_RETURN:
+ case OP_GOTO:
+ case OP_DONE:
+ break;
+ default:
+ PRVM_ERROR("PRVM_LoadProgs: program may fall off the edge (does not end with RETURN, GOTO or DONE) in %s", PRVM_NAME);
+ break;
+ }
PRVM_LoadLNO(filename);
prog->leaktest_active = prvm_leaktest.integer;
}
-int PRVM_GetProgNr()
+int PRVM_GetProgNr(void)
{
return prog - prog_list;
}
if (num < prog->numknownstrings)
{
if (!prog->knownstrings[num])
+ {
VM_Warning("PRVM_GetString: Invalid zone-string offset (%i has been freed)\n", num);
+ return "";
+ }
return prog->knownstrings[num];
}
else
return false;
}
-static void PRVM_MarkReferencedEdicts()
+static void PRVM_MarkReferencedEdicts(void)
{
int j;
qboolean found_new;
Con_DPrintf("leak check used %d stages to find all references\n", stage);
}
-void PRVM_LeakTest()
+void PRVM_LeakTest(void)
{
int i, j;
qboolean leaked = false;