aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md2
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb19
-rw-r--r--activesupport/lib/active_support/message_encryptor.rb14
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb5
-rw-r--r--activesupport/test/multibyte_chars_test.rb3
5 files changed, 42 insertions, 1 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 5df3ec406f..ad9a12fc9b 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,5 +1,7 @@
## Rails 4.0.0 (unreleased) ##
+* Add html_escape_once to ERB::Util, and delegate escape_once tag helper to it. *Carlos Antonio da Silva*
+
* Remove ActiveSupport::TestCase#pending method, use `skip` instead. *Carlos Antonio da Silva*
* Deprecates the compatibility method Module#local_constant_names,
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 73aa7dd89a..dd780da157 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -5,6 +5,8 @@ class ERB
module Util
HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
+ HTML_ESCAPE_ONCE_REGEXP = /[\"><]|&(?!([a-zA-Z]+|(#\d+));)/
+ JSON_ESCAPE_REGEXP = /[&"><]/
# A utility method for escaping HTML tag characters.
# This method is also aliased as <tt>h</tt>.
@@ -33,6 +35,21 @@ class ERB
singleton_class.send(:remove_method, :html_escape)
module_function :html_escape
+ # A utility method for escaping HTML without affecting existing escaped entities.
+ #
+ # ==== Examples
+ # html_escape_once("1 < 2 &amp; 3")
+ # # => "1 &lt; 2 &amp; 3"
+ #
+ # html_escape_once("&lt;&lt; Accept & Checkout")
+ # # => "&lt;&lt; Accept &amp; Checkout"
+ def html_escape_once(s)
+ result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP) { |special| HTML_ESCAPE[special] }
+ s.html_safe? ? result.html_safe : result
+ end
+
+ module_function :html_escape_once
+
# A utility method for escaping HTML entities in JSON strings
# using \uXXXX JavaScript escape sequences for string literals:
#
@@ -51,7 +68,7 @@ class ERB
# <%=j @person.to_json %>
#
def json_escape(s)
- result = s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
+ result = s.to_s.gsub(JSON_ESCAPE_REGEXP) { |special| JSON_ESCAPE[special] }
s.html_safe? ? result.html_safe : result
end
diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb
index 6ec5a04933..ada2e79ccb 100644
--- a/activesupport/lib/active_support/message_encryptor.rb
+++ b/activesupport/lib/active_support/message_encryptor.rb
@@ -9,6 +9,11 @@ module ActiveSupport
#
# This can be used in situations similar to the <tt>MessageVerifier</tt>, but where you don't
# want users to be able to determine the value of the payload.
+ #
+ # key = OpenSSL::Digest::SHA256.new('password').digest # => "\x89\xE0\x156\xAC..."
+ # crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
+ # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
+ # crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
class MessageEncryptor
module NullSerializer #:nodoc:
def self.load(value)
@@ -23,6 +28,15 @@ module ActiveSupport
class InvalidMessage < StandardError; end
OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
+ # Initialize a new MessageEncryptor.
+ # +secret+ must be at least as long as the cipher key size. For the default 'aes-256-cbc' cipher,
+ # this is 256 bits. If you are using a user-entered secret, you can generate a suitable key with
+ # <tt>OpenSSL::Digest::SHA256.new(user_secret).digest</tt> or similar.
+ #
+ # Options:
+ # * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'
+ # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
+ #
def initialize(secret, options = {})
@secret = secret
@cipher = options[:cipher] || 'aes-256-cbc'
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index ac61870871..9a748dfa60 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -1,4 +1,5 @@
# encoding: utf-8
+require 'active_support/json'
require 'active_support/core_ext/string/access'
require 'active_support/core_ext/string/behavior'
require 'active_support/core_ext/module/delegation'
@@ -188,6 +189,10 @@ module ActiveSupport #:nodoc:
chars(Unicode.tidy_bytes(@wrapped_string, force))
end
+ def as_json(options = nil) #:nodoc:
+ to_s.as_json(options)
+ end
+
%w(capitalize downcase reverse tidy_bytes upcase).each do |method|
define_method("#{method}!") do |*args|
@wrapped_string = send(method, *args).to_s
diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb
index 63e7a35c01..90aa13b3e6 100644
--- a/activesupport/test/multibyte_chars_test.rb
+++ b/activesupport/test/multibyte_chars_test.rb
@@ -88,6 +88,9 @@ class MultibyteCharsTest < ActiveSupport::TestCase
assert(('a'.mb_chars << 'b'.mb_chars).kind_of?(@proxy_class))
end
+ def test_should_return_string_as_json
+ assert_equal UNICODE_STRING, @chars.as_json
+ end
end
class MultibyteCharsUTF8BehaviourTest < ActiveSupport::TestCase