diff options
-rw-r--r-- | activerecord/lib/active_record/enum.rb | 3 | ||||
-rw-r--r-- | activerecord/test/cases/enum_test.rb | 4 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/string/output_safety.rb | 24 |
3 files changed, 19 insertions, 12 deletions
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb index 9ad718a02a..d1bc785bee 100644 --- a/activerecord/lib/active_record/enum.rb +++ b/activerecord/lib/active_record/enum.rb @@ -87,6 +87,9 @@ module ActiveRecord # def status() STATUS.key self[:status] end define_method(name) { enum_values.key self[name] } + # def status_before_type_cast() STATUS.key self[:status] end + define_method("#{name}_before_type_cast") { enum_values.key self[name] } + pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index pairs.each do |value, i| enum_values[value] = i diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index c09e58fbf1..0075df8b8d 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -88,4 +88,8 @@ class EnumTest < ActiveRecord::TestCase assert Book.written.create.written? assert Book.read.create.read? end + + test "_before_type_cast returns the enum label (required for form fields)" do + assert_equal "proposed", @book.status_before_type_cast + end end diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 1b20507c0b..eb02b6a442 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -70,9 +70,20 @@ class ERB # them inside a script tag to avoid XSS vulnerability: # # <script> - # var currentUser = <%= json_escape current_user.to_json %>; + # var currentUser = <%= raw json_escape(current_user.to_json) %>; # </script> # + # It is necessary to +raw+ the result of +json_escape+, so that quotation marks + # don't get converted to <tt>"</tt> entities. +json_escape+ doesn't + # automatically flag the result as HTML safe, since the raw value is unsafe to + # use inside HTML attributes. + # + # If you need to output JSON elsewhere in your HTML, you can just do something + # like this, as any unsafe characters (including quotation marks) will be + # automatically escaped for you: + # + # <div data-user-info="<%= current_user.to_json %>">...</div> + # # WARNING: this helper only works with valid JSON. Using this on non-JSON values # will open up serious XSS vulnerabilities. For example, if you replace the # +current_user.to_json+ in the example above with user input instead, the browser @@ -88,17 +99,6 @@ class ERB # is recommended that you always apply this helper (other libraries, such as the # JSON gem, do not provide this kind of protection by default; also some gems # might override +to_json+ to bypass Active Support's encoder). - # - # The output of this helper method is marked as HTML safe so that you can directly - # include it inside a <tt><script></tt> tag as shown above. - # - # However, it is NOT safe to use the output of this inside an HTML attribute, - # because quotation marks are not escaped. Doing so might break your page's layout. - # If you intend to use this inside an HTML attribute, you should use the - # +html_escape+ helper (or its +h+ alias) instead: - # - # <div data-user-info="<%= h current_user.to_json %>">...</div> - # def json_escape(s) result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE) s.html_safe? ? result.html_safe : result |