Skip to content

Commit

Permalink
Merge pull request rails#54226 from intrip/actiontext-plaintext-skip-…
Browse files Browse the repository at this point in the history
…script-and-style

Don't include `script` and `style` content to node plaintext conversion
  • Loading branch information
byroot authored Jan 15, 2025
2 parents b73e978 + bd0729c commit 8c7e394
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
3 changes: 2 additions & 1 deletion actiontext/lib/action_text/content.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,11 @@ def render_attachment_galleries(&block)
# content.to_plain_text # => "safeunsafe"
#
# NOTE: that the returned string is not HTML safe and should not be rendered in
# browsers.
# browsers without additional sanitization.
#
# content = ActionText::Content.new("<script>alert()</script>")
# content.to_plain_text # => "<script>alert()</script>"
# ActionText::ContentHelper.sanitizer.sanitize(content.to_plain_text) # => ""
def to_plain_text
render_attachments(with_full_attributes: false, &:to_plain_text).fragment.to_plain_text
end
Expand Down
6 changes: 6 additions & 0 deletions actiontext/lib/action_text/plain_text_conversion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ def plain_text_for_node(node, index = 0)
def plain_text_for_node_children(node)
texts = []
node.children.each_with_index do |child, index|
next if skippable?(child)

texts << plain_text_for_node(child, index)
end
texts.join
end

def skippable?(node)
node.name == "script" || node.name == "style"
end

def plain_text_method_for_node(node)
:"plain_text_for_#{node.name}_node"
end
Expand Down
24 changes: 24 additions & 0 deletions actiontext/test/unit/plain_text_conversion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,30 @@ class ActionText::PlainTextConversionTest < ActiveSupport::TestCase
)
end

test "script tags are ignored" do
assert_converted_to(
"Hello world!",
<<~HTML
<script type="javascript">
console.log("message");
</script>
<div><strong>Hello </strong>world!</div>
HTML
)
end

test "style tags are ignored" do
assert_converted_to(
"Hello world!",
<<~HTML
<style type="text/css">
body { color: red; }
</style>
<div><strong>Hello </strong>world!</div>
HTML
)
end

private
def assert_converted_to(plain_text, html)
assert_equal plain_text, ActionText::Content.new(html).to_plain_text
Expand Down
4 changes: 2 additions & 2 deletions guides/source/action_text_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ content as follows:

`ActionText::RichText#to_s` safely transforms RichText into an HTML String. On
the other hand `ActionText::RichText#to_plain_text` returns a string that is not
HTML safe and should not be rendered in browsers. You can learn more about
Action Text's sanitization process in the [`ActionText::RichText`
HTML safe and should not be rendered in browsers without additional sanitization.
You can learn more about Action Text's sanitization process in the [`ActionText::RichText`
documentation](https://api.rubyonrails.org/classes/ActionText/RichText.html).

NOTE: If there's an attached resource within `content` field, it might not show
Expand Down

0 comments on commit 8c7e394

Please sign in to comment.