]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_edict.c
Quake menu: show DP's weird resolution set in windowed mode, and really detected...
[xonotic/darkplaces.git] / prvm_edict.c
index e0f3773275c14789a983cb7dbdab01e7e6a06aa6..456ffb5bedc7dcacd1e30cabadaaa3bc1d714c26 100644 (file)
@@ -224,7 +224,7 @@ void PRVM_ED_ClearEdict (prvm_edict_t *e)
        PRVM_GCALL(init_edict)(e);
 }
 
-const char *PRVM_AllocationOrigin()
+const char *PRVM_AllocationOrigin(void)
 {
        char *buf = NULL;
        if(prog->leaktest_active)
@@ -1630,8 +1630,8 @@ PRVM_ResetProg
 ===============
 */
 
-void PRVM_LeakTest();
-void PRVM_ResetProg()
+void PRVM_LeakTest(void);
+void PRVM_ResetProg(void)
 {
        PRVM_LeakTest();
        PRVM_GCALL(reset_cmd)();
@@ -1707,6 +1707,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
        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));
 
@@ -1772,6 +1773,9 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                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++)
@@ -1779,6 +1783,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                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
@@ -1789,6 +1794,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                        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
@@ -1797,6 +1803,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                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
@@ -1920,6 +1927,20 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                        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);
 
@@ -2217,7 +2238,7 @@ void PRVM_InitProg(int prognr)
        prog->leaktest_active = prvm_leaktest.integer;
 }
 
-int PRVM_GetProgNr()
+int PRVM_GetProgNr(void)
 {
        return prog - prog_list;
 }
@@ -2338,7 +2359,10 @@ const char *PRVM_GetString(int num)
                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
@@ -2651,7 +2675,7 @@ static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict, int mark)
        return false;
 }
 
-static void PRVM_MarkReferencedEdicts()
+static void PRVM_MarkReferencedEdicts(void)
 {
        int j;
        qboolean found_new;
@@ -2688,7 +2712,7 @@ static void PRVM_MarkReferencedEdicts()
        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;