diff --git a/UnitystationLauncher/ContentScanning/Scanners/MemberReferenceScanner.cs b/UnitystationLauncher/ContentScanning/Scanners/MemberReferenceScanner.cs index bd3b8f8..6ae9a86 100644 --- a/UnitystationLauncher/ContentScanning/Scanners/MemberReferenceScanner.cs +++ b/UnitystationLauncher/ContentScanning/Scanners/MemberReferenceScanner.cs @@ -12,31 +12,17 @@ namespace UnitystationLauncher.ContentScanning.Scanners; internal static class MemberReferenceScanner { // Using the Parallel implementation of this - internal static void CheckMemberReferences(SandboxConfig sandboxConfig, List members, ConcurrentBag errors) + internal static void CheckMemberReferences(SandboxConfig sandboxConfig, IEnumerable members, ConcurrentBag errors) { Parallel.ForEach(members, memberRef => { - MType baseType = memberRef.ParentType; - while (baseType is not MTypeReferenced) + MTypeReferenced? baseTypeReferenced = GetBaseMTypeReferenced(memberRef); + + if (baseTypeReferenced == null) { - switch (baseType) - { - case MTypeGeneric generic: - baseType = generic.GenericType; - - break; - // Members on arrays (not to be confused with vectors) are all fine. - // See II.14.2 in ECMA-335. - case MTypeWackyArray: - // Valid for this to show up, safe to ignore. - case MTypeDefined: - return; - default: throw new ArgumentOutOfRangeException(); - } + return; } - MTypeReferenced baseTypeReferenced = (MTypeReferenced)baseType; - if (baseTypeReferenced.IsTypeAccessAllowed(sandboxConfig, out TypeConfig? typeCfg) == false) { // Technically this error isn't necessary since we have an earlier pass @@ -52,19 +38,24 @@ internal static void CheckMemberReferences(SandboxConfig sandboxConfig, List - field.Name == mMemberRefField.Name - && mMemberRefField.FieldType.WhitelistEquals(field.FieldType))) - { - return; // Found - } + CheckMemberRefType(memberRef, typeCfg, errors); + }); - errors.Add(new($"Access to field not allowed: {mMemberRefField}")); - break; - case MMemberRefMethod mMemberRefMethod: + } + + private static void CheckMemberRefType(MMemberRef memberRef, TypeConfig typeCfg, ConcurrentBag errors) + { + switch (memberRef) + { + case MMemberRefField mMemberRefField + when typeCfg.FieldsParsed.Any(field => field.Name == mMemberRefField.Name + && mMemberRefField.FieldType.WhitelistEquals(field.FieldType)): + return; // Found + case MMemberRefField mMemberRefField: + errors.Add(new($"Access to field not allowed: {mMemberRefField}")); + return; + case MMemberRefMethod mMemberRefMethod: + { foreach (WhitelistMethodDefine parsed in typeCfg.MethodsParsed) { bool paramMismatch = false; @@ -98,11 +89,35 @@ internal static void CheckMemberReferences(SandboxConfig sandboxConfig, List