From 40c68c9c833b0cd413aedd8c12649bf9f897e517 Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Thu, 19 Dec 2019 11:00:42 -0500 Subject: [PATCH] Remove support for taint_mode on ruby versions that don't support it --- lib/liquid/template.rb | 9 +++++- lib/liquid/variable.rb | 2 +- test/integration/drop_test.rb | 38 +++++++++++++----------- test/integration/tags/render_tag_test.rb | 36 +++++++++++----------- test/integration/template_test.rb | 8 +++++ test/test_helper.rb | 4 +++ 6 files changed, 60 insertions(+), 37 deletions(-) diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 228870c..8ec300d 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -69,7 +69,14 @@ module Liquid # :lax is the default, and ignores the taint flag completely # :warn adds a warning, but does not interrupt the rendering # :error raises an error when tainted output is used - attr_writer :taint_mode + # @deprecated Since it is being deprecated in ruby itself. + def taint_mode=(mode) + taint_supported = Object.new.taint.tainted? + if mode != :lax && !taint_supported + raise NotImplementedError, "#{RUBY_ENGINE} #{RUBY_VERSION} doesn't support taint checking" + end + @taint_mode = mode + end attr_accessor :default_exception_renderer Template.default_exception_renderer = lambda do |exception| diff --git a/lib/liquid/variable.rb b/lib/liquid/variable.rb index 9566f94..9c80bc3 100644 --- a/lib/liquid/variable.rb +++ b/lib/liquid/variable.rb @@ -143,8 +143,8 @@ module Liquid end def taint_check(context, obj) - return unless obj.tainted? return if Template.taint_mode == :lax + return unless obj.tainted? @markup =~ QuotedFragment name = Regexp.last_match(0) diff --git a/test/integration/drop_test.rb b/test/integration/drop_test.rb index eeb1238..81c8222 100644 --- a/test/integration/drop_test.rb +++ b/test/integration/drop_test.rb @@ -114,29 +114,31 @@ class DropsTest < Minitest::Test assert_equal(' ', tpl.render!('product' => ProductDrop.new)) end - def test_rendering_raises_on_tainted_attr - with_taint_mode(:error) do - tpl = Liquid::Template.parse('{{ product.user_input }}') - assert_raises TaintedError do - tpl.render!('product' => ProductDrop.new) + if taint_supported? + def test_rendering_raises_on_tainted_attr + with_taint_mode(:error) do + tpl = Liquid::Template.parse('{{ product.user_input }}') + assert_raises TaintedError do + tpl.render!('product' => ProductDrop.new) + end end end - end - def test_rendering_warns_on_tainted_attr - with_taint_mode(:warn) do - tpl = Liquid::Template.parse('{{ product.user_input }}') - context = Context.new('product' => ProductDrop.new) - tpl.render!(context) - assert_equal [Liquid::TaintedError], context.warnings.map(&:class) - assert_equal "variable 'product.user_input' is tainted and was not escaped", context.warnings.first.to_s(false) + def test_rendering_warns_on_tainted_attr + with_taint_mode(:warn) do + tpl = Liquid::Template.parse('{{ product.user_input }}') + context = Context.new('product' => ProductDrop.new) + tpl.render!(context) + assert_equal [Liquid::TaintedError], context.warnings.map(&:class) + assert_equal "variable 'product.user_input' is tainted and was not escaped", context.warnings.first.to_s(false) + end end - end - def test_rendering_doesnt_raise_on_escaped_tainted_attr - with_taint_mode(:error) do - tpl = Liquid::Template.parse('{{ product.user_input | escape }}') - tpl.render!('product' => ProductDrop.new) + def test_rendering_doesnt_raise_on_escaped_tainted_attr + with_taint_mode(:error) do + tpl = Liquid::Template.parse('{{ product.user_input | escape }}') + tpl.render!('product' => ProductDrop.new) + end end end diff --git a/test/integration/tags/render_tag_test.rb b/test/integration/tags/render_tag_test.rb index 7ba990f..ae9390e 100644 --- a/test/integration/tags/render_tag_test.rb +++ b/test/integration/tags/render_tag_test.rb @@ -42,29 +42,31 @@ class RenderTagTest < Minitest::Test assert_template_result('', "{% assign snippet = 'should not be visible' %}{% render 'snippet' %}") end - def test_render_sets_the_correct_template_name_for_errors - Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}') + if taint_supported? + def test_render_sets_the_correct_template_name_for_errors + Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}') - with_taint_mode :error do - template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}') - context = Context.new('unsafe' => (+'unsafe').tap(&:taint)) - template.render(context) + with_taint_mode :error do + template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}') + context = Context.new('unsafe' => (+'unsafe').tap(&:taint)) + template.render(context) - assert_equal [Liquid::TaintedError], template.errors.map(&:class) - assert_equal 'snippet', template.errors.first.template_name + assert_equal [Liquid::TaintedError], template.errors.map(&:class) + assert_equal 'snippet', template.errors.first.template_name + end end - end - def test_render_sets_the_correct_template_name_for_warnings - Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}') + def test_render_sets_the_correct_template_name_for_warnings + Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}') - with_taint_mode :warn do - template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}') - context = Context.new('unsafe' => (+'unsafe').tap(&:taint)) - template.render(context) + with_taint_mode :warn do + template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}') + context = Context.new('unsafe' => (+'unsafe').tap(&:taint)) + template.render(context) - assert_equal [Liquid::TaintedError], context.warnings.map(&:class) - assert_equal 'snippet', context.warnings.first.template_name + assert_equal [Liquid::TaintedError], context.warnings.map(&:class) + assert_equal 'snippet', context.warnings.first.template_name + end end end diff --git a/test/integration/template_test.rb b/test/integration/template_test.rb index 014f951..f5588ed 100644 --- a/test/integration/template_test.rb +++ b/test/integration/template_test.rb @@ -361,4 +361,12 @@ class TemplateTest < Minitest::Test result = t.render('x' => 1, 'y' => 5) assert_equal('12345', result) end + + unless taint_supported? + def test_taint_mode + assert_raises(NotImplementedError) do + Template.taint_mode = :warn + end + end + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 7422129..e7f1df3 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -32,6 +32,10 @@ module Minitest def fixture(name) File.join(File.expand_path(__dir__), "fixtures", name) end + + def self.taint_supported? + Object.new.taint.tainted? + end end module Assertions