activesupport 3.2.22.5 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -136
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -2
- data/lib/active_support.rb +8 -21
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache.rb +203 -171
- data/lib/active_support/cache/file_store.rb +12 -12
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/callbacks.rb +195 -247
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +113 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +11 -14
- data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
- data/lib/active_support/core_ext/class/attribute.rb +12 -8
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date.rb +6 -0
- data/lib/active_support/core_ext/date/calculations.rb +34 -188
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/infinite_comparable.rb +35 -0
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +19 -0
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +57 -40
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +6 -6
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +1 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/string.rb +2 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +29 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time.rb +6 -0
- data/lib/active_support/core_ext/time/calculations.rb +105 -193
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +112 -37
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber.rb +56 -36
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +32 -29
- data/lib/active_support/message_verifier.rb +8 -14
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/notifications.rb +57 -25
- data/lib/active_support/notifications/fanout.rb +105 -18
- data/lib/active_support/notifications/instrumenter.rb +32 -13
- data/lib/active_support/number_helper.rb +636 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +52 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +25 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +78 -43
- data/lib/active_support/values/time_zone.rb +77 -58
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +4 -4
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support/xml_mini/jdom.rb +9 -17
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- metadata +107 -77
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/memoizable.rb +0 -116
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
@@ -8,7 +8,7 @@ module ActiveSupport
|
|
8
8
|
# Replaces non-ASCII characters with an ASCII approximation, or if none
|
9
9
|
# exists, a replacement character which defaults to "?".
|
10
10
|
#
|
11
|
-
# transliterate(
|
11
|
+
# transliterate('Ærøskøbing')
|
12
12
|
# # => "AEroskobing"
|
13
13
|
#
|
14
14
|
# Default approximations are provided for Western/Latin characters,
|
@@ -30,33 +30,33 @@ module ActiveSupport
|
|
30
30
|
# ö: "oe"
|
31
31
|
#
|
32
32
|
# # Or set them using Ruby
|
33
|
-
# I18n.backend.store_translations(:de, :
|
34
|
-
# :
|
35
|
-
# :
|
36
|
-
#
|
37
|
-
#
|
33
|
+
# I18n.backend.store_translations(:de, i18n: {
|
34
|
+
# transliterate: {
|
35
|
+
# rule: {
|
36
|
+
# 'ü' => 'ue',
|
37
|
+
# 'ö' => 'oe'
|
38
38
|
# }
|
39
39
|
# }
|
40
40
|
# })
|
41
41
|
#
|
42
|
-
# The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that
|
43
|
-
# characters to ASCII approximations as shown above, or, for more
|
44
|
-
# requirements, a Proc:
|
42
|
+
# The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that
|
43
|
+
# maps characters to ASCII approximations as shown above, or, for more
|
44
|
+
# complex requirements, a Proc:
|
45
45
|
#
|
46
|
-
# I18n.backend.store_translations(:de, :
|
47
|
-
# :
|
48
|
-
# :
|
46
|
+
# I18n.backend.store_translations(:de, i18n: {
|
47
|
+
# transliterate: {
|
48
|
+
# rule: ->(string) { MyTransliterator.transliterate(string) }
|
49
49
|
# }
|
50
50
|
# })
|
51
51
|
#
|
52
52
|
# Now you can have different transliterations for each locale:
|
53
53
|
#
|
54
54
|
# I18n.locale = :en
|
55
|
-
# transliterate(
|
55
|
+
# transliterate('Jürgen')
|
56
56
|
# # => "Jurgen"
|
57
57
|
#
|
58
58
|
# I18n.locale = :de
|
59
|
-
# transliterate(
|
59
|
+
# transliterate('Jürgen')
|
60
60
|
# # => "Juergen"
|
61
61
|
def transliterate(string, replacement = "?")
|
62
62
|
I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
|
@@ -64,9 +64,8 @@ module ActiveSupport
|
|
64
64
|
:replacement => replacement)
|
65
65
|
end
|
66
66
|
|
67
|
-
# Replaces special characters in a string so that it may be used as part of
|
68
|
-
#
|
69
|
-
# ==== Examples
|
67
|
+
# Replaces special characters in a string so that it may be used as part of
|
68
|
+
# a 'pretty' URL.
|
70
69
|
#
|
71
70
|
# class Person
|
72
71
|
# def to_param
|
@@ -8,14 +8,13 @@ module ActiveSupport
|
|
8
8
|
|
9
9
|
module JSON
|
10
10
|
class << self
|
11
|
+
# Parses a JSON string (JavaScript Object Notation) into a hash.
|
12
|
+
# See www.json.org for more info.
|
13
|
+
#
|
14
|
+
# ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
|
15
|
+
# => {"team" => "rails", "players" => "36"}
|
11
16
|
def decode(json, options ={})
|
12
|
-
|
13
|
-
# a reserved word. Use adapter as a proxy for new features.
|
14
|
-
data = if MultiJson.respond_to?(:adapter)
|
15
|
-
MultiJson.load(json, options)
|
16
|
-
else
|
17
|
-
MultiJson.decode(json, options)
|
18
|
-
end
|
17
|
+
data = MultiJson.load(json, options)
|
19
18
|
if ActiveSupport.parse_json_times
|
20
19
|
convert_dates_from(data)
|
21
20
|
else
|
@@ -24,20 +23,12 @@ module ActiveSupport
|
|
24
23
|
end
|
25
24
|
|
26
25
|
def engine
|
27
|
-
|
28
|
-
MultiJson.adapter
|
29
|
-
else
|
30
|
-
MultiJson.engine
|
31
|
-
end
|
26
|
+
MultiJson.adapter
|
32
27
|
end
|
33
28
|
alias :backend :engine
|
34
29
|
|
35
30
|
def engine=(name)
|
36
|
-
|
37
|
-
MultiJson.use name
|
38
|
-
else
|
39
|
-
MultiJson.engine = name
|
40
|
-
end
|
31
|
+
MultiJson.use(name)
|
41
32
|
end
|
42
33
|
alias :backend= :engine=
|
43
34
|
|
@@ -48,6 +39,16 @@ module ActiveSupport
|
|
48
39
|
self.backend = old_backend
|
49
40
|
end
|
50
41
|
|
42
|
+
# Returns the class of the error that will be raised when there is an
|
43
|
+
# error in decoding JSON. Using this method means you won't directly
|
44
|
+
# depend on the ActiveSupport's JSON implementation, in case it changes
|
45
|
+
# in the future.
|
46
|
+
#
|
47
|
+
# begin
|
48
|
+
# obj = ActiveSupport::JSON.decode(some_string)
|
49
|
+
# rescue ActiveSupport::JSON.parse_error
|
50
|
+
# Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}")
|
51
|
+
# end
|
51
52
|
def parse_error
|
52
53
|
MultiJson::DecodeError
|
53
54
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'active_support/core_ext/object/to_json'
|
2
2
|
require 'active_support/core_ext/module/delegation'
|
3
3
|
require 'active_support/json/variable'
|
4
|
-
require 'active_support/ordered_hash'
|
5
4
|
|
6
5
|
require 'bigdecimal'
|
7
6
|
require 'active_support/core_ext/big_decimal/conversions' # for #to_s
|
8
|
-
require 'active_support/core_ext/array/wrap'
|
9
7
|
require 'active_support/core_ext/hash/except'
|
10
8
|
require 'active_support/core_ext/hash/slice'
|
11
9
|
require 'active_support/core_ext/object/instance_variables'
|
@@ -19,6 +17,7 @@ module ActiveSupport
|
|
19
17
|
class << self
|
20
18
|
delegate :use_standard_json_time_format, :use_standard_json_time_format=,
|
21
19
|
:escape_html_entities_in_json, :escape_html_entities_in_json=,
|
20
|
+
:encode_big_decimal_as_string, :encode_big_decimal_as_string=,
|
22
21
|
:to => :'ActiveSupport::JSON::Encoding'
|
23
22
|
end
|
24
23
|
|
@@ -26,7 +25,11 @@ module ActiveSupport
|
|
26
25
|
# matches YAML-formatted dates
|
27
26
|
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})?))$/
|
28
27
|
|
29
|
-
# Dumps
|
28
|
+
# Dumps objects in JSON (JavaScript Object Notation).
|
29
|
+
# See www.json.org for more info.
|
30
|
+
#
|
31
|
+
# ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
|
32
|
+
# # => "{\"team\":\"rails\",\"players\":\"36\"}"
|
30
33
|
def self.encode(value, options = nil)
|
31
34
|
Encoding::Encoder.new(options).encode(value)
|
32
35
|
end
|
@@ -49,7 +52,7 @@ module ActiveSupport
|
|
49
52
|
end
|
50
53
|
end
|
51
54
|
|
52
|
-
# like encode, but only calls as_json, without encoding to string
|
55
|
+
# like encode, but only calls as_json, without encoding to string.
|
53
56
|
def as_json(value, use_options = true)
|
54
57
|
check_for_circular_references(value) do
|
55
58
|
use_options ? value.as_json(options_for(value)) : value.as_json
|
@@ -58,7 +61,8 @@ module ActiveSupport
|
|
58
61
|
|
59
62
|
def options_for(value)
|
60
63
|
if value.is_a?(Array) || value.is_a?(Hash)
|
61
|
-
# hashes and arrays need to get encoder in the options, so that
|
64
|
+
# hashes and arrays need to get encoder in the options, so that
|
65
|
+
# they can detect circular references.
|
62
66
|
options.merge(:encoder => self)
|
63
67
|
else
|
64
68
|
options.dup
|
@@ -103,9 +107,14 @@ module ActiveSupport
|
|
103
107
|
'&' => '\u0026' }
|
104
108
|
|
105
109
|
class << self
|
106
|
-
# If true, use ISO 8601 format for dates and times. Otherwise, fall back
|
110
|
+
# If true, use ISO 8601 format for dates and times. Otherwise, fall back
|
111
|
+
# to the Active Support legacy format.
|
107
112
|
attr_accessor :use_standard_json_time_format
|
108
113
|
|
114
|
+
# If false, serializes BigDecimal objects as numeric instead of wrapping
|
115
|
+
# them in a string.
|
116
|
+
attr_accessor :encode_big_decimal_as_string
|
117
|
+
|
109
118
|
attr_accessor :escape_regex
|
110
119
|
attr_reader :escape_html_entities_in_json
|
111
120
|
|
@@ -119,24 +128,17 @@ module ActiveSupport
|
|
119
128
|
end
|
120
129
|
|
121
130
|
def escape(string)
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
json = string.
|
126
|
-
gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
|
127
|
-
gsub(/([\xC0-\xDF][\x80-\xBF]|
|
128
|
-
[\xE0-\xEF][\x80-\xBF]{2}|
|
129
|
-
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
|
130
|
-
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\\\u\&')
|
131
|
-
}
|
131
|
+
string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
|
132
|
+
json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }
|
132
133
|
json = %("#{json}")
|
133
|
-
json.force_encoding(::Encoding::UTF_8)
|
134
|
+
json.force_encoding(::Encoding::UTF_8)
|
134
135
|
json
|
135
136
|
end
|
136
137
|
end
|
137
138
|
|
138
139
|
self.use_standard_json_time_format = true
|
139
|
-
self.escape_html_entities_in_json =
|
140
|
+
self.escape_html_entities_in_json = true
|
141
|
+
self.encode_big_decimal_as_string = true
|
140
142
|
end
|
141
143
|
end
|
142
144
|
end
|
@@ -158,32 +160,67 @@ class Struct #:nodoc:
|
|
158
160
|
end
|
159
161
|
|
160
162
|
class TrueClass
|
161
|
-
def as_json(options = nil)
|
162
|
-
|
163
|
+
def as_json(options = nil) #:nodoc:
|
164
|
+
self
|
165
|
+
end
|
166
|
+
|
167
|
+
def encode_json(encoder) #:nodoc:
|
168
|
+
to_s
|
169
|
+
end
|
163
170
|
end
|
164
171
|
|
165
172
|
class FalseClass
|
166
|
-
def as_json(options = nil)
|
167
|
-
|
173
|
+
def as_json(options = nil) #:nodoc:
|
174
|
+
self
|
175
|
+
end
|
176
|
+
|
177
|
+
def encode_json(encoder) #:nodoc:
|
178
|
+
to_s
|
179
|
+
end
|
168
180
|
end
|
169
181
|
|
170
182
|
class NilClass
|
171
|
-
def as_json(options = nil)
|
172
|
-
|
183
|
+
def as_json(options = nil) #:nodoc:
|
184
|
+
self
|
185
|
+
end
|
186
|
+
|
187
|
+
def encode_json(encoder) #:nodoc:
|
188
|
+
'null'
|
189
|
+
end
|
173
190
|
end
|
174
191
|
|
175
192
|
class String
|
176
|
-
def as_json(options = nil)
|
177
|
-
|
193
|
+
def as_json(options = nil) #:nodoc:
|
194
|
+
self
|
195
|
+
end
|
196
|
+
|
197
|
+
def encode_json(encoder) #:nodoc:
|
198
|
+
encoder.escape(self)
|
199
|
+
end
|
178
200
|
end
|
179
201
|
|
180
202
|
class Symbol
|
181
|
-
def as_json(options = nil)
|
203
|
+
def as_json(options = nil) #:nodoc:
|
204
|
+
to_s
|
205
|
+
end
|
182
206
|
end
|
183
207
|
|
184
208
|
class Numeric
|
185
|
-
def as_json(options = nil)
|
186
|
-
|
209
|
+
def as_json(options = nil) #:nodoc:
|
210
|
+
self
|
211
|
+
end
|
212
|
+
|
213
|
+
def encode_json(encoder) #:nodoc:
|
214
|
+
to_s
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class Float
|
219
|
+
# Encoding Infinity or NaN to JSON should return "null". The default returns
|
220
|
+
# "Infinity" or "NaN" which breaks parsing the JSON. E.g. JSON.parse('[NaN]').
|
221
|
+
def as_json(options = nil) #:nodoc:
|
222
|
+
finite? ? self : nil
|
223
|
+
end
|
187
224
|
end
|
188
225
|
|
189
226
|
class BigDecimal
|
@@ -192,14 +229,26 @@ class BigDecimal
|
|
192
229
|
# those libraries would get in general a wrong number and no way to recover
|
193
230
|
# other than manually inspecting the string with the JSON code itself.
|
194
231
|
#
|
195
|
-
# That's why a JSON string is returned. The JSON literal is not numeric, but
|
196
|
-
# the other end knows by contract that the data is supposed to be a
|
197
|
-
# it still has the chance to post-process the string and get the
|
198
|
-
|
232
|
+
# That's why a JSON string is returned. The JSON literal is not numeric, but
|
233
|
+
# if the other end knows by contract that the data is supposed to be a
|
234
|
+
# BigDecimal, it still has the chance to post-process the string and get the
|
235
|
+
# real value.
|
236
|
+
#
|
237
|
+
# Use <tt>ActiveSupport.use_standard_json_big_decimal_format = true</tt> to
|
238
|
+
# override this behavior.
|
239
|
+
def as_json(options = nil) #:nodoc:
|
240
|
+
if finite?
|
241
|
+
ActiveSupport.encode_big_decimal_as_string ? to_s : self
|
242
|
+
else
|
243
|
+
nil
|
244
|
+
end
|
245
|
+
end
|
199
246
|
end
|
200
247
|
|
201
248
|
class Regexp
|
202
|
-
def as_json(options = nil)
|
249
|
+
def as_json(options = nil) #:nodoc:
|
250
|
+
to_s
|
251
|
+
end
|
203
252
|
end
|
204
253
|
|
205
254
|
module Enumerable
|
@@ -208,6 +257,12 @@ module Enumerable
|
|
208
257
|
end
|
209
258
|
end
|
210
259
|
|
260
|
+
class Range
|
261
|
+
def as_json(options = nil) #:nodoc:
|
262
|
+
to_s
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
211
266
|
class Array
|
212
267
|
def as_json(options = nil) #:nodoc:
|
213
268
|
# use encoder as a proxy to call as_json on all elements, to protect from circular references
|
@@ -226,9 +281,9 @@ class Hash
|
|
226
281
|
# create a subset of the hash by applying :only or :except
|
227
282
|
subset = if options
|
228
283
|
if attrs = options[:only]
|
229
|
-
slice(*Array
|
284
|
+
slice(*Array(attrs))
|
230
285
|
elsif attrs = options[:except]
|
231
|
-
except(*Array
|
286
|
+
except(*Array(attrs))
|
232
287
|
else
|
233
288
|
self
|
234
289
|
end
|
@@ -238,11 +293,10 @@ class Hash
|
|
238
293
|
|
239
294
|
# use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
|
240
295
|
encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
|
241
|
-
|
242
|
-
result[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
|
296
|
+
Hash[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
|
243
297
|
end
|
244
298
|
|
245
|
-
def encode_json(encoder)
|
299
|
+
def encode_json(encoder) #:nodoc:
|
246
300
|
# values are encoded with use_options = false, because we don't want hash representations from ActiveModel to be
|
247
301
|
# processed once again with as_json with options, as this could cause unexpected results (i.e. missing fields);
|
248
302
|
|
@@ -1,7 +1,16 @@
|
|
1
|
+
require 'active_support/deprecation'
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module JSON
|
3
|
-
# A string that returns itself as its JSON-encoded form.
|
5
|
+
# Deprecated: A string that returns itself as its JSON-encoded form.
|
4
6
|
class Variable < String
|
7
|
+
def initialize(*args)
|
8
|
+
message = 'ActiveSupport::JSON::Variable is deprecated and will be removed in Rails 4.1. ' \
|
9
|
+
'For your own custom JSON literals, define #as_json and #encode_json yourself.'
|
10
|
+
ActiveSupport::Deprecation.warn message
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
5
14
|
def as_json(options = nil) self end #:nodoc:
|
6
15
|
def encode_json(encoder) self end #:nodoc:
|
7
16
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'thread_safe'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
module ActiveSupport
|
5
|
+
# KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
|
6
|
+
# It can be used to derive a number of keys for various purposes from a given secret.
|
7
|
+
# This lets rails applications have a single secure secret, but avoid reusing that
|
8
|
+
# key in multiple incompatible contexts.
|
9
|
+
class KeyGenerator
|
10
|
+
def initialize(secret, options = {})
|
11
|
+
@secret = secret
|
12
|
+
# The default iterations are higher than required for our key derivation uses
|
13
|
+
# on the off chance someone uses this for password storage
|
14
|
+
@iterations = options[:iterations] || 2**16
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a derived key suitable for use. The default key_size is chosen
|
18
|
+
# to be compatible with the default settings of ActiveSupport::MessageVerifier.
|
19
|
+
# i.e. OpenSSL::Digest::SHA1#block_length
|
20
|
+
def generate_key(salt, key_size=64)
|
21
|
+
OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
|
26
|
+
# re-executing the key generation process when it's called using the same salt and
|
27
|
+
# key_size
|
28
|
+
class CachingKeyGenerator
|
29
|
+
def initialize(key_generator)
|
30
|
+
@key_generator = key_generator
|
31
|
+
@cache_keys = ThreadSafe::Cache.new
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a derived key suitable for use. The default key_size is chosen
|
35
|
+
# to be compatible with the default settings of ActiveSupport::MessageVerifier.
|
36
|
+
# i.e. OpenSSL::Digest::SHA1#block_length
|
37
|
+
def generate_key(salt, key_size=64)
|
38
|
+
@cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class DummyKeyGenerator # :nodoc:
|
43
|
+
SECRET_MIN_LENGTH = 30 # Characters
|
44
|
+
|
45
|
+
def initialize(secret)
|
46
|
+
ensure_secret_secure(secret)
|
47
|
+
@secret = secret
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_key(salt)
|
51
|
+
@secret
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# To prevent users from using something insecure like "Password" we make sure that the
|
57
|
+
# secret they've provided is at least 30 characters in length.
|
58
|
+
def ensure_secret_secure(secret)
|
59
|
+
if secret.blank?
|
60
|
+
raise ArgumentError, "A secret is required to generate an " +
|
61
|
+
"integrity hash for cookie session data. Use " +
|
62
|
+
"config.secret_key_base = \"some secret phrase of at " +
|
63
|
+
"least #{SECRET_MIN_LENGTH} characters\"" +
|
64
|
+
"in config/initializers/secret_token.rb"
|
65
|
+
end
|
66
|
+
|
67
|
+
if secret.length < SECRET_MIN_LENGTH
|
68
|
+
raise ArgumentError, "Secret should be something secure, " +
|
69
|
+
"like \"#{SecureRandom.hex(16)}\". The value you " +
|
70
|
+
"provided, \"#{secret}\", is shorter than the minimum length " +
|
71
|
+
"of #{SECRET_MIN_LENGTH} characters"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|