mirror of
https://github.com/Shopify/liquid.git
synced 2026-10-03 09:05:13 -07:00
Remove support for taint_mode on ruby versions that don't support it
This commit is contained in:
@@ -69,7 +69,14 @@ module Liquid
|
|||||||
# :lax is the default, and ignores the taint flag completely
|
# :lax is the default, and ignores the taint flag completely
|
||||||
# :warn adds a warning, but does not interrupt the rendering
|
# :warn adds a warning, but does not interrupt the rendering
|
||||||
# :error raises an error when tainted output is used
|
# :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
|
attr_accessor :default_exception_renderer
|
||||||
Template.default_exception_renderer = lambda do |exception|
|
Template.default_exception_renderer = lambda do |exception|
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def taint_check(context, obj)
|
def taint_check(context, obj)
|
||||||
return unless obj.tainted?
|
|
||||||
return if Template.taint_mode == :lax
|
return if Template.taint_mode == :lax
|
||||||
|
return unless obj.tainted?
|
||||||
|
|
||||||
@markup =~ QuotedFragment
|
@markup =~ QuotedFragment
|
||||||
name = Regexp.last_match(0)
|
name = Regexp.last_match(0)
|
||||||
|
|||||||
@@ -114,29 +114,31 @@ class DropsTest < Minitest::Test
|
|||||||
assert_equal(' ', tpl.render!('product' => ProductDrop.new))
|
assert_equal(' ', tpl.render!('product' => ProductDrop.new))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_rendering_raises_on_tainted_attr
|
if taint_supported?
|
||||||
with_taint_mode(:error) do
|
def test_rendering_raises_on_tainted_attr
|
||||||
tpl = Liquid::Template.parse('{{ product.user_input }}')
|
with_taint_mode(:error) do
|
||||||
assert_raises TaintedError do
|
tpl = Liquid::Template.parse('{{ product.user_input }}')
|
||||||
tpl.render!('product' => ProductDrop.new)
|
assert_raises TaintedError do
|
||||||
|
tpl.render!('product' => ProductDrop.new)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def test_rendering_warns_on_tainted_attr
|
def test_rendering_warns_on_tainted_attr
|
||||||
with_taint_mode(:warn) do
|
with_taint_mode(:warn) do
|
||||||
tpl = Liquid::Template.parse('{{ product.user_input }}')
|
tpl = Liquid::Template.parse('{{ product.user_input }}')
|
||||||
context = Context.new('product' => ProductDrop.new)
|
context = Context.new('product' => ProductDrop.new)
|
||||||
tpl.render!(context)
|
tpl.render!(context)
|
||||||
assert_equal [Liquid::TaintedError], context.warnings.map(&:class)
|
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)
|
assert_equal "variable 'product.user_input' is tainted and was not escaped", context.warnings.first.to_s(false)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def test_rendering_doesnt_raise_on_escaped_tainted_attr
|
def test_rendering_doesnt_raise_on_escaped_tainted_attr
|
||||||
with_taint_mode(:error) do
|
with_taint_mode(:error) do
|
||||||
tpl = Liquid::Template.parse('{{ product.user_input | escape }}')
|
tpl = Liquid::Template.parse('{{ product.user_input | escape }}')
|
||||||
tpl.render!('product' => ProductDrop.new)
|
tpl.render!('product' => ProductDrop.new)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -42,29 +42,31 @@ class RenderTagTest < Minitest::Test
|
|||||||
assert_template_result('', "{% assign snippet = 'should not be visible' %}{% render 'snippet' %}")
|
assert_template_result('', "{% assign snippet = 'should not be visible' %}{% render 'snippet' %}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_sets_the_correct_template_name_for_errors
|
if taint_supported?
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}')
|
def test_render_sets_the_correct_template_name_for_errors
|
||||||
|
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}')
|
||||||
|
|
||||||
with_taint_mode :error do
|
with_taint_mode :error do
|
||||||
template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}')
|
template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}')
|
||||||
context = Context.new('unsafe' => (+'unsafe').tap(&:taint))
|
context = Context.new('unsafe' => (+'unsafe').tap(&:taint))
|
||||||
template.render(context)
|
template.render(context)
|
||||||
|
|
||||||
assert_equal [Liquid::TaintedError], template.errors.map(&:class)
|
assert_equal [Liquid::TaintedError], template.errors.map(&:class)
|
||||||
assert_equal 'snippet', template.errors.first.template_name
|
assert_equal 'snippet', template.errors.first.template_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def test_render_sets_the_correct_template_name_for_warnings
|
def test_render_sets_the_correct_template_name_for_warnings
|
||||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}')
|
Liquid::Template.file_system = StubFileSystem.new('snippet' => '{{ unsafe }}')
|
||||||
|
|
||||||
with_taint_mode :warn do
|
with_taint_mode :warn do
|
||||||
template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}')
|
template = Liquid::Template.parse('{% render "snippet", unsafe: unsafe %}')
|
||||||
context = Context.new('unsafe' => (+'unsafe').tap(&:taint))
|
context = Context.new('unsafe' => (+'unsafe').tap(&:taint))
|
||||||
template.render(context)
|
template.render(context)
|
||||||
|
|
||||||
assert_equal [Liquid::TaintedError], context.warnings.map(&:class)
|
assert_equal [Liquid::TaintedError], context.warnings.map(&:class)
|
||||||
assert_equal 'snippet', context.warnings.first.template_name
|
assert_equal 'snippet', context.warnings.first.template_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -361,4 +361,12 @@ class TemplateTest < Minitest::Test
|
|||||||
result = t.render('x' => 1, 'y' => 5)
|
result = t.render('x' => 1, 'y' => 5)
|
||||||
assert_equal('12345', result)
|
assert_equal('12345', result)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless taint_supported?
|
||||||
|
def test_taint_mode
|
||||||
|
assert_raises(NotImplementedError) do
|
||||||
|
Template.taint_mode = :warn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ module Minitest
|
|||||||
def fixture(name)
|
def fixture(name)
|
||||||
File.join(File.expand_path(__dir__), "fixtures", name)
|
File.join(File.expand_path(__dir__), "fixtures", name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.taint_supported?
|
||||||
|
Object.new.taint.tainted?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Assertions
|
module Assertions
|
||||||
|
|||||||
Reference in New Issue
Block a user