diff --git a/lib/miq_expression.rb b/lib/miq_expression.rb index cc08e4f3975..e5c69d6e8d2 100644 --- a/lib/miq_expression.rb +++ b/lib/miq_expression.rb @@ -1,4 +1,6 @@ class MiqExpression + class InvalidExpression < StandardError ; end + # bit array of the types of nodes available/desired MODE_NONE = 0 MODE_RUBY = 1 @@ -35,28 +37,11 @@ def initialize(exp, ctype = nil) @ruby = nil end - def valid?(component = exp) - operator = component.keys.first - case operator.downcase - when "and", "or" - component[operator].all?(&method(:valid?)) - when "not", "!" - valid?(component[operator]) - when "find" - validate_set = Set.new(%w[checkall checkany checkcount search]) - validate_keys = component[operator].keys.select { |k| validate_set.include?(k) } - validate_keys.all? { |k| valid?(component[operator][k]) } - else - if component[operator].key?("field") - field = Field.parse(component[operator]["field"]) - return false if field && !field.valid? - end - if Field.is_field?(component[operator]["value"]) - field = Field.parse(component[operator]["value"]) - return false unless field && field.valid? - end - true - end + def valid? + preprocess_exp(exp) + true + rescue InvalidExpression + false end def set_tagged_target(model, associations = []) @@ -180,14 +165,14 @@ def to_ruby(timezone = nil, prune_sql: false) nil elsif @ruby @ruby.dup - elsif valid? + else pexp = preprocess_exp(exp) pexp, _ = prune_exp(pexp, MODE_RUBY) if prune_sql @ruby = self.class._to_ruby(pexp, context_type, timezone) || true @ruby == true ? nil : @ruby.dup - else - "" end + rescue InvalidExpression + "" end def self._to_ruby(exp, context_type, tz) @@ -329,6 +314,8 @@ def to_sql(tz = nil) sql = to_arel(pexp, tz).to_sql if pexp.present? incl = includes_for_sql if sql.present? [sql, incl, attrs] + rescue InvalidExpression + [nil, nil, {:supported_by_sql => false}] end def preprocess_exp(exp) @@ -355,10 +342,12 @@ def preprocess_exp(exp) field = operator_values["field"] if field field_field = operator_values["field-field"] = Field.parse(field) + raise(InvalidExpression, field) unless field_field.valid? end value = operator_values["value"] if value value_field = operator_values["value-field"] = Field.parse(value) + raise(InvalidExpression, field) if value_field && !value_field.valid? end # attempt to do conversion only if db type of column is integer and value to compare to is String