Skip to content

Commit

Permalink
Stop using i18n's built in HTML error handling.
Browse files Browse the repository at this point in the history
i18n doesn't depend on active support which means it can't use our html_safe
code to do its escaping when generating the spans.  Rather than try to sanitize
the output from i18n, just revert to our old behaviour of rescuing the error
and constructing the tag ourselves.

Fixes: CVE-2013-4491

Conflicts:
	actionpack/lib/action_view/helpers/translation_helper.rb

Backport: 50afd8eec9d088ad5a2d41f00a05520d5b78a6a0
  • Loading branch information
NZKoz authored and tenderlove committed Dec 2, 2013
1 parent 5ed70c5 commit 78790e4
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 14 deletions.
21 changes: 8 additions & 13 deletions actionpack/lib/action_view/helpers/translation_helper.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
require 'action_view/helpers/tag_helper'
require 'i18n/exceptions'

module I18n
class ExceptionHandler
include Module.new {
def call(exception, locale, key, options)
exception.is_a?(MissingTranslation) && options[:rescue_format] == :html ? super.html_safe : super
end
}
end
end

module ActionView
# = Action View Translation Helpers
module Helpers
module TranslationHelper
# Delegates to <tt>I18n#translate</tt> but also performs three additional functions.
#
# First, it'll pass the <tt>:rescue_format => :html</tt> option to I18n so that any
# thrown +MissingTranslation+ messages will be turned into inline spans that
# First, it will ensure that any thrown +MissingTranslation+ messages will be turned
# into inline spans that:
#
# * have a "translation-missing" class set,
# * contain the missing key as a title attribute and
Expand All @@ -44,7 +34,9 @@ module TranslationHelper
# naming convention helps to identify translations that include HTML tags so that
# you know what kind of output to expect when you call translate in a template.
def translate(key, options = {})
options.merge!(:rescue_format => :html) unless options.key?(:rescue_format)
# If the user has specified rescue_format then pass it all through, otherwise use
# raise and do the work ourselves
options[:raise] = true unless options.key?(:raise) || options.key?(:rescue_format)
if html_safe_translation_key?(key)
html_safe_options = options.dup
options.except(*I18n::RESERVED_KEYS).each do |name, value|
Expand All @@ -58,6 +50,9 @@ def translate(key, options = {})
else
I18n.translate(scope_key_by_partial(key), options)
end
rescue I18n::MissingTranslationData => e
keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
content_tag('span', keys.last.to_s.titleize, :class => 'translation_missing', :title => "translation missing: #{keys.join('.')}")
end
alias :t :translate

Expand Down
2 changes: 1 addition & 1 deletion actionpack/test/template/translation_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def setup
end

def test_delegates_to_i18n_setting_the_rescue_format_option_to_html
I18n.expects(:translate).with(:foo, :locale => 'en', :rescue_format => :html).returns("")
I18n.expects(:translate).with(:foo, :locale => 'en', :raise=>true).returns("")
translate :foo, :locale => 'en'
end

Expand Down

0 comments on commit 78790e4

Please sign in to comment.