diff --git a/lib/liquid/errors.rb b/lib/liquid/errors.rb index e227636..e1defc5 100644 --- a/lib/liquid/errors.rb +++ b/lib/liquid/errors.rb @@ -58,4 +58,5 @@ module Liquid TaintedError = Class.new(Error) MemoryError = Class.new(Error) ZeroDivisionError = Class.new(Error) + FloatDomainError = Class.new(Error) end diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index ae1637c..a615b46 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -177,12 +177,12 @@ module Liquid # remove a substring def remove(input, string) - input.to_s.gsub(string, ''.freeze) + input.to_s.gsub(string.to_s, ''.freeze) end # remove the first occurrences of a substring def remove_first(input, string) - input.to_s.sub(string, ''.freeze) + input.to_s.sub(string.to_s, ''.freeze) end # add one string to another @@ -285,6 +285,8 @@ module Liquid def modulo(input, operand) apply_operation(input, operand, :%) + rescue ::ZeroDivisionError => e + raise Liquid::ZeroDivisionError, e.message end def round(input, n = 0) @@ -292,14 +294,20 @@ module Liquid result = result.to_f if result.is_a?(BigDecimal) result = result.to_i if n == 0 result + rescue ::FloatDomainError => e + raise Liquid::FloatDomainError, e.message end def ceil(input) to_number(input).ceil.to_i + rescue ::FloatDomainError => e + raise Liquid::FloatDomainError, e.message end def floor(input) to_number(input).floor.to_i + rescue ::FloatDomainError => e + raise Liquid::FloatDomainError, e.message end def default(input, default_value = "".freeze) diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index 8dc376c..c168061 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -274,7 +274,9 @@ class StandardFiltersTest < Minitest::Test def test_remove assert_equal ' ', @filters.remove("a a a a", 'a') + assert_equal ' ', @filters.remove("1 1 1 1", 1) assert_equal 'a a a', @filters.remove_first("a a a a", 'a ') + assert_equal ' 1 1 1', @filters.remove_first("1 1 1 1", 1) assert_template_result 'a a a', "{{ 'a a a a' | remove_first: 'a ' }}" end @@ -333,26 +335,41 @@ class StandardFiltersTest < Minitest::Test assert_equal "Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render assert_template_result "0.5", "{{ 2.0 | divided_by:4 }}" + assert_raises(Liquid::ZeroDivisionError) do + assert_template_result "4", "{{ 1 | modulo: 0 }}" + end end def test_modulo assert_template_result "1", "{{ 3 | modulo:2 }}" + assert_raises(Liquid::ZeroDivisionError) do + assert_template_result "4", "{{ 1 | modulo: 0 }}" + end end def test_round assert_template_result "5", "{{ input | round }}", 'input' => 4.6 assert_template_result "4", "{{ '4.3' | round }}" assert_template_result "4.56", "{{ input | round: 2 }}", 'input' => 4.5612 + assert_raises(Liquid::FloatDomainError) do + assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | round }}" + end end def test_ceil assert_template_result "5", "{{ input | ceil }}", 'input' => 4.6 assert_template_result "5", "{{ '4.3' | ceil }}" + assert_raises(Liquid::FloatDomainError) do + assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | ceil }}" + end end def test_floor assert_template_result "4", "{{ input | floor }}", 'input' => 4.6 assert_template_result "4", "{{ '4.3' | floor }}" + assert_raises(Liquid::FloatDomainError) do + assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | floor }}" + end end def test_append