aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/json
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2013-11-06 17:17:07 -0800
committerJeremy Kemper <jeremy@bitsweat.net>2013-11-06 17:17:07 -0800
commit240863a1680bbb7da00bac68e8aa1ee996bcdb57 (patch)
tree5518edc1602caa1f36985f9ea8f9a725fa99fed2 /activesupport/lib/active_support/json
parent5584ddc43da6f3275c45305f50d934e505750f8c (diff)
parent798881ecd4510b9e1e5e10529fc2d81b9deb961e (diff)
downloadrails-240863a1680bbb7da00bac68e8aa1ee996bcdb57.tar.gz
rails-240863a1680bbb7da00bac68e8aa1ee996bcdb57.tar.bz2
rails-240863a1680bbb7da00bac68e8aa1ee996bcdb57.zip
Merge pull request #12785 from chancancode/do_not_leak_internal_state
Do not expose internal state in the public encoder API (i.e. as_json)
Diffstat (limited to 'activesupport/lib/active_support/json')
-rw-r--r--activesupport/lib/active_support/json/decoding.rb3
-rw-r--r--activesupport/lib/active_support/json/encoding.rb64
2 files changed, 27 insertions, 40 deletions
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb
index 315c76199a..8b5fc70dee 100644
--- a/activesupport/lib/active_support/json/decoding.rb
+++ b/activesupport/lib/active_support/json/decoding.rb
@@ -7,6 +7,9 @@ module ActiveSupport
mattr_accessor :parse_json_times
module JSON
+ # matches YAML-formatted dates
+ DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
+
class << self
# Parses a JSON string (JavaScript Object Notation) into a hash.
# See www.json.org for more info.
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 4d73672047..c9840e9faa 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -10,7 +10,6 @@ require 'active_support/core_ext/object/instance_variables'
require 'active_support/core_ext/time/conversions'
require 'active_support/core_ext/date_time/conversions'
require 'active_support/core_ext/date/conversions'
-require 'set'
module ActiveSupport
class << self
@@ -21,9 +20,6 @@ module ActiveSupport
end
module JSON
- # matches YAML-formatted dates
- DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
-
# Dumps objects in JSON (JavaScript Object Notation).
# See www.json.org for more info.
#
@@ -34,56 +30,22 @@ module ActiveSupport
end
module Encoding #:nodoc:
- class CircularReferenceError < StandardError; end
-
class Encoder
attr_reader :options
def initialize(options = nil)
@options = options || {}
- @seen = Set.new
- end
-
- def encode(value, use_options = true)
- check_for_circular_references(value) do
- jsonified = use_options ? value.as_json(options_for(value)) : value.as_json
- jsonified.encode_json(self)
- end
end
- # like encode, but only calls as_json, without encoding to string.
- def as_json(value, use_options = true)
- check_for_circular_references(value) do
- use_options ? value.as_json(options_for(value)) : value.as_json
- end
- end
-
- def options_for(value)
- if value.is_a?(Array) || value.is_a?(Hash)
- # hashes and arrays need to get encoder in the options, so that
- # they can detect circular references.
- options.merge(:encoder => self)
- else
- options.dup
- end
+ def encode(value)
+ value.as_json(options.dup).encode_json(self)
end
def escape(string)
Encoding.escape(string)
end
-
- private
- def check_for_circular_references(value)
- unless @seen.add?(value.__id__)
- raise CircularReferenceError, 'object references itself'
- end
- yield
- ensure
- @seen.delete(value.__id__)
- end
end
-
ESCAPED_CHARS = {
"\x00" => '\u0000', "\x01" => '\u0001', "\x02" => '\u0002',
"\x03" => '\u0003', "\x04" => '\u0004', "\x05" => '\u0005',
@@ -138,6 +100,28 @@ module ActiveSupport
json.force_encoding(::Encoding::UTF_8)
json
end
+
+ # Deprecate CircularReferenceError
+ def const_missing(name)
+ if name == :CircularReferenceError
+ message = "The JSON encoder in Rails 4.1 no longer offers protection from circular references. " \
+ "You are seeing this warning because you are rescuing from (or otherwise referencing) " \
+ "ActiveSupport::Encoding::CircularReferenceError. In the future, this error will be " \
+ "removed from Rails. You should remove these rescue blocks from your code and ensure " \
+ "that your data structures are free of circular references so they can be properly " \
+ "serialized into JSON.\n\n" \
+ "For example, the following Hash contains a circular reference to itself:\n" \
+ " h = {}\n" \
+ " h['circular'] = h\n" \
+ "In this case, calling h.to_json would not work properly."
+
+ ActiveSupport::Deprecation.warn message
+
+ SystemStackError
+ else
+ super
+ end
+ end
end
self.use_standard_json_time_format = true