From 1832531726082e6680061ce1203ba8d0815f2115 Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sun, 5 Mar 2017 01:47:01 +0200 Subject: [PATCH] Fixed: check protected fields against analog of OwningClass in functions, as opposed to the type that the field was accessed from. --- src/scripting/backend/codegen.cpp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 9f7da15c4d..859b5b4c1d 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -6084,10 +6084,34 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct } PClass* cls_ctx = dyn_cast(classctx); PClass* cls_target = dyn_cast(objtype); - if ((vsym->Flags & VARF_Protected) && (!cls_ctx || !cls_target || !cls_ctx->IsDescendantOf(cls_target))) + // [ZZ] neither PSymbol, PField or PSymbolTable have the necessary information. so we need to do the more complex check here. + if (vsym->Flags & VARF_Protected) { - ScriptPosition.Message(MSG_ERROR, "Protected member %s not accessible", vsym->SymbolName.GetChars()); - return nullptr; + // early break. + if (!cls_ctx || !cls_target) + { + ScriptPosition.Message(MSG_ERROR, "Protected member %s not accessible", vsym->SymbolName.GetChars()); + return nullptr; + } + + // find the class that declared this field. + PClass* p = cls_target; + while (p) + { + if (&p->Symbols == symtbl) + { + cls_target = p; + break; + } + + p = p->ParentClass; + } + + if (!cls_ctx->IsDescendantOf(cls_target)) + { + ScriptPosition.Message(MSG_ERROR, "Protected member %s not accessible", vsym->SymbolName.GetChars()); + return nullptr; + } } auto x = isclass ? new FxClassMember(object, vsym, ScriptPosition) : new FxStructMember(object, vsym, ScriptPosition);