private bool HasOnlyLegalCasts(PropertyExpression property, List <Expression> parents)
        {
            //Validate the casts being applied to a PropertyExpression. Does not consider casts that may be being
            //applied to the outer condition itself (i.e. (object)(s.Prop == val)
            var casts = parents.Where(p =>
                                      p.NodeType == ExpressionType.Convert || p.NodeType == ExpressionType.ConvertChecked ||
                                      p.NodeType == ExpressionType.TypeAs);

            var illegalCasts = casts.Where(c => IllegalCast(property, (UnaryExpression)c)).ToList();

            //If we've casted our PropertyExpression, the value we're comparing it to is not valid for
            //its true type, and therefore cannot be evaluated by PRTG
            if (illegalCasts.Count > 0)
            {
                Logger.Log($"Expression {property} contains an illegal cast(s): " + string.Join(", ", illegalCasts.Select(e => e.Type)) + ". Ignoring filter.", Indentation.Six);

                if (strict)
                {
                    throw Error.UnsupportedCastExpression(property, illegalCasts);
                }

                return(false);
            }

            return(true);
        }
        private Expression RemoveIllegal(BinaryExpression expr)
        {
            //Analayze an (A && B) or (A || B), with the implication being A and B are most likely independent
            //BinaryExpressions
            var left  = expr.Left;
            var right = expr.Right;

            PropertyExpression leftProperty  = GetMemberAccess(left);
            PropertyExpression rightProperty = GetMemberAccess(right);

            //Validate whether any expressions did something illegal like Prop1 == Prop2
            if (leftProperty == null && rightProperty == null)
            {
                Logger.Log("Cannot compare between two properties in a single expression. Eliminating expression", Indentation.Six);
                return(ReturnIllegal(null, expr, IllegalType.LeftRightSameProperty));
            }

            if (leftProperty == null)
            {
                Logger.Log($"Reducing expression '{expr}' to '{right}' as '{left}' did not contain a property expression", Indentation.Six);
                return(ReturnIllegal(right, left, IllegalType.NotSingleProperty));
            }

            if (rightProperty == null)
            {
                Logger.Log($"Reducing expression '{expr}' to '{left}' as '{right}' did not contain a property expression", Indentation.Six);
                return(ReturnIllegal(left, right, IllegalType.NotSingleProperty));
            }

            if (expr.NodeType == ExpressionType.AndAlso)
            {
                //Cannot AND between the same property. Request a single property and sort the expression out client side
                if (leftProperty.PropertyInfo.Name == rightProperty.PropertyInfo.Name && leftProperty.Keep == false)
                {
                    Logger.Log($"Cannot AND between property {leftProperty.PropertyInfo.Name}. Reducing to '{left}'", Indentation.Six);
                    return(ReturnIllegal(left, right, IllegalType.AndSameProperty));
                }

                //Valid expression
                return(expr);
            }

            if (expr.NodeType == ExpressionType.OrElse)
            {
                //Cannot OR between different properties. Request a single property and generate an additional permutation
                //for the other condition
                if (leftProperty.PropertyInfo.Name != rightProperty.PropertyInfo.Name)
                {
                    Logger.Log($"Cannot OR between different properties '{leftProperty.PropertyInfo.Name}' and '{rightProperty.PropertyInfo.Name}'. Adding '{right}' to secondary request and reducing to '{left}'", Indentation.Six);
                    illegalExpressionsForSplitRequest.Add(right);
                    return(ReturnIllegal(left, right, IllegalType.OrDifferentProperty));
                }

                //Valid expression
                return(expr);
            }

            return(expr);
        }
        private Property GetProperty(PropertyExpression member)
        {
            var attrib = member.PropertyInfo.GetAttribute <PropertyParameterAttribute>();

            return((Property)attrib.Property);
        }
Beispiel #4
0
 internal static Exception UnsupportedCastExpression(PropertyExpression property, List <Expression> illegalCasts)
 {
     return(new NotSupportedException(string.Format(unsupportedCastExpression, Clean(property), property.Type, string.Join(", ", $"'{illegalCasts.First().Type.Name}'"))));
 }
Beispiel #5
0
        private Property GetProperty(PropertyExpression member)
        {
            var attrib = member.PropertyInfo.GetAttribute <PropertyParameterAttribute>();

            return(attrib.Name.ToEnum <Property>());
        }