[Haml] Mark the return value of the Haml rendering method as HTML safe if XSS protection is enabled.

Closes gh-50
This commit is contained in:
Nathan Weizenbaum 2009-10-29 14:14:30 -07:00
parent 0193edf05a
commit 60ab39b3ae
5 changed files with 31 additions and 2 deletions

View File

@ -17,6 +17,9 @@
This allows it to work properly when Haml is a gem
and the `rails_xss` plugin is being used.
* Mark the return value of Haml templates as HTML safe.
This makes Haml partials work with Rails' XSS protection.
## [2.2.9](http://github.com/nex3/haml/commit/2.2.9)
* Fixed a bug where Haml's text was concatenated to the wrong buffer

View File

@ -175,7 +175,8 @@ module Haml
@haml_buffer = buffer
end
eval(precompiled, scope, @options[:filename], @options[:line])
eval(precompiled + "\n" + precompiled_method_return_value,
scope, @options[:filename], @options[:line])
# Get rid of the current buffer
scope_object.instance_eval do

View File

@ -99,11 +99,17 @@ __in_erb_template = true
END
postamble = <<END.gsub("\n", ";")
@haml_buffer = @haml_buffer.upper
_erbout
#{precompiled_method_return_value}
END
preamble + locals_code(local_names) + precompiled + postamble
end
# Returns the string used as the return value of the precompiled method.
# This method exists so it can be monkeypatched to return modified values.
def precompiled_method_return_value
"_erbout"
end
def locals_code(names)
names = names.keys if Hash == names

View File

@ -26,6 +26,14 @@ module Haml
require 'haml/helpers/xss_mods'
Haml::Helpers.send(:include, Haml::Helpers::XssMods)
Haml::Precompiler.module_eval do
def precompiled_method_return_value_with_haml_xss
"(#{precompiled_method_return_value_without_haml_xss}).html_safe!"
end
alias_method :precompiled_method_return_value_without_haml_xss, :precompiled_method_return_value
alias_method :precompiled_method_return_value, :precompiled_method_return_value_with_haml_xss
end
true
end
end

View File

@ -241,6 +241,9 @@ END
## XSS Protection Tests
# In order to enable these, either test against Rails 3.0
# or test against Rails 2.2.5+ with the rails_xss plugin
# (http://github.com/NZKoz/rails_xss) in test/plugins.
if Haml::Util.rails_xss_safe?
def test_escape_html_option_set
assert Haml::Template.options[:escape_html]
@ -273,5 +276,13 @@ END
def test_xss_protection_with_mixed_strings_in_interpolation
assert_equal("Foo & Bar &amp; Baz\n", render('Foo #{"&".html_safe!} Bar #{"&"} Baz', :action_view))
end
def test_rendered_string_is_html_safe
assert(render("Foo").html_safe?)
end
def test_rendered_string_is_html_safe_with_action_view
assert(render("Foo", :action_view).html_safe?)
end
end
end