diff --git a/lib/miq_expression.rb b/lib/miq_expression.rb
index 02851f89626..aae86a30f26 100644
--- a/lib/miq_expression.rb
+++ b/lib/miq_expression.rb
@@ -640,16 +640,7 @@ def self.quote(val, typ)
val.to_s.to_f_with_method
when "numeric_set"
val = val.split(",") if val.kind_of?(String)
- v_arr = Array.wrap(val).flat_map do |v|
- if v.kind_of?(String)
- v = begin
- eval(v)
- rescue
- nil
- end
- end
- v.kind_of?(Range) ? v.to_a : v
- end.compact.uniq.sort
+ v_arr = Array.wrap(val).flat_map { |v| quote_numeric_set_atom(v) }.compact.uniq.sort
"[#{v_arr.join(",")}]"
when "string_set"
val = val.split(",") if val.kind_of?(String)
@@ -660,6 +651,32 @@ def self.quote(val, typ)
end
end
+ private_class_method def self.quote_numeric_set_atom(val)
+ val = val.to_s unless val.kind_of?(Numeric) || val.kind_of?(Range)
+
+ if val.kind_of?(String)
+ val = val.strip
+ val =
+ if val.include?("..") # Parse Ranges
+ b, e = val.split("..", 2).map do |i|
+ if integer?(i)
+ i.to_i_with_method
+ elsif numeric?(i)
+ i.to_f_with_method
+ end
+ end
+
+ Range.new(b, e) if b && e
+ elsif integer?(val) # Parse Integers
+ val.to_i_with_method
+ elsif numeric?(val) # Parse Floats
+ val.to_f_with_method
+ end
+ end
+
+ val.kind_of?(Range) ? val.to_a : val
+ end
+
def self.quote_human(val, typ)
case typ.to_s
when "integer", "decimal", "fixnum", "float"
diff --git a/spec/lib/miq_expression_spec.rb b/spec/lib/miq_expression_spec.rb
index d30d0e04199..04bec549fc8 100644
--- a/spec/lib/miq_expression_spec.rb
+++ b/spec/lib/miq_expression_spec.rb
@@ -1366,9 +1366,34 @@
expect { exp.to_ruby }.to raise_error(/operator 'RUBY' is not supported/)
end
- it "tests numeric set expressions" do
- exp = MiqExpression.new("=" => {"field" => "Host-enabled_inbound_ports", "value" => "22,427,5988,5989"})
- expect(exp.to_ruby).to eq('/virtual/enabled_inbound_ports == [22,427,5988,5989]')
+ it "ignores invalid values for a numeric_set in an = expression" do
+ actual = described_class.new("=" => {"field" => "Host-enabled_inbound_ports", "value" => "22, 427, 5988, 5989, foo, `echo 1000`.to_i, abc..123, 1..4"}).to_ruby
+ expected = "/virtual/enabled_inbound_ports == [1,2,3,4,22,427,5988,5989]"
+ expect(actual).to eq(expected)
+ end
+
+ it "ignores invalid values for a numeric_set in an INCLUDES ALL expression" do
+ actual = described_class.new("INCLUDES ALL" => {"field" => "Host-enabled_inbound_ports", "value" => "22, 427, 5988, 5989, foo, `echo 1000`.to_i, abc..123, 1..4"}).to_ruby
+ expected = "(/virtual/enabled_inbound_ports & [1,2,3,4,22,427,5988,5989]) == [1,2,3,4,22,427,5988,5989]"
+ expect(actual).to eq(expected)
+ end
+
+ it "ignores invalid values for a numeric_set in an INCLUDES ANY expression" do
+ actual = described_class.new("INCLUDES ANY" => {"field" => "Host-enabled_inbound_ports", "value" => "22, 427, 5988, 5989, foo, `echo 1000`.to_i, abc..123, 1..4"}).to_ruby
+ expected = "([1,2,3,4,22,427,5988,5989] - /virtual/enabled_inbound_ports) != [1,2,3,4,22,427,5988,5989]"
+ expect(actual).to eq(expected)
+ end
+
+ it "ignores invalid values for a numeric_set in an INCLUDES ONLY expression" do
+ actual = described_class.new("INCLUDES ONLY" => {"field" => "Host-enabled_inbound_ports", "value" => "22, 427, 5988, 5989, foo, `echo 1000`.to_i, abc..123, 1..4"}).to_ruby
+ expected = "(/virtual/enabled_inbound_ports - [1,2,3,4,22,427,5988,5989]) == []"
+ expect(actual).to eq(expected)
+ end
+
+ it "ignores invalid values for a numeric_set in an LIMITED TO expression" do
+ actual = described_class.new("LIMITED TO" => {"field" => "Host-enabled_inbound_ports", "value" => "22, 427, 5988, 5989, foo, `echo 1000`.to_i, abc..123, 1..4"}).to_ruby
+ expected = "(/virtual/enabled_inbound_ports - [1,2,3,4,22,427,5988,5989]) == []"
+ expect(actual).to eq(expected)
end
it "escapes forward slashes for values in REGULAR EXPRESSION MATCHES expressions" do
@@ -1476,10 +1501,10 @@
exp:
INCLUDES ANY:
field: Host-enabled_inbound_ports
- value: 22, 427, 5988, 5989, 1..3
+ value: 22, 427, 5988, 5989, 1..4
'
- expected = "([1,2,3,22,427,5988,5989] - /virtual/enabled_inbound_ports) != [1,2,3,22,427,5988,5989]"
+ expected = "([1,2,3,4,22,427,5988,5989] - /virtual/enabled_inbound_ports) != [1,2,3,4,22,427,5988,5989]"
expect(filter.to_ruby).to eq(expected)
end
@@ -1488,10 +1513,10 @@
exp:
INCLUDES ONLY:
field: Host-enabled_inbound_ports
- value: 22
+ value: 22, 427, 5988, 5989, 1..4
'
- expected = "(/virtual/enabled_inbound_ports - [22]) == []"
+ expected = "(/virtual/enabled_inbound_ports - [1,2,3,4,22,427,5988,5989]) == []"
expect(filter.to_ruby).to eq(expected)
end
@@ -1500,10 +1525,10 @@
exp:
LIMITED TO:
field: Host-enabled_inbound_ports
- value: 22
+ value: 22, 427, 5988, 5989, 1..4
'
- expected = "(/virtual/enabled_inbound_ports - [22]) == []"
+ expected = "(/virtual/enabled_inbound_ports - [1,2,3,4,22,427,5988,5989]) == []"
expect(filter.to_ruby).to eq(expected)
end