Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# 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

### Features
Expand Down
48 changes: 33 additions & 15 deletions lib/liquid/standardfilters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,23 @@ def where(input, property, target_value = nil)

if ary.empty?
[]
elsif ary.first.respond_to?(:[]) && target_value.nil?
begin
ary.select { |item| item[property] }
elsif target_value.nil?
ary.select do |item|
item[property]
rescue TypeError
raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end
elsif ary.first.respond_to?(:[])
begin
ary.select { |item| item[property] == target_value }
else
ary.select do |item|
item[property] == target_value
rescue TypeError
raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end
end
end
Expand All @@ -237,11 +243,14 @@ def uniq(input, property = nil)
ary.uniq
elsif ary.empty? # The next two cases assume a non-empty array.
[]
elsif ary.first.respond_to?(:[])
begin
ary.uniq { |a| a[property] }
else
ary.uniq do |item|
item[property]
rescue TypeError
raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end
end
end
Expand Down Expand Up @@ -277,11 +286,14 @@ def compact(input, property = nil)
ary.compact
elsif ary.empty? # The next two cases assume a non-empty array.
[]
elsif ary.first.respond_to?(:[])
begin
ary.reject { |a| a[property].nil? }
else
ary.reject do |item|
item[property].nil?
rescue TypeError
raise_property_error(property)
rescue NoMethodError
return nil unless item.respond_to?(:[])
raise
end
end
end
Expand Down Expand Up @@ -486,10 +498,16 @@ def apply_operation(input, operand, operation)
end

def nil_safe_compare(a, b)
if !a.nil? && !b.nil?
a <=> b
result = a <=> b

if result
result
elsif a.nil?
1
elsif b.nil?
-1
else
a.nil? ? 1 : -1
raise Liquid::ArgumentError, "cannot sort values of incompatible types"
end
end

Expand Down
23 changes: 9 additions & 14 deletions test/integration/standard_filter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ def test_sort_when_property_is_sometimes_missing_puts_nils_last
{ "price" => 1, "handle" => "gamma" },
{ "price" => 2, "handle" => "epsilon" },
{ "price" => 4, "handle" => "alpha" },
{ "handle" => "delta" },
{ "handle" => "beta" },
{ "handle" => "delta" },
]
assert_equal(expectation, @filters.sort(input, "price"))
end
Expand Down Expand Up @@ -852,19 +852,14 @@ def test_all_filters_never_raise_non_liquid_exception
{ 1 => "bar" },
["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
]
test_types.each do |first|
test_types.each do |other|
(@filters.methods - Object.methods).each do |method|
arg_count = @filters.method(method).arity
arg_count *= -1 if arg_count < 0
inputs = [first]
inputs << ([other] * (arg_count - 1)) if arg_count > 1
begin
@filters.send(method, *inputs)
rescue Liquid::ArgumentError, Liquid::ZeroDivisionError
nil
end
end
StandardFilters.public_instance_methods(false).each do |method|
arg_count = @filters.method(method).arity
arg_count *= -1 if arg_count < 0

test_types.repeated_permutation(arg_count) do |args|
@filters.send(method, *args)
rescue Liquid::Error
nil
end
end
end
Expand Down