Skip to content

Commit fad9050

Browse files
Merge pull request rails#47318 from seanpdoyle/token-list-escaping
`token_list`: Guard Stimulus' `data-action` from multiple escapes
2 parents 17a9904 + 812e50b commit fad9050

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

actionview/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Guard `token_list` calls from escaping HTML too often
2+
3+
*Sean Doyle*
4+
15
* `select` can now be called with a single hash containing options and some HTML options
26

37
Previously this would not work as expected:

actionview/lib/action_view/helpers/tag_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ def content_tag(name, content_or_options_with_block = nil, options = nil, escape
363363
# token_list(nil, false, 123, "", "foo", { bar: true })
364364
# # => "123 foo bar"
365365
def token_list(*args)
366-
tokens = build_tag_values(*args).flat_map { |value| value.to_s.split(/\s+/) }.uniq
366+
tokens = build_tag_values(*args).flat_map { |value| CGI.unescape_html(value.to_s).split(/\s+/) }.uniq
367367

368368
safe_join(tokens, " ")
369369
end

actionview/test/template/tag_helper_test.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,29 @@ def test_token_list_and_class_names
448448
end
449449
end
450450

451+
def test_token_list_and_class_names_returns_an_html_safe_string
452+
assert_predicate token_list("a value"), :html_safe?
453+
assert_predicate class_names("a value"), :html_safe?
454+
end
455+
456+
def test_token_list_and_class_names_only_html_escape_once
457+
[:token_list, :class_names].each do |helper_method|
458+
helper = ->(*arguments) { public_send(helper_method, *arguments) }
459+
460+
tokens = %w[
461+
click->controller#action1
462+
click->controller#action2
463+
click->controller#action3
464+
click->controller#action4
465+
]
466+
467+
token_list = tokens.reduce(&helper)
468+
469+
assert_predicate token_list, :html_safe?
470+
assert_equal tokens, (CGI.unescape_html(token_list)).split
471+
end
472+
end
473+
451474
def test_content_tag_with_data_attributes
452475
assert_dom_equal '<p data-number="1" data-string="hello" data-string-with-quotes="double&quot;quote&quot;party&quot;">limelight</p>',
453476
content_tag("p", "limelight", data: { number: 1, string: "hello", string_with_quotes: 'double"quote"party"' })

0 commit comments

Comments
 (0)