diff options
Diffstat (limited to 'activesupport/lib/active_support/json.rb')
-rw-r--r-- | activesupport/lib/active_support/json.rb | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/activesupport/lib/active_support/json.rb b/activesupport/lib/active_support/json.rb index 2bdb4a7b11..6d845182fb 100644 --- a/activesupport/lib/active_support/json.rb +++ b/activesupport/lib/active_support/json.rb @@ -1,11 +1,74 @@ +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/module/attribute_accessors' + module ActiveSupport # If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format. mattr_accessor :use_standard_json_time_format + # Look for and parse json strings that look like ISO 8601 times. + mattr_accessor :parse_json_times - class << self - def escape_html_entities_in_json - @escape_html_entities_in_json + module JSON + # matches YAML-formatted dates + DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/ + + module Encoding #:nodoc: + mattr_accessor :escape_regex + + ESCAPED_CHARS = { + "\010" => '\b', + "\f" => '\f', + "\n" => '\n', + "\r" => '\r', + "\t" => '\t', + '"' => '\"', + '\\' => '\\\\', + '>' => '\u003E', + '<' => '\u003C', + '&' => '\u0026' + } + + def self.escape(string) + string = string.dup.force_encoding(::Encoding::BINARY) if string.respond_to?(:force_encoding) + json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }. + gsub(/([\xC0-\xDF][\x80-\xBF]| + [\xE0-\xEF][\x80-\xBF]{2}| + [\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s| + s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&') + } + %("#{json}") + end + end + + class << self + delegate :decode, :to => :backend + + def backend + unless defined? @backend + self.backend = defined?(::JSON) ? "JSONGem" : "Yaml" + end + @backend + end + + def backend=(name) + if name.is_a?(Module) + @backend = name + else + require "active_support/json/backends/#{name.to_s.downcase}.rb" + @backend = ActiveSupport::JSON::Backends::const_get(name) + end + end + + def with_backend(name) + old_backend, self.backend = backend, name + yield + ensure + self.backend = old_backend + end end + end + + class << self + attr_reader :escape_html_entities_in_json def escape_html_entities_in_json=(value) ActiveSupport::JSON::Encoding.escape_regex = \ @@ -19,5 +82,6 @@ module ActiveSupport end end +ActiveSupport.escape_html_entities_in_json = true + require 'active_support/json/encoding' -require 'active_support/json/decoding' |