Skip to content

Commit

Permalink
Unescape HTML entities (mastodon#24019)
Browse files Browse the repository at this point in the history
  • Loading branch information
c960657 authored and skerit committed Jul 7, 2023
1 parent a574a7c commit 577f735
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
6 changes: 5 additions & 1 deletion app/lib/plain_text_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def to_s
if local?
text
else
strip_tags(insert_newlines).chomp
html_entities.decode(strip_tags(insert_newlines)).chomp
end
end

Expand All @@ -27,4 +27,8 @@ def to_s
def insert_newlines
text.gsub(NEWLINE_TAGS_RE) { |match| "#{match}\n" }
end

def html_entities
HTMLEntities.new
end
end
61 changes: 56 additions & 5 deletions spec/lib/plain_text_formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,71 @@
describe '#to_s' do
subject { described_class.new(status.text, status.local?).to_s }

context 'given a post with local status' do
context 'when status is local' do
let(:status) { Fabricate(:status, text: '<p>a text by a nerd who uses an HTML tag in text</p>', uri: nil) }

it 'returns the raw text' do
expect(subject).to eq '<p>a text by a nerd who uses an HTML tag in text</p>'
end
end

context 'given a post with remote status' do
context 'when status is remote' do
let(:remote_account) { Fabricate(:account, domain: 'remote.test', username: 'bob', url: 'https://remote.test/') }
let(:status) { Fabricate(:status, account: remote_account, text: '<p>Hello</p><script>alert("Hello")</script>') }

it 'returns tag-stripped text' do
expect(subject).to eq 'Hello'
context 'when text contains inline HTML tags' do
let(:status) { Fabricate(:status, account: remote_account, text: '<b>Lorem</b> <em>ipsum</em>') }

it 'strips the tags' do
expect(subject).to eq 'Lorem ipsum'
end
end

context 'when text contains <p> tags' do
let(:status) { Fabricate(:status, account: remote_account, text: '<p>Lorem</p><p>ipsum</p>') }

it 'inserts a newline' do
expect(subject).to eq "Lorem\nipsum"
end
end

context 'when text contains a single <br> tag' do
let(:status) { Fabricate(:status, account: remote_account, text: 'Lorem<br>ipsum') }

it 'inserts a newline' do
expect(subject).to eq "Lorem\nipsum"
end
end

context 'when text contains consecutive <br> tag' do
let(:status) { Fabricate(:status, account: remote_account, text: 'Lorem<br><br><br>ipsum') }

it 'inserts a single newline' do
expect(subject).to eq "Lorem\nipsum"
end
end

context 'when text contains HTML entity' do
let(:status) { Fabricate(:status, account: remote_account, text: 'Lorem &amp; ipsum &#x2764;') }

it 'unescapes the entity' do
expect(subject).to eq 'Lorem & ipsum ❤'
end
end

context 'when text contains <script> tag' do
let(:status) { Fabricate(:status, account: remote_account, text: 'Lorem <script> alert("Booh!") </script>ipsum') }

it 'strips the tag and its contents' do
expect(subject).to eq 'Lorem ipsum'
end
end

context 'when text contains an HTML comment tags' do
let(:status) { Fabricate(:status, account: remote_account, text: 'Lorem <!-- Booh! -->ipsum') }

it 'strips the comment' do
expect(subject).to eq 'Lorem ipsum'
end
end
end
end
Expand Down

0 comments on commit 577f735

Please sign in to comment.