Skip to content

Commit

Permalink
Fix invalid byte sequence in UTF-8 in event mailer
Browse files Browse the repository at this point in the history
Sometimes the build log contains invalid UTF-8 characters that raise an
exception during email composing.

Fixes #6872
  • Loading branch information
danidoni committed Feb 3, 2022
1 parent 944d7ec commit 5fd0ee4
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
18 changes: 17 additions & 1 deletion src/api/app/mailers/event_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def event(subscribers, e)

set_headers
begin
locals = { event: e.expanded_payload }
locals = { event: sanitize_expanded_payload(e.expanded_payload) }
rescue Project::UnknownObjectError, Package::UnknownObjectError
# object got removed already
return
Expand All @@ -52,4 +52,20 @@ def event(subscribers, e)
format.text { render template_name, locals: locals } if template_exists?("event_mailer/#{template_name}", formats: [:text])
end
end

private

# Reencode the fail log replacing invalid UTF-8 characters with the default unicode replacement character: '\ufffd'
# source: https://stackoverflow.com/a/24493972
def reencode_faillog(faillog)
faillog.encode!('UTF-8', 'UTF-8', invalid: :replace)
end

def sanitize_expanded_payload(payload)
if payload['faillog']
payload.merge('faillog' => reencode_faillog(payload.delete('faillog')))
else
payload
end
end
end
34 changes: 34 additions & 0 deletions src/api/spec/mailers/event_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,39 @@
expect(ActionMailer::Base.deliveries).to be_empty
end
end

context 'when trying to compose an email containing invalid byte sequences' do
let(:expanded_payload) do
{
'project' => 'project_2',
'package' => 'package_2',
'repository' => 'repository_2',
'arch' => 'i585',
'faillog' => "invalid byte sequence ->\xD3'"
}
end
let(:from) { create(:confirmed_user) }
let(:recipient) { create(:confirmed_user) }
let(:event_stub) do
instance_double('Event::Base',
expanded_payload: expanded_payload,
custom_headers: {},
template_name: 'build_fail',
originator: from,
subject: 'Test email',
created_at: Time.zone.now)
end
let(:mail) { EventMailer.event([recipient], event_stub) }

it 'renders the headers' do
expect(mail.subject).to eq('Test email')
expect(mail.to).to eq([recipient.email])
expect(mail.from).to eq([from.email])
end

it 'renders the body' do
expect(mail.body.encoded).to match('Package project_2/package_2 failed to build in repository_2/i585')
end
end
end
end

0 comments on commit 5fd0ee4

Please sign in to comment.