Fix some internal errors in filters from invalid input. (#1476)

These fixes came from improving the corresponding test, so these might not
actually be causing problems in practice.
This commit is contained in:
Dylan Thacker-Smith
2022-02-24 09:17:37 -05:00
committed by GitHub
parent 15eaa49e48
commit 0d5e01ae98
3 changed files with 48 additions and 29 deletions
+6
View File
@@ -1,5 +1,11 @@
# Liquid Change Log # Liquid Change Log
## 5.1.1 (unreleased)
### Fixes
* Fix some internal errors in filters from invalid input [Dylan Thacker-Smith]
## 5.1.0 / 2021-09-09 ## 5.1.0 / 2021-09-09
### Features ### Features
+33 -15
View File
@@ -213,17 +213,23 @@ module Liquid
if ary.empty? if ary.empty?
[] []
elsif ary.first.respond_to?(:[]) && target_value.nil? elsif target_value.nil?
begin ary.select do |item|
ary.select { |item| item[property] } item[property]
rescue TypeError rescue TypeError
raise_property_error(property) raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end end
elsif ary.first.respond_to?(:[]) else
begin ary.select do |item|
ary.select { |item| item[property] == target_value } item[property] == target_value
rescue TypeError rescue TypeError
raise_property_error(property) raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end end
end end
end end
@@ -237,11 +243,14 @@ module Liquid
ary.uniq ary.uniq
elsif ary.empty? # The next two cases assume a non-empty array. elsif ary.empty? # The next two cases assume a non-empty array.
[] []
elsif ary.first.respond_to?(:[]) else
begin ary.uniq do |item|
ary.uniq { |a| a[property] } item[property]
rescue TypeError rescue TypeError
raise_property_error(property) raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end end
end end
end end
@@ -277,11 +286,14 @@ module Liquid
ary.compact ary.compact
elsif ary.empty? # The next two cases assume a non-empty array. elsif ary.empty? # The next two cases assume a non-empty array.
[] []
elsif ary.first.respond_to?(:[]) else
begin ary.reject do |item|
ary.reject { |a| a[property].nil? } item[property].nil?
rescue TypeError rescue TypeError
raise_property_error(property) raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end end
end end
end end
@@ -486,10 +498,16 @@ module Liquid
end end
def nil_safe_compare(a, b) def nil_safe_compare(a, b)
if !a.nil? && !b.nil? result = a <=> b
a <=> b
if result
result
elsif a.nil?
1
elsif b.nil?
-1
else else
a.nil? ? 1 : -1 raise Liquid::ArgumentError, "cannot sort values of incompatible types"
end end
end end
+9 -14
View File
@@ -259,8 +259,8 @@ class StandardFiltersTest < Minitest::Test
{ "price" => 1, "handle" => "gamma" }, { "price" => 1, "handle" => "gamma" },
{ "price" => 2, "handle" => "epsilon" }, { "price" => 2, "handle" => "epsilon" },
{ "price" => 4, "handle" => "alpha" }, { "price" => 4, "handle" => "alpha" },
{ "handle" => "delta" },
{ "handle" => "beta" }, { "handle" => "beta" },
{ "handle" => "delta" },
] ]
assert_equal(expectation, @filters.sort(input, "price")) assert_equal(expectation, @filters.sort(input, "price"))
end end
@@ -852,19 +852,14 @@ class StandardFiltersTest < Minitest::Test
{ 1 => "bar" }, { 1 => "bar" },
["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }], ["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
] ]
test_types.each do |first| StandardFilters.public_instance_methods(false).each do |method|
test_types.each do |other| arg_count = @filters.method(method).arity
(@filters.methods - Object.methods).each do |method| arg_count *= -1 if arg_count < 0
arg_count = @filters.method(method).arity
arg_count *= -1 if arg_count < 0 test_types.repeated_permutation(arg_count) do |args|
inputs = [first] @filters.send(method, *args)
inputs << ([other] * (arg_count - 1)) if arg_count > 1 rescue Liquid::Error
begin nil
@filters.send(method, *inputs)
rescue Liquid::ArgumentError, Liquid::ZeroDivisionError
nil
end
end
end end
end end
end end