sanitize the progs.dat loader

master
an 2019-12-05 20:53:00 -05:00
parent 163560269a
commit 9ba9da23f0
2 changed files with 150 additions and 98 deletions

View File

@ -37,36 +37,156 @@ cvar_t saved2 = {"saved2", "0", CVAR_ARCHIVE};
cvar_t saved3 = {"saved3", "0", CVAR_ARCHIVE};
cvar_t saved4 = {"saved4", "0", CVAR_ARCHIVE};
static void PR_LoadProgHeader(byte *prog_data)
static void PR_LoadProgHeader(byte const *data)
{
progs.version = ReadLittleLong(&prog_data[4 * 0]);
progs.crc = ReadLittleLong(&prog_data[4 * 1]);
progs.version = ReadLittleLong(&data);
progs.crc = ReadLittleLong(&data);
progs.ofs_statements = ReadLittleLong(&prog_data[4 * 2]);
progs.numstatements = ReadLittleLong(&prog_data[4 * 3]);
progs.ofs_statements = ReadLittleLong(&data);
progs.numstatements = ReadLittleLong(&data);
progs.ofs_globaldefs = ReadLittleLong(&prog_data[4 * 4]);
progs.numglobaldefs = ReadLittleLong(&prog_data[4 * 5]);
progs.ofs_globaldefs = ReadLittleLong(&data);
progs.numglobaldefs = ReadLittleLong(&data);
progs.ofs_fielddefs = ReadLittleLong(&prog_data[4 * 6]);
progs.numfielddefs = ReadLittleLong(&prog_data[4 * 7]);
progs.ofs_fielddefs = ReadLittleLong(&data);
progs.numfielddefs = ReadLittleLong(&data);
progs.ofs_functions = ReadLittleLong(&prog_data[4 * 8]);
progs.numfunctions = ReadLittleLong(&prog_data[4 * 9]);
progs.ofs_functions = ReadLittleLong(&data);
progs.numfunctions = ReadLittleLong(&data);
progs.ofs_strings = ReadLittleLong(&prog_data[4 * 10]);
progs.numstrings = ReadLittleLong(&prog_data[4 * 11]);
progs.ofs_strings = ReadLittleLong(&data);
progs.numstrings = ReadLittleLong(&data);
progs.ofs_globals = ReadLittleLong(&prog_data[4 * 12]);
progs.numglobals = ReadLittleLong(&prog_data[4 * 13]);
progs.ofs_globals = ReadLittleLong(&data);
progs.numglobals = ReadLittleLong(&data);
progs.entityfields = ReadLittleLong(&prog_data[4 * 14]);
progs.entityfields = ReadLittleLong(&data);
/* round off to next highest whole word address (esp for Alpha) this ensures
* that pointers in the engine data area are always properly aligned
*/
pr_edict_size = progs.entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t);
pr_edict_size += sizeof(void *) - 1;
pr_edict_size &= ~(sizeof(void *) - 1);
if(progs.version != PROG_VERSION)
Host_Error("progs.dat has wrong version number (%" PRIi32 " should be %" PRIi32 ")", progs.version, PROG_VERSION);
Host_Error("PR_LoadProgHeader: has wrong version number (%" PRIi32 " should be %" PRIi32 ")", progs.version, PROG_VERSION);
if(progs.crc != PROGHEADER_CRC)
Host_Error("progs.dat system vars have been modified, progdefs.h is out of date");
Host_Error("PR_LoadProgHeader: system vars have been modified, progdefs.h is out of date");
if(progs.ofs_strings + progs.numstrings >= com_filesize)
Host_Error("PR_LoadProgHeader: strings go past end of file\n");
}
static void PR_LoadFunctions(byte const *data)
{
int32_t i;
pr_functions = Hunk_AllocName(sizeof(*pr_functions) * progs.numfunctions,
"pr_functions");
for(i = 0; i < progs.numfunctions; i++)
{
pr_functions[i].first_statement = ReadLittleLong(&data);
pr_functions[i].parm_start = ReadLittleLong(&data);
pr_functions[i].locals = ReadLittleLong(&data);
pr_functions[i].profile = 0; ReadSkip(&data, 4);
pr_functions[i].s_name = ReadLittleLong(&data);
pr_functions[i].s_file = ReadLittleLong(&data);
pr_functions[i].numparms = ReadLittleLong(&data);
ReadCopy(pr_functions[i].parm_size, &data, 8);
}
}
static void PR_LoadStrings(byte const *data)
{
pr_strings = Hunk_Memdup(data, progs.numstrings, "pr_strings");
// initialize the strings
pr_numknownstrings = 0;
pr_maxknownstrings = 0;
if(pr_knownstrings)
Z_Free(pr_knownstrings);
pr_knownstrings = NULL;
PR_SetEngineString("");
}
static void PR_LoadDef(ddef_t *def, byte const **data)
{
def->type = ReadLittleShort(data);
def->ofs = ReadLittleShort(data);
def->s_name = ReadLittleLong(data);
}
static void PR_LoadGlobalDefs(byte const *data)
{
int32_t i;
pr_globaldefs = Hunk_AllocName(sizeof(*pr_globaldefs) * progs.numglobaldefs,
"pr_globaldefs");
for(i = 0; i < progs.numglobaldefs; i++)
{
PR_LoadDef(&pr_globaldefs[i], &data);
}
}
static void PR_LoadFieldDefs(byte const *data)
{
int32_t i;
pr_fielddefs = Hunk_AllocName(sizeof(*pr_fielddefs) * progs.numfielddefs,
"pr_fielddefs");
pr_alpha_supported = false; //johnfitz
for(i = 0; i < progs.numfielddefs; i++)
{
PR_LoadDef(&pr_fielddefs[i], &data);
if(pr_fielddefs[i].type & DEF_SAVEGLOBAL)
Host_Error("PR_LoadProgs: field defs cannot have DEF_SAVEGLOBAL");
//johnfitz -- detect alpha support
if(!strcmp(&pr_strings[pr_fielddefs[i].s_name], "alpha"))
pr_alpha_supported = true;
//johnfitz
}
}
static void PR_LoadStatements(byte const *data)
{
int32_t i;
pr_statements = Hunk_AllocName(sizeof(*pr_statements) * progs.numstatements,
"pr_statements");
for(i = 0; i < progs.numstatements; i++)
{
pr_statements[i].op = ReadLittleShort(&data);
pr_statements[i].a = ReadLittleShort(&data);
pr_statements[i].b = ReadLittleShort(&data);
pr_statements[i].c = ReadLittleShort(&data);
}
}
static void PR_LoadGlobals(byte const *data)
{
int32_t i;
// HACK
pr_global_struct = Hunk_Memdup(data, progs.numglobals * 4, "pr_global_struct");
/*
pr_global_struct = Hunk_AllocName(sizeof(*pr_global_struct),
"pr_global_struct");
*/
pr_globals = (float *)pr_global_struct;
for(i = 0; i < progs.numglobals; i++)
pr_globals[i] = LittleFloat(pr_globals[i]);
}
/*
@ -83,87 +203,21 @@ void PR_LoadProgs(void)
CRC_Init(&pr_crc);
prog_data = COM_LoadHunkFile("progs.dat", NULL);
prog_data = COM_LoadTempFile("progs.dat", NULL);
if(!prog_data)
Host_Error("PR_LoadProgs: couldn't load progs.dat");
Con_DPrintf("Programs occupy %" PRIi32 "K.\n", com_filesize / 1024);
Con_DPrintf("Programs occupy %" PRIi32 "K\n", com_filesize / 1024);
for(i = 0; i < com_filesize; i++)
CRC_ProcessByte(&pr_crc, prog_data[i]);
PR_LoadProgHeader(prog_data);
pr_functions = (dfunction_t *)&prog_data[progs.ofs_functions];
pr_strings = (char const *)&prog_data[progs.ofs_strings];
if(progs.ofs_strings + progs.numstrings >= com_filesize)
Host_Error("progs.dat strings go past end of file\n");
// initialize the strings
pr_numknownstrings = 0;
pr_maxknownstrings = 0;
if(pr_knownstrings)
Z_Free(pr_knownstrings);
pr_knownstrings = NULL;
PR_SetEngineString("");
pr_globaldefs = (ddef_t *)&prog_data[progs.ofs_globaldefs];
pr_fielddefs = (ddef_t *)&prog_data[progs.ofs_fielddefs];
pr_statements = (dstatement_t *)&prog_data[progs.ofs_statements];
pr_global_struct = (globalvars_t *)&prog_data[progs.ofs_globals];
pr_globals = (float *)pr_global_struct;
// byte swap the lumps
for(i = 0; i < progs.numstatements; i++)
{
pr_statements[i].op = LittleShort(pr_statements[i].op);
pr_statements[i].a = LittleShort(pr_statements[i].a);
pr_statements[i].b = LittleShort(pr_statements[i].b);
pr_statements[i].c = LittleShort(pr_statements[i].c);
}
for(i = 0; i < progs.numfunctions; i++)
{
pr_functions[i].first_statement = LittleLong(pr_functions[i].first_statement);
pr_functions[i].parm_start = LittleLong(pr_functions[i].parm_start);
pr_functions[i].s_name = LittleLong(pr_functions[i].s_name);
pr_functions[i].s_file = LittleLong(pr_functions[i].s_file);
pr_functions[i].numparms = LittleLong(pr_functions[i].numparms);
pr_functions[i].locals = LittleLong(pr_functions[i].locals);
}
for(i = 0; i < progs.numglobaldefs; i++)
{
pr_globaldefs[i].type = LittleShort(pr_globaldefs[i].type);
pr_globaldefs[i].ofs = LittleShort(pr_globaldefs[i].ofs);
pr_globaldefs[i].s_name = LittleLong(pr_globaldefs[i].s_name);
}
pr_alpha_supported = false; //johnfitz
for(i = 0; i < progs.numfielddefs; i++)
{
pr_fielddefs[i].type = LittleShort(pr_fielddefs[i].type);
if(pr_fielddefs[i].type & DEF_SAVEGLOBAL)
Host_Error("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
pr_fielddefs[i].ofs = LittleShort(pr_fielddefs[i].ofs);
pr_fielddefs[i].s_name = LittleLong(pr_fielddefs[i].s_name);
//johnfitz -- detect alpha support
if(!strcmp(pr_strings + pr_fielddefs[i].s_name, "alpha"))
pr_alpha_supported = true;
//johnfitz
}
for(i = 0; i < progs.numglobals; i++)
((int32_t *)pr_globals)[i] = LittleLong(((int32_t *)pr_globals)[i]);
pr_edict_size = progs.entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t);
// round off to next highest whole word address (esp for Alpha)
// this ensures that pointers in the engine data area are always
// properly aligned
pr_edict_size += sizeof(void *) - 1;
pr_edict_size &= ~(sizeof(void *) - 1);
PR_LoadStrings(&prog_data[progs.ofs_strings]);
PR_LoadStatements(&prog_data[progs.ofs_statements]);
PR_LoadFunctions(&prog_data[progs.ofs_functions]);
PR_LoadGlobalDefs(&prog_data[progs.ofs_globaldefs]);
PR_LoadFieldDefs(&prog_data[progs.ofs_fielddefs]);
PR_LoadGlobals(&prog_data[progs.ofs_globals]);
}

View File

@ -189,13 +189,11 @@ const char *PR_GlobalStringNoContents(int32_t ofs)
//===========================================================================
#define PR_STRING_ALLOCSLOTS 256
static void PR_AllocStringSlots(void)
{
pr_maxknownstrings += PR_STRING_ALLOCSLOTS;
pr_maxknownstrings += 256;
Con_DPrintf2("PR_AllocStringSlots: realloc'ing for %" PRIi32 " slots\n", pr_maxknownstrings);
pr_knownstrings = (const char **) Z_Realloc(pr_knownstrings, pr_maxknownstrings * sizeof(char *));
pr_knownstrings = Z_Realloc(pr_knownstrings, pr_maxknownstrings * sizeof(*pr_knownstrings));
}
const char *PR_GetString(int32_t num)
@ -206,7 +204,7 @@ const char *PR_GetString(int32_t num)
{
if(!pr_knownstrings[-1 - num])
{
Host_Error("PR_GetString: attempt to get a non-existant string %" PRIi32 "\n", num);
Host_Error("PR_GetString: attempt to get a non-existent string %" PRIi32 "\n", num);
return "";
}
return pr_knownstrings[-1 - num];
@ -220,7 +218,7 @@ const char *PR_GetString(int32_t num)
int32_t PR_SetEngineString(const char *s)
{
int32_t i;
int32_t i;
if(!s)
return 0;