Skip to content

Commit 5f189f4

Browse files
committed
Introduce ActionView::Template::Handlers::ERB.escape_whitelist.
This is a list of mime types where template text is not html escaped by default. It prevents `Jack & Joe` from rendering as `Jack & Joe` for the whitelisted mime types. The default whitelist contains text/plain. This follows a whitelist approach where plain text templates are not escaped, and all the others (json, xml) are. The mime type is assumed to be set by the abstract controller.
1 parent 44f12bb commit 5f189f4

3 files changed

Lines changed: 27 additions & 1 deletion

File tree

actionpack/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343

4444
*Josh Peek*
4545

46+
* Introduce `ActionView::Template::Handlers::ERB.escape_whitelist`. This is a list
47+
of mime types where template text is not html escaped by default. It prevents `Jack & Joe`
48+
from rendering as `Jack & Joe` for the whitelisted mime types. The default whitelist
49+
contains text/plain. Fix #7976
50+
51+
*Joost Baaij*
52+
4653
* `assert_template` can be used to assert on the same template with different locals
4754
Fix #3675
4855

actionpack/lib/action_view/template/handlers/erb.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class ERB
4747
class_attribute :erb_implementation
4848
self.erb_implementation = Erubis
4949

50+
# Do not escape templates of these mime types.
51+
class_attribute :escape_whitelist
52+
self.escape_whitelist = ["text/plain"]
53+
5054
ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
5155

5256
def self.call(template)
@@ -78,6 +82,7 @@ def call(template)
7882

7983
self.class.erb_implementation.new(
8084
erb,
85+
:escape => (self.class.escape_whitelist.include? template.type),
8186
:trim => (self.class.erb_trim_mode == "-")
8287
).src
8388
end

actionpack/test/template/template_test.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ def hello
2626
"Hello"
2727
end
2828

29+
def apostrophe
30+
"l'apostrophe"
31+
end
32+
2933
def partial
3034
ActionView::Template.new(
3135
"<%= @virtual_path %>",
@@ -48,7 +52,7 @@ def my_buffer
4852
end
4953
end
5054

51-
def new_template(body = "<%= hello %>", details = {})
55+
def new_template(body = "<%= hello %>", details = {format: html})
5256
ActionView::Template.new(body, "hello template", details.fetch(:handler) { ERBHandler }, {:virtual_path => "hello"}.merge!(details))
5357
end
5458

@@ -72,6 +76,16 @@ def test_basic_template
7276
assert_equal "Hello", render
7377
end
7478

79+
def test_basic_template_does_html_escape
80+
@template = new_template("<%= apostrophe %>")
81+
assert_equal "l&#39;apostrophe", render
82+
end
83+
84+
def test_text_template_does_not_html_escape
85+
@template = new_template("<%= apostrophe %>", format: text)
86+
assert_equal "l'apostrophe", render
87+
end
88+
7589
def test_raw_template
7690
@template = new_template("<%= hello %>", :handler => ActionView::Template::Handlers::Raw.new)
7791
assert_equal "<%= hello %>", render

0 commit comments

Comments
 (0)