activesupport 4.2.11.1 → 6.0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +399 -411
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +34 -6
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +58 -53
- data/lib/active_support/cache/mem_cache_store.rb +95 -91
- data/lib/active_support/cache/memory_store.rb +39 -36
- data/lib/active_support/cache/null_store.rb +11 -7
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +75 -42
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +331 -217
- data/lib/active_support/callbacks.rb +650 -592
- data/lib/active_support/concern.rb +35 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +13 -14
- data/lib/active_support/core_ext/array/access.rb +41 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -20
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +45 -31
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +114 -22
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +4 -23
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +19 -42
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +5 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
- data/lib/active_support/core_ext/hash.rb +10 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +133 -30
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +44 -19
- data/lib/active_support/core_ext/module/reachable.rb +5 -7
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +5 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -3
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +13 -93
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +51 -20
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +81 -23
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_range.rb +7 -21
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +16 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +48 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +16 -7
- data/lib/active_support/core_ext/string/output_safety.rb +93 -40
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +115 -52
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -7
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +208 -166
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +61 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +57 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +53 -0
- data/lib/active_support/duration.rb +315 -40
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +234 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +129 -30
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +50 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +58 -13
- data/lib/active_support/inflector/methods.rb +159 -145
- data/lib/active_support/inflector/transliterate.rb +84 -34
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +32 -30
- data/lib/active_support/json/encoding.rb +17 -60
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +11 -43
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +44 -19
- data/lib/active_support/logger.rb +9 -23
- data/lib/active_support/logger_silence.rb +32 -14
- data/lib/active_support/logger_thread_safe_level.rb +32 -8
- data/lib/active_support/message_encryptor.rb +166 -53
- data/lib/active_support/message_verifier.rb +149 -16
- data/lib/active_support/messages/metadata.rb +72 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +56 -63
- data/lib/active_support/multibyte/unicode.rb +56 -290
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +109 -22
- data/lib/active_support/notifications/instrumenter.rb +107 -16
- data/lib/active_support/notifications.rb +51 -10
- data/lib/active_support/number_helper/number_converter.rb +16 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +105 -68
- data/lib/active_support/option_merger.rb +24 -4
- data/lib/active_support/ordered_hash.rb +7 -5
- data/lib/active_support/ordered_options.rb +27 -5
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +74 -30
- data/lib/active_support/tagged_logging.rb +25 -13
- data/lib/active_support/test_case.rb +107 -44
- data/lib/active_support/testing/assertions.rb +151 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +13 -10
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +35 -26
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +43 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +84 -20
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +179 -39
- data/lib/active_support/values/time_zone.rb +203 -63
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -115
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +38 -46
- data/lib/active_support.rb +13 -11
- metadata +84 -26
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/duplicable"
|
4
|
+
require "active_support/core_ext/array/extract"
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
# +ParameterFilter+ allows you to specify keys for sensitive data from
|
8
|
+
# hash-like object and replace corresponding value. Filtering only certain
|
9
|
+
# sub-keys from a hash is possible by using the dot notation:
|
10
|
+
# 'credit_card.number'. If a proc is given, each key and value of a hash and
|
11
|
+
# all sub-hashes are passed to it, where the value or the key can be replaced
|
12
|
+
# using String#replace or similar methods.
|
13
|
+
#
|
14
|
+
# ActiveSupport::ParameterFilter.new([:password])
|
15
|
+
# => replaces the value to all keys matching /password/i with "[FILTERED]"
|
16
|
+
#
|
17
|
+
# ActiveSupport::ParameterFilter.new([:foo, "bar"])
|
18
|
+
# => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
|
19
|
+
#
|
20
|
+
# ActiveSupport::ParameterFilter.new(["credit_card.code"])
|
21
|
+
# => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
|
22
|
+
# change { file: { code: "xxxx"} }
|
23
|
+
#
|
24
|
+
# ActiveSupport::ParameterFilter.new([-> (k, v) do
|
25
|
+
# v.reverse! if k =~ /secret/i
|
26
|
+
# end])
|
27
|
+
# => reverses the value to all keys matching /secret/i
|
28
|
+
class ParameterFilter
|
29
|
+
FILTERED = "[FILTERED]" # :nodoc:
|
30
|
+
|
31
|
+
# Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
|
32
|
+
# Other types of filters are treated as +String+ using +to_s+.
|
33
|
+
# For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
|
34
|
+
#
|
35
|
+
# ==== Options
|
36
|
+
#
|
37
|
+
# * <tt>:mask</tt> - A replaced object when filtered. Defaults to +"[FILTERED]"+
|
38
|
+
def initialize(filters = [], mask: FILTERED)
|
39
|
+
@filters = filters
|
40
|
+
@mask = mask
|
41
|
+
end
|
42
|
+
|
43
|
+
# Mask value of +params+ if key matches one of filters.
|
44
|
+
def filter(params)
|
45
|
+
compiled_filter.call(params)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
|
49
|
+
def filter_param(key, value)
|
50
|
+
@filters.empty? ? value : compiled_filter.value_for_key(key, value)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def compiled_filter
|
55
|
+
@compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
|
56
|
+
end
|
57
|
+
|
58
|
+
class CompiledFilter # :nodoc:
|
59
|
+
def self.compile(filters, mask:)
|
60
|
+
return lambda { |params| params.dup } if filters.empty?
|
61
|
+
|
62
|
+
strings, regexps, blocks = [], [], []
|
63
|
+
|
64
|
+
filters.each do |item|
|
65
|
+
case item
|
66
|
+
when Proc
|
67
|
+
blocks << item
|
68
|
+
when Regexp
|
69
|
+
regexps << item
|
70
|
+
else
|
71
|
+
strings << Regexp.escape(item.to_s)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
deep_regexps = regexps.extract! { |r| r.to_s.include?("\\.") }
|
76
|
+
deep_strings = strings.extract! { |s| s.include?("\\.") }
|
77
|
+
|
78
|
+
regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
|
79
|
+
deep_regexps << Regexp.new(deep_strings.join("|"), true) unless deep_strings.empty?
|
80
|
+
|
81
|
+
new regexps, deep_regexps, blocks, mask: mask
|
82
|
+
end
|
83
|
+
|
84
|
+
attr_reader :regexps, :deep_regexps, :blocks
|
85
|
+
|
86
|
+
def initialize(regexps, deep_regexps, blocks, mask:)
|
87
|
+
@regexps = regexps
|
88
|
+
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
|
89
|
+
@blocks = blocks
|
90
|
+
@mask = mask
|
91
|
+
end
|
92
|
+
|
93
|
+
def call(params, parents = [], original_params = params)
|
94
|
+
filtered_params = params.class.new
|
95
|
+
|
96
|
+
params.each do |key, value|
|
97
|
+
filtered_params[key] = value_for_key(key, value, parents, original_params)
|
98
|
+
end
|
99
|
+
|
100
|
+
filtered_params
|
101
|
+
end
|
102
|
+
|
103
|
+
def value_for_key(key, value, parents = [], original_params = nil)
|
104
|
+
parents.push(key) if deep_regexps
|
105
|
+
if regexps.any? { |r| r.match?(key.to_s) }
|
106
|
+
value = @mask
|
107
|
+
elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
|
108
|
+
value = @mask
|
109
|
+
elsif value.is_a?(Hash)
|
110
|
+
value = call(value, parents, original_params)
|
111
|
+
elsif value.is_a?(Array)
|
112
|
+
# If we don't pop the current parent it will be duplicated as we
|
113
|
+
# process each array value.
|
114
|
+
parents.pop if deep_regexps
|
115
|
+
value = value.map { |v| value_for_key(key, v, parents, original_params) }
|
116
|
+
# Restore the parent stack after processing the array.
|
117
|
+
parents.push(key) if deep_regexps
|
118
|
+
elsif blocks.any?
|
119
|
+
key = key.dup if key.duplicable?
|
120
|
+
value = value.dup if value.duplicable?
|
121
|
+
blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
|
122
|
+
end
|
123
|
+
parents.pop if deep_regexps
|
124
|
+
value
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -1,6 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/delegation"
|
2
4
|
|
3
5
|
module ActiveSupport
|
6
|
+
# NOTE: This approach has been deprecated for end-user code in favor of {thread_mattr_accessor}[rdoc-ref:Module#thread_mattr_accessor] and friends.
|
7
|
+
# Please use that approach instead.
|
8
|
+
#
|
4
9
|
# This module is used to encapsulate access to thread local variables.
|
5
10
|
#
|
6
11
|
# Instead of polluting the thread locals namespace:
|
@@ -35,15 +40,15 @@ module ActiveSupport
|
|
35
40
|
# If the class has an initializer, it must accept no arguments.
|
36
41
|
module PerThreadRegistry
|
37
42
|
def self.extended(object)
|
38
|
-
object.instance_variable_set
|
43
|
+
object.instance_variable_set "@per_thread_registry_key", object.name.freeze
|
39
44
|
end
|
40
45
|
|
41
46
|
def instance
|
42
47
|
Thread.current[@per_thread_registry_key] ||= new
|
43
48
|
end
|
44
49
|
|
45
|
-
|
46
|
-
def method_missing(name, *args, &block)
|
50
|
+
private
|
51
|
+
def method_missing(name, *args, &block)
|
47
52
|
# Caches the method definition as a singleton method of the receiver.
|
48
53
|
#
|
49
54
|
# By letting #delegate handle it, we avoid an enclosure that'll capture args.
|
data/lib/active_support/rails.rb
CHANGED
@@ -1,27 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This is private interface.
|
2
4
|
#
|
3
5
|
# Rails components cherry pick from Active Support as needed, but there are a
|
4
|
-
# few features that are used for sure some way or another and it is not worth
|
5
|
-
#
|
6
|
+
# few features that are used for sure in some way or another and it is not worth
|
7
|
+
# putting individual requires absolutely everywhere. Think blank? for example.
|
6
8
|
#
|
7
9
|
# This file is loaded by every Rails component except Active Support itself,
|
8
10
|
# but it does not belong to the Rails public interface. It is internal to
|
9
11
|
# Rails and can change anytime.
|
10
12
|
|
11
13
|
# Defines Object#blank? and Object#present?.
|
12
|
-
require
|
14
|
+
require "active_support/core_ext/object/blank"
|
13
15
|
|
14
16
|
# Rails own autoload, eager_load, etc.
|
15
|
-
require
|
17
|
+
require "active_support/dependencies/autoload"
|
16
18
|
|
17
19
|
# Support for ClassMethods and the included macro.
|
18
|
-
require
|
20
|
+
require "active_support/concern"
|
19
21
|
|
20
22
|
# Defines Class#class_attribute.
|
21
|
-
require
|
23
|
+
require "active_support/core_ext/class/attribute"
|
22
24
|
|
23
25
|
# Defines Module#delegate.
|
24
|
-
require
|
26
|
+
require "active_support/core_ext/module/delegation"
|
25
27
|
|
26
28
|
# Defines ActiveSupport::Deprecation.
|
27
|
-
require
|
29
|
+
require "active_support/deprecation"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support"
|
2
4
|
require "active_support/i18n_railtie"
|
3
5
|
|
@@ -7,6 +9,21 @@ module ActiveSupport
|
|
7
9
|
|
8
10
|
config.eager_load_namespaces << ActiveSupport
|
9
11
|
|
12
|
+
initializer "active_support.set_authenticated_message_encryption" do |app|
|
13
|
+
config.after_initialize do
|
14
|
+
unless app.config.active_support.use_authenticated_message_encryption.nil?
|
15
|
+
ActiveSupport::MessageEncryptor.use_authenticated_message_encryption =
|
16
|
+
app.config.active_support.use_authenticated_message_encryption
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
initializer "active_support.reset_all_current_attributes_instances" do |app|
|
22
|
+
app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
|
23
|
+
app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
|
24
|
+
app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
|
25
|
+
end
|
26
|
+
|
10
27
|
initializer "active_support.deprecation_behavior" do |app|
|
11
28
|
if deprecation = app.config.active_support.deprecation
|
12
29
|
ActiveSupport::Deprecation.behavior = deprecation
|
@@ -16,31 +33,48 @@ module ActiveSupport
|
|
16
33
|
# Sets the default value for Time.zone
|
17
34
|
# If assigned value cannot be matched to a TimeZone, an exception will be raised.
|
18
35
|
initializer "active_support.initialize_time_zone" do |app|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
raise 'Value assigned to config.time_zone not recognized. ' \
|
24
|
-
'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
|
36
|
+
begin
|
37
|
+
TZInfo::DataSource.get
|
38
|
+
rescue TZInfo::DataSourceNotFound => e
|
39
|
+
raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
|
25
40
|
end
|
26
|
-
|
27
|
-
Time.zone_default =
|
41
|
+
require "active_support/core_ext/time/zones"
|
42
|
+
Time.zone_default = Time.find_zone!(app.config.time_zone)
|
28
43
|
end
|
29
44
|
|
30
45
|
# Sets the default week start
|
31
46
|
# If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
|
32
47
|
initializer "active_support.initialize_beginning_of_week" do |app|
|
33
|
-
require
|
48
|
+
require "active_support/core_ext/date/calculations"
|
34
49
|
beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week)
|
35
50
|
|
36
51
|
Date.beginning_of_week_default = beginning_of_week_default
|
37
52
|
end
|
38
53
|
|
54
|
+
initializer "active_support.require_master_key" do |app|
|
55
|
+
if app.config.respond_to?(:require_master_key) && app.config.require_master_key
|
56
|
+
begin
|
57
|
+
app.credentials.key
|
58
|
+
rescue ActiveSupport::EncryptedFile::MissingKeyError => error
|
59
|
+
$stderr.puts error.message
|
60
|
+
exit 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
39
65
|
initializer "active_support.set_configs" do |app|
|
40
66
|
app.config.active_support.each do |k, v|
|
41
67
|
k = "#{k}="
|
42
68
|
ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
|
43
69
|
end
|
44
70
|
end
|
71
|
+
|
72
|
+
initializer "active_support.set_hash_digest_class" do |app|
|
73
|
+
config.after_initialize do
|
74
|
+
if app.config.active_support.use_sha1_digests
|
75
|
+
ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
45
79
|
end
|
46
80
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/execution_wrapper"
|
4
|
+
require "active_support/executor"
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
#--
|
8
|
+
# This class defines several callbacks:
|
9
|
+
#
|
10
|
+
# to_prepare -- Run once at application startup, and also from
|
11
|
+
# +to_run+.
|
12
|
+
#
|
13
|
+
# to_run -- Run before a work run that is reloading. If
|
14
|
+
# +reload_classes_only_on_change+ is true (the default), the class
|
15
|
+
# unload will have already occurred.
|
16
|
+
#
|
17
|
+
# to_complete -- Run after a work run that has reloaded. If
|
18
|
+
# +reload_classes_only_on_change+ is false, the class unload will
|
19
|
+
# have occurred after the work run, but before this callback.
|
20
|
+
#
|
21
|
+
# before_class_unload -- Run immediately before the classes are
|
22
|
+
# unloaded.
|
23
|
+
#
|
24
|
+
# after_class_unload -- Run immediately after the classes are
|
25
|
+
# unloaded.
|
26
|
+
#
|
27
|
+
class Reloader < ExecutionWrapper
|
28
|
+
define_callbacks :prepare
|
29
|
+
|
30
|
+
define_callbacks :class_unload
|
31
|
+
|
32
|
+
# Registers a callback that will run once at application startup and every time the code is reloaded.
|
33
|
+
def self.to_prepare(*args, &block)
|
34
|
+
set_callback(:prepare, *args, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Registers a callback that will run immediately before the classes are unloaded.
|
38
|
+
def self.before_class_unload(*args, &block)
|
39
|
+
set_callback(:class_unload, *args, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Registers a callback that will run immediately after the classes are unloaded.
|
43
|
+
def self.after_class_unload(*args, &block)
|
44
|
+
set_callback(:class_unload, :after, *args, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
to_run(:after) { self.class.prepare! }
|
48
|
+
|
49
|
+
# Initiate a manual reload
|
50
|
+
def self.reload!
|
51
|
+
executor.wrap do
|
52
|
+
new.tap do |instance|
|
53
|
+
instance.run!
|
54
|
+
ensure
|
55
|
+
instance.complete!
|
56
|
+
end
|
57
|
+
end
|
58
|
+
prepare!
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.run! # :nodoc:
|
62
|
+
if check!
|
63
|
+
super
|
64
|
+
else
|
65
|
+
Null
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Run the supplied block as a work unit, reloading code as needed
|
70
|
+
def self.wrap
|
71
|
+
executor.wrap do
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class_attribute :executor, default: Executor
|
77
|
+
class_attribute :check, default: lambda { false }
|
78
|
+
|
79
|
+
def self.check! # :nodoc:
|
80
|
+
@should_reload ||= check.call
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.reloaded! # :nodoc:
|
84
|
+
@should_reload = false
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.prepare! # :nodoc:
|
88
|
+
new.run_callbacks(:prepare)
|
89
|
+
end
|
90
|
+
|
91
|
+
def initialize
|
92
|
+
super
|
93
|
+
@locked = false
|
94
|
+
end
|
95
|
+
|
96
|
+
# Acquire the ActiveSupport::Dependencies::Interlock unload lock,
|
97
|
+
# ensuring it will be released automatically
|
98
|
+
def require_unload_lock!
|
99
|
+
unless @locked
|
100
|
+
ActiveSupport::Dependencies.interlock.start_unloading
|
101
|
+
@locked = true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Release the unload lock if it has been previously obtained
|
106
|
+
def release_unload_lock!
|
107
|
+
if @locked
|
108
|
+
@locked = false
|
109
|
+
ActiveSupport::Dependencies.interlock.done_unloading
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def run! # :nodoc:
|
114
|
+
super
|
115
|
+
release_unload_lock!
|
116
|
+
end
|
117
|
+
|
118
|
+
def class_unload!(&block) # :nodoc:
|
119
|
+
require_unload_lock!
|
120
|
+
run_callbacks(:class_unload, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
def complete! # :nodoc:
|
124
|
+
super
|
125
|
+
self.class.reloaded!
|
126
|
+
ensure
|
127
|
+
release_unload_lock!
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
require "active_support/core_ext/class/attribute"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
5
6
|
|
6
7
|
module ActiveSupport
|
7
8
|
# Rescuable module adds support for easier exception handling.
|
@@ -9,8 +10,7 @@ module ActiveSupport
|
|
9
10
|
extend Concern
|
10
11
|
|
11
12
|
included do
|
12
|
-
class_attribute :rescue_handlers
|
13
|
-
self.rescue_handlers = []
|
13
|
+
class_attribute :rescue_handlers, default: []
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
@@ -37,7 +37,7 @@ module ActiveSupport
|
|
37
37
|
# render xml: exception, status: 500
|
38
38
|
# end
|
39
39
|
#
|
40
|
-
#
|
40
|
+
# private
|
41
41
|
# def deny_access
|
42
42
|
# ...
|
43
43
|
# end
|
@@ -48,72 +48,127 @@ module ActiveSupport
|
|
48
48
|
# end
|
49
49
|
#
|
50
50
|
# Exceptions raised inside exception handlers are not propagated up.
|
51
|
-
def rescue_from(*klasses, &block)
|
52
|
-
|
53
|
-
|
54
|
-
unless options.has_key?(:with)
|
51
|
+
def rescue_from(*klasses, with: nil, &block)
|
52
|
+
unless with
|
55
53
|
if block_given?
|
56
|
-
|
54
|
+
with = block
|
57
55
|
else
|
58
|
-
raise ArgumentError, "Need a handler.
|
56
|
+
raise ArgumentError, "Need a handler. Pass the with: keyword argument or provide a block."
|
59
57
|
end
|
60
58
|
end
|
61
59
|
|
62
60
|
klasses.each do |klass|
|
63
|
-
key = if klass.is_a?(
|
61
|
+
key = if klass.is_a?(Module) && klass.respond_to?(:===)
|
64
62
|
klass.name
|
65
63
|
elsif klass.is_a?(String)
|
66
64
|
klass
|
67
65
|
else
|
68
|
-
raise ArgumentError, "#{klass}
|
66
|
+
raise ArgumentError, "#{klass.inspect} must be an Exception class or a String referencing an Exception class"
|
69
67
|
end
|
70
68
|
|
71
|
-
#
|
72
|
-
self.rescue_handlers += [[key,
|
69
|
+
# Put the new handler at the end because the list is read in reverse.
|
70
|
+
self.rescue_handlers += [[key, with]]
|
73
71
|
end
|
74
72
|
end
|
75
|
-
end
|
76
73
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
74
|
+
# Matches an exception to a handler based on the exception class.
|
75
|
+
#
|
76
|
+
# If no handler matches the exception, check for a handler matching the
|
77
|
+
# (optional) exception.cause. If no handler matches the exception or its
|
78
|
+
# cause, this returns +nil+, so you can deal with unhandled exceptions.
|
79
|
+
# Be sure to re-raise unhandled exceptions if this is what you expect.
|
80
|
+
#
|
81
|
+
# begin
|
82
|
+
# …
|
83
|
+
# rescue => exception
|
84
|
+
# rescue_with_handler(exception) || raise
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# Returns the exception if it was handled and +nil+ if it was not.
|
88
|
+
def rescue_with_handler(exception, object: self, visited_exceptions: [])
|
89
|
+
visited_exceptions << exception
|
84
90
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
# could trigger some other handler and the array could include
|
96
|
-
# precisely a string whose corresponding constant has not yet been
|
97
|
-
# seen. This is why we are tolerant to unknown constants.
|
98
|
-
#
|
99
|
-
# Note that this tolerance only matters if the exception was given as
|
100
|
-
# a string, otherwise a NameError will be raised by the interpreter
|
101
|
-
# itself when rescue_from CONSTANT is executed.
|
102
|
-
klass = self.class.const_get(klass_name) rescue nil
|
103
|
-
klass ||= klass_name.constantize rescue nil
|
104
|
-
exception.is_a?(klass) if klass
|
91
|
+
if handler = handler_for_rescue(exception, object: object)
|
92
|
+
handler.call exception
|
93
|
+
exception
|
94
|
+
elsif exception
|
95
|
+
if visited_exceptions.include?(exception.cause)
|
96
|
+
nil
|
97
|
+
else
|
98
|
+
rescue_with_handler(exception.cause, object: object, visited_exceptions: visited_exceptions)
|
99
|
+
end
|
100
|
+
end
|
105
101
|
end
|
106
102
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
103
|
+
def handler_for_rescue(exception, object: self) #:nodoc:
|
104
|
+
case rescuer = find_rescue_handler(exception)
|
105
|
+
when Symbol
|
106
|
+
method = object.method(rescuer)
|
107
|
+
if method.arity == 0
|
108
|
+
-> e { method.call }
|
109
|
+
else
|
110
|
+
method
|
111
|
+
end
|
112
|
+
when Proc
|
113
|
+
if rescuer.arity == 0
|
114
|
+
-> e { object.instance_exec(&rescuer) }
|
115
|
+
else
|
116
|
+
-> e { object.instance_exec(e, &rescuer) }
|
117
|
+
end
|
115
118
|
end
|
116
119
|
end
|
120
|
+
|
121
|
+
private
|
122
|
+
def find_rescue_handler(exception)
|
123
|
+
if exception
|
124
|
+
# Handlers are in order of declaration but the most recently declared
|
125
|
+
# is the highest priority match, so we search for matching handlers
|
126
|
+
# in reverse.
|
127
|
+
_, handler = rescue_handlers.reverse_each.detect do |class_or_name, _|
|
128
|
+
if klass = constantize_rescue_handler_class(class_or_name)
|
129
|
+
klass === exception
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
handler
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def constantize_rescue_handler_class(class_or_name)
|
138
|
+
case class_or_name
|
139
|
+
when String, Symbol
|
140
|
+
begin
|
141
|
+
# Try a lexical lookup first since we support
|
142
|
+
#
|
143
|
+
# class Super
|
144
|
+
# rescue_from 'Error', with: …
|
145
|
+
# end
|
146
|
+
#
|
147
|
+
# class Sub
|
148
|
+
# class Error < StandardError; end
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
# so an Error raised in Sub will hit the 'Error' handler.
|
152
|
+
const_get class_or_name
|
153
|
+
rescue NameError
|
154
|
+
class_or_name.safe_constantize
|
155
|
+
end
|
156
|
+
else
|
157
|
+
class_or_name
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Delegates to the class method, but uses the instance as the subject for
|
163
|
+
# rescue_from handlers (method calls, instance_exec blocks).
|
164
|
+
def rescue_with_handler(exception)
|
165
|
+
self.class.rescue_with_handler exception, object: self
|
166
|
+
end
|
167
|
+
|
168
|
+
# Internal handler lookup. Delegates to class method. Some libraries call
|
169
|
+
# this directly, so keeping it around for compatibility.
|
170
|
+
def handler_for_rescue(exception) #:nodoc:
|
171
|
+
self.class.handler_for_rescue exception, object: self
|
117
172
|
end
|
118
173
|
end
|
119
174
|
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "digest/sha2"
|
2
4
|
|
3
5
|
module ActiveSupport
|
4
6
|
module SecurityUtils
|
5
|
-
# Constant time string comparison.
|
7
|
+
# Constant time string comparison, for fixed length strings.
|
6
8
|
#
|
7
9
|
# The values compared should be of fixed length, such as strings
|
8
|
-
# that have already been processed by HMAC.
|
9
|
-
|
10
|
-
|
11
|
-
def secure_compare(a, b)
|
12
|
-
return false unless a.bytesize == b.bytesize
|
10
|
+
# that have already been processed by HMAC. Raises in case of length mismatch.
|
11
|
+
def fixed_length_secure_compare(a, b)
|
12
|
+
raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
|
13
13
|
|
14
14
|
l = a.unpack "C#{a.bytesize}"
|
15
15
|
|
@@ -17,11 +17,15 @@ module ActiveSupport
|
|
17
17
|
b.each_byte { |byte| res |= byte ^ l.shift }
|
18
18
|
res == 0
|
19
19
|
end
|
20
|
-
module_function :
|
20
|
+
module_function :fixed_length_secure_compare
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
# Constant time string comparison, for variable length strings.
|
23
|
+
#
|
24
|
+
# The values are first processed by SHA256, so that we don't leak length info
|
25
|
+
# via timing attacks.
|
26
|
+
def secure_compare(a, b)
|
27
|
+
fixed_length_secure_compare(::Digest::SHA256.digest(a), ::Digest::SHA256.digest(b)) && a == b
|
24
28
|
end
|
25
|
-
module_function :
|
29
|
+
module_function :secure_compare
|
26
30
|
end
|
27
31
|
end
|