From 421f78c771c12e2e030b70197fa08953c6ba245e Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Fri, 3 Mar 2017 22:52:35 +0200 Subject: [PATCH] Fixed potential crash with new() in anonymous functions (is that even allowed?); Added compile-time check for disallowed new() --- src/scripting/backend/codegen.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 1700dd3e6..dca4fdbf1 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -99,7 +99,9 @@ static const FLOP FxFlops[] = // this can be imported in vmexec.h void FScopeBarrier_ValidateNew(PClass* cls, PFunction* callingfunc) { - int outerside = FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags); + int outerside = callingfunc->Variants.Size() ? FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags) : FScopeBarrier::Side_Virtual; + if (outerside == FScopeBarrier::Side_Virtual) + outerside = FScopeBarrier::SideFromObjectFlags(callingfunc->OwningClass->ObjectFlags); int innerside = FScopeBarrier::SideFromObjectFlags(cls->ObjectFlags); if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData)) // "cannot construct ui class ... from data context" ThrowAbortException(X_OTHER, "Cannot construct %s class %s from %s context", FScopeBarrier::StringFromSide(innerside), cls->TypeName.GetChars(), FScopeBarrier::StringFromSide(outerside)); @@ -5095,6 +5097,18 @@ FxExpression *FxNew::Resolve(FCompileContext &ctx) return nullptr; } + // + int outerside = ctx.Function && ctx.Function->Variants.Size() ? FScopeBarrier::SideFromFlags(ctx.Function->Variants[0].Flags) : FScopeBarrier::Side_Virtual; + if (outerside == FScopeBarrier::Side_Virtual) + outerside = FScopeBarrier::SideFromObjectFlags(ctx.Class->ObjectFlags); + int innerside = FScopeBarrier::SideFromObjectFlags(cls->ObjectFlags); + if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData)) // "cannot construct ui class ... from data context" + { + ScriptPosition.Message(MSG_ERROR, "Cannot construct %s class %s from %s context", FScopeBarrier::StringFromSide(innerside), cls->TypeName.GetChars(), FScopeBarrier::StringFromSide(outerside)); + delete this; + return nullptr; + } + ValueType = NewPointer(cls); }