Skip to content
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ nav_order: 5

## main

* Fix html escaping in `#call` for non strings.

*Reegan Viljoen*

* Exclude html escaping of I18n reserved keys with `I18n::RESERVED_KEYS` rather than `I18n.reserved_keys_pattern`.

*Nick Coyne*
Expand Down
2 changes: 1 addition & 1 deletion lib/view_component/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def content_evaluated?

def maybe_escape_html(text)
return text if request && !request.format.html?
return text if text.nil? || text.empty?
return text if text.blank?

if text.html_safe?
text
Expand Down
18 changes: 18 additions & 0 deletions test/sandbox/app/components/inline_slot_html_escape_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class InlineSlotHtmlEscapeComponent < ViewComponent::Base
renders_one :empty_state

def initialize(counter:, heading:, url:)
@counter = counter
@heading = heading
@url = url
end

def call
return empty_state unless @heading.nil?

link_to @url do
@counter +
tag.p(@heading)
end
end
end
16 changes: 16 additions & 0 deletions test/sandbox/test/slotable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -752,4 +752,20 @@ def test_slot_names_can_start_with_call
end
end
end

def test_inline_slot_html_escape_with_integer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests don't appear to assert anything?

render_inline InlineSlotHtmlEscapeComponent.new(heading: "lorem ipsum", counter: 12, url: "/some_url") do |component|
component.with_empty_state do
"empty state"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense for this slot to return a non-string value? Otherwise we're testing the existing behavior and not the behavior mentioned in the issue.

end
end
end

def test_inline_slot_html_escape_with_json
render_inline InlineSlotHtmlEscapeComponent.new(heading: "lorem ipsum", counter: {foo: "bar"}.to_json, url: "/some_url") do |component|
component.with_empty_state do
"empty state"
end
end
end
end