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); }
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}'")))); }
private Property GetProperty(PropertyExpression member) { var attrib = member.PropertyInfo.GetAttribute <PropertyParameterAttribute>(); return(attrib.Name.ToEnum <Property>()); }