bool IsMemberWhitelisted(ISymbol memberSymbol, MyWhitelistTarget target) { while (true) { if (target == MyWhitelistTarget.Ingame && IsBlacklisted(memberSymbol)) { return(false); } var result = IsWhitelisted(memberSymbol.ContainingType, target); if (result == TypeKeyQuantity.AllMembers) { return(true); } MyWhitelistTarget allowedTarget; if (m_whitelist.TryGetValue(memberSymbol.GetWhitelistKey(TypeKeyQuantity.ThisOnly), out allowedTarget) && allowedTarget.HasFlag(target)) { return(true); } if (memberSymbol.IsOverride) { memberSymbol = memberSymbol.GetOverriddenSymbol(); if (memberSymbol != null) { continue; } } return(false); } }
void Register(MyWhitelistTarget target, INamespaceSymbol symbol, Type type) { var whitelistKey = symbol.GetWhitelistKey(TypeKeyQuantity.AllMembers); if (m_whitelist.ContainsKey(whitelistKey)) { throw new MyWhitelistException("Duplicate registration of the whitelist key " + whitelistKey + " retrieved from " + type); } m_whitelist.Add(whitelistKey, target); }
TypeKeyQuantity IsWhitelisted(INamespaceSymbol namespaceSymbol, MyWhitelistTarget target) { MyWhitelistTarget allowedTarget; if (m_whitelist.TryGetValue(namespaceSymbol.GetWhitelistKey(TypeKeyQuantity.AllMembers), out allowedTarget) && allowedTarget.HasFlag(target)) { return(TypeKeyQuantity.AllMembers); } return(TypeKeyQuantity.None); }
void RegisterMember(MyWhitelistTarget target, ISymbol symbol, MemberInfo member) { if (!(symbol is IEventSymbol || symbol is IFieldSymbol || symbol is IPropertySymbol || symbol is IMethodSymbol)) { throw new MyWhitelistException("Unsupported symbol type " + symbol); } var namespaceSymbol = symbol.ContainingNamespace; if (namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace) { var namespaceKey = namespaceSymbol.GetWhitelistKey(TypeKeyQuantity.AllMembers); MyWhitelistTarget existingTarget; if (m_whitelist.TryGetValue(namespaceKey, out existingTarget) && existingTarget >= target) { throw new MyWhitelistException("The member " + member + " is covered by the " + namespaceKey + " rule"); } } var typeSymbol = symbol.ContainingType; while (typeSymbol != null) { var typeKey = typeSymbol.GetWhitelistKey(TypeKeyQuantity.AllMembers); MyWhitelistTarget existingTarget; if (m_whitelist.TryGetValue(typeKey, out existingTarget) && existingTarget >= target) { throw new MyWhitelistException("The member " + member + " is covered by the " + typeKey + " rule"); } // If there is no previous registration of the containing type, or the current registration // is less restrictive than the one we're currently asking for, it needs to be updated. // (this will only allow the reference of a type, but none of its members). typeKey = typeSymbol.GetWhitelistKey(TypeKeyQuantity.ThisOnly); if (!m_whitelist.TryGetValue(typeKey, out existingTarget) || existingTarget < target) { m_whitelist[typeKey] = target; } typeSymbol = typeSymbol.ContainingType; } var whitelistKey = symbol.GetWhitelistKey(TypeKeyQuantity.ThisOnly); if (m_whitelist.ContainsKey(whitelistKey)) { throw new MyWhitelistException("Duplicate registration of the whitelist key " + whitelistKey + " retrieved from " + member); } m_whitelist.Add(whitelistKey, target); }
internal bool IsWhitelisted(ISymbol symbol, MyWhitelistTarget target) { var typeSymbol = symbol as INamedTypeSymbol; if (typeSymbol != null) { return(IsWhitelisted(typeSymbol, target) != TypeKeyQuantity.None); } if (symbol.IsMemberSymbol()) { return(IsMemberWhitelisted(symbol, target)); } // This is not a symbol we need concern ourselves with. return(true); }
/// <summary> /// Adds one or more specific types and all their members to the whitelist. /// </summary> /// <param name="target"></param> /// <param name="types"></param> public void AllowTypes(MyWhitelistTarget target, params Type[] types) { if (types.IsNullOrEmpty()) { throw new MyWhitelistException("Needs at least one type"); } AssertVitality(); for (var index = 0; index < types.Length; index++) { var type = types[index]; if (type == null) { throw new MyWhitelistException("The type in index " + index + " is null"); } var typeSymbol = ResolveTypeSymbol(type); Whitelist.Register(target, typeSymbol, type); } }
void Register(MyWhitelistTarget target, ITypeSymbol symbol, Type type) { var namespaceSymbol = symbol.ContainingNamespace; if (namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace) { var namespaceKey = namespaceSymbol.GetWhitelistKey(TypeKeyQuantity.AllMembers); MyWhitelistTarget existingTarget; if (m_whitelist.TryGetValue(namespaceKey, out existingTarget) && existingTarget >= target) { throw new MyWhitelistException("The type " + type + " is covered by the " + namespaceKey + " rule"); } } var whitelistKey = symbol.GetWhitelistKey(TypeKeyQuantity.AllMembers); if (m_whitelist.ContainsKey(whitelistKey)) { throw new MyWhitelistException("Duplicate registration of the whitelist key " + whitelistKey + " retrieved from " + type); } m_whitelist.Add(whitelistKey, target); }
TypeKeyQuantity IsWhitelisted(INamedTypeSymbol typeSymbol, MyWhitelistTarget target) { // Delegates are allowed directly in checking, as they are harmless since you have to call // or store something in it which is also checked. if (IsDelegate(typeSymbol)) { return(TypeKeyQuantity.AllMembers); } if (target == MyWhitelistTarget.Ingame && IsBlacklisted(typeSymbol)) { return(TypeKeyQuantity.None); } var result = IsWhitelisted(typeSymbol.ContainingNamespace, target); if (result == TypeKeyQuantity.AllMembers) { return(result); } MyWhitelistTarget allowedTarget; if (m_whitelist.TryGetValue(typeSymbol.GetWhitelistKey(TypeKeyQuantity.AllMembers), out allowedTarget) && allowedTarget.HasFlag(target)) { return(TypeKeyQuantity.AllMembers); } if (m_whitelist.TryGetValue(typeSymbol.GetWhitelistKey(TypeKeyQuantity.ThisOnly), out allowedTarget) && allowedTarget.HasFlag(target)) { return(TypeKeyQuantity.ThisOnly); } return(TypeKeyQuantity.None); }
/// <summary> /// Adds the entire namespace of one or more given types. /// </summary> /// <param name="target"></param> /// <param name="types"></param> public void AllowNamespaceOfTypes(MyWhitelistTarget target, params Type[] types) { if (types.IsNullOrEmpty()) { throw new MyWhitelistException("Needs at least one type"); } AssertVitality(); for (var index = 0; index < types.Length; index++) { var type = types[index]; if (type == null) { throw new MyWhitelistException("The type in index " + index + " is null"); } var typeSymbol = ResolveTypeSymbol(type); var namespaceSymbol = typeSymbol.ContainingNamespace; if (namespaceSymbol == null || namespaceSymbol.IsGlobalNamespace) { continue; } Whitelist.Register(target, namespaceSymbol, type); } }
bool IsMemberWhitelisted(ISymbol memberSymbol, MyWhitelistTarget target) { while (true) { if (target == MyWhitelistTarget.Ingame && IsBlacklisted(memberSymbol)) { return false; } var result = IsWhitelisted(memberSymbol.ContainingType, target); if (result == TypeKeyQuantity.AllMembers) { return true; } MyWhitelistTarget allowedTarget; if (m_whitelist.TryGetValue(memberSymbol.GetWhitelistKey(TypeKeyQuantity.ThisOnly), out allowedTarget) && allowedTarget.HasFlag(target)) { return true; } if (memberSymbol.IsOverride) { memberSymbol = memberSymbol.GetOverriddenSymbol(); if (memberSymbol != null) { continue; } } return false; } }
TypeKeyQuantity IsWhitelisted(INamedTypeSymbol typeSymbol, MyWhitelistTarget target) { // Delegates are allowed directly in checking, as they are harmless since you have to call // or store something in it which is also checked. if (IsDelegate(typeSymbol)) { return TypeKeyQuantity.AllMembers; } if (target == MyWhitelistTarget.Ingame && IsBlacklisted(typeSymbol)) { return TypeKeyQuantity.None; } var result = IsWhitelisted(typeSymbol.ContainingNamespace, target); if (result == TypeKeyQuantity.AllMembers) { return result; } MyWhitelistTarget allowedTarget; if (m_whitelist.TryGetValue(typeSymbol.GetWhitelistKey(TypeKeyQuantity.AllMembers), out allowedTarget) && allowedTarget.HasFlag(target)) { return TypeKeyQuantity.AllMembers; } if (m_whitelist.TryGetValue(typeSymbol.GetWhitelistKey(TypeKeyQuantity.ThisOnly), out allowedTarget) && allowedTarget.HasFlag(target)) { return TypeKeyQuantity.ThisOnly; } return TypeKeyQuantity.None; }
TypeKeyQuantity IsWhitelisted(INamespaceSymbol namespaceSymbol, MyWhitelistTarget target) { MyWhitelistTarget allowedTarget; if (m_whitelist.TryGetValue(namespaceSymbol.GetWhitelistKey(TypeKeyQuantity.AllMembers), out allowedTarget) && allowedTarget.HasFlag(target)) { return TypeKeyQuantity.AllMembers; } return TypeKeyQuantity.None; }
/// <summary> /// Adds only the specified members to the whitelist. /// </summary> /// <param name="target"></param> /// <param name="members"></param> public void AllowMembers(MyWhitelistTarget target, params MemberInfo[] members) { if (members.IsNullOrEmpty()) { throw new MyWhitelistException("Needs at least one member"); } AssertVitality(); for (var index = 0; index < members.Length; index++) { var member = members[index]; if (member == null) { throw new MyWhitelistException("Element " + index + " is null"); } var typeSymbol = ResolveTypeSymbol(member.DeclaringType); var candidates = typeSymbol.GetMembers().Where(m => m.MetadataName == member.Name).ToList(); var method = member as MethodInfo; ParameterInfo[] methodParameters = null; if (method != null) { // Sanity check. I don't think this is actually possible. Debug.Assert(candidates.All(m => m is IMethodSymbol), "Illogical failure: Found more than one non-method with the same name?!?"); methodParameters = method.GetParameters(); candidates.RemoveAll(s => ((IMethodSymbol)s).Parameters.Length != methodParameters.Length); if (method.IsGenericMethodDefinition) { candidates.RemoveAll(s => !((IMethodSymbol)s).IsGenericMethod); } else { candidates.RemoveAll(s => ((IMethodSymbol)s).IsGenericMethod); } if (method.IsSpecialName && method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) { throw new MyWhitelistException("Whitelist the actual properties, not their access methods"); } } switch (candidates.Count) { case 0: throw new MyWhitelistException(string.Format("Cannot add {0} to the whitelist because its symbol variant could not be found.", member)); case 1: Whitelist.RegisterMember(target, candidates[0], member); break; default: // Sanity check. I don't think this is actually possible. Debug.Assert(method != null, "Illogical failure: Found more than one non-method with the same name?!?"); var methodSymbol = FindMethodOverload(candidates, methodParameters); if (methodSymbol == null) { throw new MyWhitelistException(string.Format("Cannot add {0} to the whitelist because its symbol variant could not be found.", member)); } Whitelist.RegisterMember(target, methodSymbol, member); break; } } }
internal bool IsWhitelisted(ISymbol symbol, MyWhitelistTarget target) { var typeSymbol = symbol as INamedTypeSymbol; if (typeSymbol != null) { return IsWhitelisted(typeSymbol, target) != TypeKeyQuantity.None; } if (symbol.IsMemberSymbol()) { return IsMemberWhitelisted(symbol, target); } // This is not a symbol we need concern ourselves with. return true; }
public WhitelistDiagnosticAnalyzer(MyScriptWhitelist whitelist, MyWhitelistTarget target) { m_whitelist = whitelist; m_target = target; }