FIX: during concurrent emails generation renderer should not be reused

Our instance used for template rendering needs a lock to ensure there is
no race condition where rendering happens on 2 threads at the same time.

This can lead to local poisoning which can cause unexpected results in
emails
This commit is contained in:
Sam Saffron 2019-10-10 08:50:48 +11:00
parent 04452e748d
commit 5aaf7e3316
4 changed files with 13 additions and 7 deletions

View File

@ -589,7 +589,7 @@ class UserNotifications < ActionMailer::Base
end
unless translation_override_exists
html = UserNotificationRenderer.instance.render(
html = UserNotificationRenderer.render(
template: 'email/notification',
format: :html,
locals: { context_posts: context_posts,

View File

@ -5,9 +5,15 @@ class UserNotificationRenderer < ActionView::Base
include UserNotificationsHelper
include EmailHelper
def self.instance
@instance ||= UserNotificationRenderer.with_view_paths(
Rails.configuration.paths["app/views"]
)
LOCK = Mutex.new
def self.render(*args)
LOCK.synchronize do
@instance ||= UserNotificationRenderer.with_view_paths(
Rails.configuration.paths["app/views"]
)
@instance.render(*args)
end
end
end

View File

@ -94,7 +94,7 @@ module Email
html_override.gsub!("%{respond_instructions}", "")
end
html = UserNotificationRenderer.instance.render(
html = UserNotificationRenderer.render(
template: 'layouts/email_template',
format: :html,
locals: { html_body: html_override.html_safe }

View File

@ -18,7 +18,7 @@ module Email
style = if @message.html_part
Email::Styles.new(@message.html_part.body.to_s, @opts)
else
unstyled = UserNotificationRenderer.instance.render(
unstyled = UserNotificationRenderer.render(
template: 'layouts/email_template',
format: :html,
locals: { html_body: PrettyText.cook(text).html_safe }