Fixed: the game could crash while resolving expressions in some places

This commit is contained in:
Leonard2 2016-08-04 19:58:57 +02:00 committed by Christoph Oelckers
parent 4a859393fe
commit 73d0ed78fe
2 changed files with 40 additions and 17 deletions

View file

@ -361,16 +361,20 @@ static void FinishThingdef()
if (sfunc == NULL) if (sfunc == NULL)
{ {
FCompileContext ctx(ti); FCompileContext ctx(ti);
dmg->Resolve(ctx); dmg = static_cast<FxDamageValue *>(dmg->Resolve(ctx));
VMFunctionBuilder buildit;
buildit.Registers[REGT_POINTER].Get(1); // The self pointer if (dmg != nullptr)
dmg->Emit(&buildit); {
sfunc = buildit.MakeFunction(); VMFunctionBuilder buildit;
sfunc->NumArgs = 1; buildit.Registers[REGT_POINTER].Get(1); // The self pointer
sfunc->Proto = NULL; ///FIXME: Need a proper prototype here dmg->Emit(&buildit);
// Save this function in case this damage value was reused sfunc = buildit.MakeFunction();
// (which happens quite easily with inheritance). sfunc->NumArgs = 1;
dmg->SetFunction(sfunc); sfunc->Proto = NULL; ///FIXME: Need a proper prototype here
// Save this function in case this damage value was reused
// (which happens quite easily with inheritance).
dmg->SetFunction(sfunc);
}
} }
def->Damage = sfunc; def->Damage = sfunc;

View file

@ -191,7 +191,12 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
FxExpression *expr = ParseExpression (sc, cls, true); FxExpression *expr = ParseExpression (sc, cls, true);
sc.MustGetToken(';'); sc.MustGetToken(';');
if (!expr->isConstant()) if (expr == nullptr)
{
sc.ScriptMessage("Error while resolving constant definition");
FScriptPosition::ErrorCounter++;
}
else if (!expr->isConstant())
{ {
sc.ScriptMessage("Constant definition is not a constant"); sc.ScriptMessage("Constant definition is not a constant");
FScriptPosition::ErrorCounter++; FScriptPosition::ErrorCounter++;
@ -247,16 +252,24 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
if (sc.CheckToken('=')) if (sc.CheckToken('='))
{ {
FxExpression *expr = ParseExpression (sc, cls, true); FxExpression *expr = ParseExpression (sc, cls, true);
if (!expr->isConstant()) if (expr != nullptr)
{ {
sc.ScriptMessage("'%s' must be constant", symname.GetChars()); if (!expr->isConstant())
FScriptPosition::ErrorCounter++; {
sc.ScriptMessage("'%s' must be constant", symname.GetChars());
FScriptPosition::ErrorCounter++;
}
else
{
currvalue = static_cast<FxConstant *>(expr)->GetValue().GetInt();
}
delete expr;
} }
else else
{ {
currvalue = static_cast<FxConstant *>(expr)->GetValue().GetInt(); sc.ScriptMessage("Error while resolving expression of '%s'", symname.GetChars());
FScriptPosition::ErrorCounter++;
} }
delete expr;
} }
PSymbolConstNumeric *sym = new PSymbolConstNumeric(symname, TypeSInt32); PSymbolConstNumeric *sym = new PSymbolConstNumeric(symname, TypeSInt32);
sym->Value = currvalue; sym->Value = currvalue;
@ -568,7 +581,13 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl
if (sc.CheckToken('[')) if (sc.CheckToken('['))
{ {
FxExpression *expr = ParseExpression(sc, cls, true); FxExpression *expr = ParseExpression(sc, cls, true);
if (!expr->isConstant()) if (expr == nullptr)
{
sc.ScriptMessage("Error while resolving array size");
FScriptPosition::ErrorCounter++;
maxelems = 1;
}
else if (!expr->isConstant())
{ {
sc.ScriptMessage("Array size must be a constant"); sc.ScriptMessage("Array size must be a constant");
FScriptPosition::ErrorCounter++; FScriptPosition::ErrorCounter++;