diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index 810441c..d41af49 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -21,6 +21,7 @@ module Liquid @registers = registers @errors = [] @partial = false + @strict_variables = false @resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits) squash_instance_assigns_with_environments diff --git a/lib/liquid/drop.rb b/lib/liquid/drop.rb index 0c5a354..6b5aa99 100644 --- a/lib/liquid/drop.rb +++ b/lib/liquid/drop.rb @@ -62,16 +62,17 @@ module Liquid end def self.invokable_methods - unless @invokable_methods + @invokable_methods ||= begin blacklist = Liquid::Drop.public_instance_methods + [:each] + if include?(Enumerable) blacklist += Enumerable.public_instance_methods blacklist -= [:sort, :count, :first, :min, :max, :include?] end + whitelist = [:to_liquid] + (public_instance_methods - blacklist) - @invokable_methods = Set.new(whitelist.map(&:to_s)) + Set.new(whitelist.map(&:to_s)) end - @invokable_methods end end end diff --git a/lib/liquid/parse_context.rb b/lib/liquid/parse_context.rb index baf63af..fbd7cb6 100644 --- a/lib/liquid/parse_context.rb +++ b/lib/liquid/parse_context.rb @@ -1,7 +1,7 @@ module Liquid class ParseContext - attr_accessor :partial, :locale, :line_number - attr_reader :warnings, :error_mode + attr_accessor :locale, :line_number + attr_reader :partial, :warnings, :error_mode def initialize(options = {}) @template_options = options ? options.dup : {} diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index fa82bc1..55011b3 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -48,8 +48,10 @@ module Liquid def initialize(tag_name, markup, options) super + @from = @limit = nil parse_with_selected_parser(markup) @for_block = BlockBody.new + @else_block = nil end def parse(tokens) diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 130d17d..9b82241 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -20,7 +20,7 @@ module Liquid class TagRegistry def initialize - @tags = {} + @tags = {} @cache = {} end @@ -80,11 +80,11 @@ module Liquid end def error_mode - @error_mode || :lax + @error_mode ||= :lax end def taint_mode - @taint_mode || :lax + @taint_mode ||= :lax end # Pass a module with filter methods which should be available @@ -107,6 +107,7 @@ module Liquid end def initialize + @rethrow_errors = false @resource_limits = ResourceLimits.new(self.class.default_resource_limits) end diff --git a/lib/liquid/tokenizer.rb b/lib/liquid/tokenizer.rb index 7ea0407..d03657e 100644 --- a/lib/liquid/tokenizer.rb +++ b/lib/liquid/tokenizer.rb @@ -4,7 +4,7 @@ module Liquid def initialize(source, line_numbers = false) @source = source - @line_number = 1 if line_numbers + @line_number = line_numbers ? 1 : nil @tokens = tokenize end diff --git a/test/integration/error_handling_test.rb b/test/integration/error_handling_test.rb index 6e2623f..be232ea 100644 --- a/test/integration/error_handling_test.rb +++ b/test/integration/error_handling_test.rb @@ -94,7 +94,7 @@ class ErrorHandlingTest < Minitest::Test ) end - assert_match /Liquid syntax error \(line 4\)/, err.message + assert_match(/Liquid syntax error \(line 4\)/, err.message) end def test_parsing_warn_with_line_numbers_adds_numbers_to_lexer_errors diff --git a/test/integration/hash_ordering_test.rb b/test/integration/hash_ordering_test.rb index 588e1c1..dfc1c29 100644 --- a/test/integration/hash_ordering_test.rb +++ b/test/integration/hash_ordering_test.rb @@ -1,18 +1,18 @@ require 'test_helper' -module MoneyFilter - def money(input) - sprintf(' %d$ ', input) - end -end - -module CanadianMoneyFilter - def money(input) - sprintf(' %d$ CAD ', input) - end -end - class HashOrderingTest < Minitest::Test + module MoneyFilter + def money(input) + sprintf(' %d$ ', input) + end + end + + module CanadianMoneyFilter + def money(input) + sprintf(' %d$ CAD ', input) + end + end + include Liquid def test_global_register_order diff --git a/test/integration/security_test.rb b/test/integration/security_test.rb index c5c819f..0357498 100644 --- a/test/integration/security_test.rb +++ b/test/integration/security_test.rb @@ -9,6 +9,10 @@ end class SecurityTest < Minitest::Test include Liquid + def setup + @assigns = {} + end + def test_no_instance_eval text = %( {{ '1+1' | instance_eval }} ) expected = %( 1+1 ) diff --git a/test/integration/tags/raw_tag_test.rb b/test/integration/tags/raw_tag_test.rb index c672734..634d052 100644 --- a/test/integration/tags/raw_tag_test.rb +++ b/test/integration/tags/raw_tag_test.rb @@ -24,8 +24,8 @@ class RawTagTest < Minitest::Test end def test_invalid_raw - assert_match_syntax_error /tag was never closed/, '{% raw %} foo' - assert_match_syntax_error /Valid syntax/, '{% raw } foo {% endraw %}' - assert_match_syntax_error /Valid syntax/, '{% raw } foo %}{% endraw %}' + assert_match_syntax_error(/tag was never closed/, '{% raw %} foo') + assert_match_syntax_error(/Valid syntax/, '{% raw } foo {% endraw %}') + assert_match_syntax_error(/Valid syntax/, '{% raw } foo %}{% endraw %}') end end diff --git a/test/unit/condition_unit_test.rb b/test/unit/condition_unit_test.rb index 1435995..8dfc788 100644 --- a/test/unit/condition_unit_test.rb +++ b/test/unit/condition_unit_test.rb @@ -3,50 +3,54 @@ require 'test_helper' class ConditionUnitTest < Minitest::Test include Liquid + def setup + @context = Liquid::Context.new + end + def test_basic_condition assert_equal false, Condition.new(1, '==', 2).evaluate assert_equal true, Condition.new(1, '==', 1).evaluate end def test_default_operators_evalute_true - assert_evalutes_true 1, '==', 1 - assert_evalutes_true 1, '!=', 2 - assert_evalutes_true 1, '<>', 2 - assert_evalutes_true 1, '<', 2 - assert_evalutes_true 2, '>', 1 - assert_evalutes_true 1, '>=', 1 - assert_evalutes_true 2, '>=', 1 - assert_evalutes_true 1, '<=', 2 - assert_evalutes_true 1, '<=', 1 + assert_evaluates_true 1, '==', 1 + assert_evaluates_true 1, '!=', 2 + assert_evaluates_true 1, '<>', 2 + assert_evaluates_true 1, '<', 2 + assert_evaluates_true 2, '>', 1 + assert_evaluates_true 1, '>=', 1 + assert_evaluates_true 2, '>=', 1 + assert_evaluates_true 1, '<=', 2 + assert_evaluates_true 1, '<=', 1 # negative numbers - assert_evalutes_true 1, '>', -1 - assert_evalutes_true -1, '<', 1 - assert_evalutes_true 1.0, '>', -1.0 - assert_evalutes_true -1.0, '<', 1.0 + assert_evaluates_true 1, '>', -1 + assert_evaluates_true (-1), '<', 1 + assert_evaluates_true 1.0, '>', -1.0 + assert_evaluates_true (-1.0), '<', 1.0 end def test_default_operators_evalute_false - assert_evalutes_false 1, '==', 2 - assert_evalutes_false 1, '!=', 1 - assert_evalutes_false 1, '<>', 1 - assert_evalutes_false 1, '<', 0 - assert_evalutes_false 2, '>', 4 - assert_evalutes_false 1, '>=', 3 - assert_evalutes_false 2, '>=', 4 - assert_evalutes_false 1, '<=', 0 - assert_evalutes_false 1, '<=', 0 + assert_evaluates_false 1, '==', 2 + assert_evaluates_false 1, '!=', 1 + assert_evaluates_false 1, '<>', 1 + assert_evaluates_false 1, '<', 0 + assert_evaluates_false 2, '>', 4 + assert_evaluates_false 1, '>=', 3 + assert_evaluates_false 2, '>=', 4 + assert_evaluates_false 1, '<=', 0 + assert_evaluates_false 1, '<=', 0 end def test_contains_works_on_strings - assert_evalutes_true 'bob', 'contains', 'o' - assert_evalutes_true 'bob', 'contains', 'b' - assert_evalutes_true 'bob', 'contains', 'bo' - assert_evalutes_true 'bob', 'contains', 'ob' - assert_evalutes_true 'bob', 'contains', 'bob' + assert_evaluates_true 'bob', 'contains', 'o' + assert_evaluates_true 'bob', 'contains', 'b' + assert_evaluates_true 'bob', 'contains', 'bo' + assert_evaluates_true 'bob', 'contains', 'ob' + assert_evaluates_true 'bob', 'contains', 'bob' - assert_evalutes_false 'bob', 'contains', 'bob2' - assert_evalutes_false 'bob', 'contains', 'a' - assert_evalutes_false 'bob', 'contains', '---' + assert_evaluates_false 'bob', 'contains', 'bob2' + assert_evaluates_false 'bob', 'contains', 'a' + assert_evaluates_false 'bob', 'contains', '---' end def test_invalid_comparation_operator @@ -65,29 +69,29 @@ class ConditionUnitTest < Minitest::Test @context['array'] = [1, 2, 3, 4, 5] array_expr = VariableLookup.new("array") - assert_evalutes_false array_expr, 'contains', 0 - assert_evalutes_true array_expr, 'contains', 1 - assert_evalutes_true array_expr, 'contains', 2 - assert_evalutes_true array_expr, 'contains', 3 - assert_evalutes_true array_expr, 'contains', 4 - assert_evalutes_true array_expr, 'contains', 5 - assert_evalutes_false array_expr, 'contains', 6 - assert_evalutes_false array_expr, 'contains', "1" + assert_evaluates_false array_expr, 'contains', 0 + assert_evaluates_true array_expr, 'contains', 1 + assert_evaluates_true array_expr, 'contains', 2 + assert_evaluates_true array_expr, 'contains', 3 + assert_evaluates_true array_expr, 'contains', 4 + assert_evaluates_true array_expr, 'contains', 5 + assert_evaluates_false array_expr, 'contains', 6 + assert_evaluates_false array_expr, 'contains', "1" end def test_contains_returns_false_for_nil_operands @context = Liquid::Context.new - assert_evalutes_false VariableLookup.new('not_assigned'), 'contains', '0' - assert_evalutes_false 0, 'contains', VariableLookup.new('not_assigned') + assert_evaluates_false VariableLookup.new('not_assigned'), 'contains', '0' + assert_evaluates_false 0, 'contains', VariableLookup.new('not_assigned') end def test_contains_return_false_on_wrong_data_type - assert_evalutes_false 1, 'contains', 0 + assert_evaluates_false 1, 'contains', 0 end def test_contains_with_string_left_operand_coerces_right_operand_to_string - assert_evalutes_true ' 1 ', 'contains', 1 - assert_evalutes_false ' 1 ', 'contains', 2 + assert_evaluates_true ' 1 ', 'contains', 1 + assert_evaluates_false ' 1 ', 'contains', 2 end def test_or_condition @@ -121,8 +125,8 @@ class ConditionUnitTest < Minitest::Test def test_should_allow_custom_proc_operator Condition.operators['starts_with'] = proc { |cond, left, right| left =~ %r{^#{right}} } - assert_evalutes_true 'bob', 'starts_with', 'b' - assert_evalutes_false 'bob', 'starts_with', 'o' + assert_evaluates_true 'bob', 'starts_with', 'b' + assert_evaluates_false 'bob', 'starts_with', 'o' ensure Condition.operators.delete 'starts_with' end @@ -131,24 +135,24 @@ class ConditionUnitTest < Minitest::Test @context = Liquid::Context.new @context['one'] = @context['another'] = "gnomeslab-and-or-liquid" - assert_evalutes_true VariableLookup.new("one"), '==', VariableLookup.new("another") + assert_evaluates_true VariableLookup.new("one"), '==', VariableLookup.new("another") end private - def assert_evalutes_true(left, op, right) - assert Condition.new(left, op, right).evaluate(@context || Liquid::Context.new), + def assert_evaluates_true(left, op, right) + assert Condition.new(left, op, right).evaluate(@context), "Evaluated false: #{left} #{op} #{right}" end - def assert_evalutes_false(left, op, right) - assert !Condition.new(left, op, right).evaluate(@context || Liquid::Context.new), + def assert_evaluates_false(left, op, right) + assert !Condition.new(left, op, right).evaluate(@context), "Evaluated true: #{left} #{op} #{right}" end def assert_evaluates_argument_error(left, op, right) assert_raises(Liquid::ArgumentError) do - Condition.new(left, op, right).evaluate(@context || Liquid::Context.new) + Condition.new(left, op, right).evaluate(@context) end end end # ConditionTest