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 openSUSE#6872
  • Loading branch information
danidoni committed Feb 3, 2022
1 parent 944d7ec commit 6309ce6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/api/app/mailers/event_mailer.rb
Expand Up @@ -26,7 +26,7 @@ def event(subscribers, e)

set_headers
begin
locals = { event: e.expanded_payload }
locals = { event: sanitize_expanded_payload(e) }
rescue Project::UnknownObjectError, Package::UnknownObjectError
# object got removed already
return
Expand All @@ -52,4 +52,16 @@ 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 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(event)
event.expanded_payload.merge('faillog' => reencode_faillog(event.expanded_payload.delete('faillog')))
end
end
37 changes: 37 additions & 0 deletions src/api/spec/mailers/another_event_mailer_spec.rb
@@ -0,0 +1,37 @@
require 'rails_helper'

RSpec.describe EventMailer, type: :mailer do
describe '#event' 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
double(:event,
expanded_payload: expanded_payload,
custom_headers: {},
template_name: 'build_fail',
originator: from,
subject: 'Test email',
created_at: Time.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

0 comments on commit 6309ce6

Please sign in to comment.