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);
                }
            }
Пример #10
0
        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);
        }
Пример #11
0
        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;
            }
        }
Пример #12
0
        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;
        }
Пример #13
0
 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;
 }
Пример #14
0
            /// <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;
                    }
                }
            }
Пример #15
0
            /// <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);
                }
            }
Пример #16
0
 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);
 }
Пример #17
0
        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);
        }
            /// <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;
                    }
                }
            }
Пример #19
0
            /// <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);
                }
            }
Пример #20
0
        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;
 }
 public WhitelistDiagnosticAnalyzer(MyScriptWhitelist whitelist, MyWhitelistTarget target)
 {
     m_whitelist = whitelist;
     m_target    = target;
 }