diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index d9e0635295..d0d0433883 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Add config.active_support.escape_html_entities_in_json to allow disabling of html entity escaping. [rick] + * Improve documentation. [Xavier Noria] * Modified ActiveSupport::Callbacks::Callback#call to accept multiple arguments. diff --git a/activesupport/lib/active_support/json.rb b/activesupport/lib/active_support/json.rb index 5acb02dbe9..914cf4f8fe 100644 --- a/activesupport/lib/active_support/json.rb +++ b/activesupport/lib/active_support/json.rb @@ -1,9 +1,25 @@ -require 'active_support/json/encoding' -require 'active_support/json/decoding' + module ActiveSupport + # If true, use ISO 8601 format for dates and times. Otherwise, fall back to the ActiveSupport legacy format. mattr_accessor :use_standard_json_time_format + class << self + def escape_html_entities_in_json + @escape_html_entities_in_json + end + + def escape_html_entities_in_json=(value) + ActiveSupport::JSON::Encoding.escape_regex = \ + if value + /[\010\f\n\r\t"\\><&]/ + else + /[\010\f\n\r\t"\\]/ + end + @escape_html_entities_in_json = value + end + end + module JSON RESERVED_WORDS = %w( abstract delete goto private transient @@ -31,3 +47,6 @@ module ActiveSupport end end end + +require 'active_support/json/encoding' +require 'active_support/json/decoding' diff --git a/activesupport/lib/active_support/json/encoders/string.rb b/activesupport/lib/active_support/json/encoders/string.rb index 20ca91f9aa..5ef797955a 100644 --- a/activesupport/lib/active_support/json/encoders/string.rb +++ b/activesupport/lib/active_support/json/encoders/string.rb @@ -1,6 +1,8 @@ module ActiveSupport module JSON module Encoding + mattr_accessor :escape_regex + ESCAPED_CHARS = { "\010" => '\b', "\f" => '\f', @@ -17,9 +19,11 @@ module ActiveSupport end end +ActiveSupport.escape_html_entities_in_json = true + class String def to_json(options = nil) #:nodoc: - json = '"' + gsub(/[\010\f\n\r\t"\\><&]/) { |s| + json = '"' + gsub(ActiveSupport::JSON::Encoding.escape_regex) { |s| ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s] } json.force_encoding('ascii-8bit') if respond_to?(:force_encoding) diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index adfbfd5f72..8650e34228 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -1,5 +1,4 @@ require 'active_support/json/variable' - require 'active_support/json/encoders/object' # Require explicitly for rdoc. Dir["#{File.dirname(__FILE__)}/encoders/**/*.rb"].each do |file| basename = File.basename(file, '.rb') diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index 290232988a..7bc8eaf06c 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -38,15 +38,18 @@ class TestJSONEncoding < Test::Unit::TestCase StandardDateTests = [[ Date.new(2005,2,1), %("2005-02-01") ]] StandardTimeTests = [[ Time.utc(2005,2,1,15,15,10), %("2005-02-01T15:15:10Z") ]] StandardDateTimeTests = [[ DateTime.civil(2005,2,1,15,15,10), %("2005-02-01T15:15:10+00:00") ]] + StandardStringTests = [[ 'this is the ', %("this is the ")]] constants.grep(/Tests$/).each do |class_tests| define_method("test_#{class_tests[0..-6].underscore}") do begin + ActiveSupport.escape_html_entities_in_json = class_tests !~ /^Standard/ ActiveSupport.use_standard_json_time_format = class_tests =~ /^Standard/ self.class.const_get(class_tests).each do |pair| assert_equal pair.last, pair.first.to_json end ensure + ActiveSupport.escape_html_entities_in_json = false ActiveSupport.use_standard_json_time_format = false end end