activesupport 7.0.4 → 7.1.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1076 -230
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -6
- data/lib/active_support/actionable_error.rb +3 -1
- data/lib/active_support/array_inquirer.rb +2 -0
- data/lib/active_support/backtrace_cleaner.rb +30 -5
- data/lib/active_support/benchmarkable.rb +1 -0
- data/lib/active_support/broadcast_logger.rb +251 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +37 -10
- data/lib/active_support/cache/mem_cache_store.rb +100 -76
- data/lib/active_support/cache/memory_store.rb +78 -24
- data/lib/active_support/cache/null_store.rb +6 -0
- data/lib/active_support/cache/redis_cache_store.rb +153 -141
- data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
- data/lib/active_support/cache/strategy/local_cache.rb +29 -14
- data/lib/active_support/cache.rb +333 -253
- data/lib/active_support/callbacks.rb +44 -21
- data/lib/active_support/code_generator.rb +15 -10
- data/lib/active_support/concern.rb +4 -2
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/configurable.rb +10 -0
- data/lib/active_support/core_ext/array/conversions.rb +2 -1
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/class/subclasses.rb +13 -10
- data/lib/active_support/core_ext/date/calculations.rb +15 -0
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +6 -2
- data/lib/active_support/core_ext/date_time.rb +0 -1
- data/lib/active_support/core_ext/digest/uuid.rb +1 -10
- data/lib/active_support/core_ext/enumerable.rb +8 -75
- data/lib/active_support/core_ext/erb/util.rb +196 -0
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +3 -3
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +81 -37
- data/lib/active_support/core_ext/module/deprecation.rb +15 -12
- data/lib/active_support/core_ext/module/introspection.rb +0 -1
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +2 -0
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
- data/lib/active_support/core_ext/object/duplicable.rb +25 -16
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
- data/lib/active_support/core_ext/object/json.rb +16 -6
- data/lib/active_support/core_ext/object/to_query.rb +0 -2
- data/lib/active_support/core_ext/object/with.rb +44 -0
- data/lib/active_support/core_ext/object/with_options.rb +9 -9
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +16 -0
- data/lib/active_support/core_ext/pathname/existence.rb +2 -0
- data/lib/active_support/core_ext/pathname.rb +1 -0
- data/lib/active_support/core_ext/range/conversions.rb +28 -7
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +24 -12
- data/lib/active_support/core_ext/string/filters.rb +20 -14
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +16 -9
- data/lib/active_support/core_ext/string/output_safety.rb +42 -174
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +22 -2
- data/lib/active_support/core_ext/time/conversions.rb +2 -2
- data/lib/active_support/core_ext/time/zones.rb +7 -8
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/current_attributes.rb +15 -6
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/dependencies/autoload.rb +17 -12
- data/lib/active_support/deprecation/behaviors.rb +65 -42
- data/lib/active_support/deprecation/constant_accessor.rb +5 -4
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +6 -8
- data/lib/active_support/deprecation/instance_delegator.rb +31 -4
- data/lib/active_support/deprecation/method_wrappers.rb +6 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +37 -22
- data/lib/active_support/deprecation/reporting.rb +43 -26
- data/lib/active_support/deprecation.rb +32 -5
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +104 -132
- data/lib/active_support/duration/iso8601_serializer.rb +0 -2
- data/lib/active_support/duration.rb +2 -1
- data/lib/active_support/encrypted_configuration.rb +63 -11
- data/lib/active_support/encrypted_file.rb +16 -12
- data/lib/active_support/environment_inquirer.rb +22 -2
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +121 -35
- data/lib/active_support/evented_file_update_checker.rb +17 -2
- data/lib/active_support/execution_wrapper.rb +4 -4
- data/lib/active_support/file_update_checker.rb +4 -2
- data/lib/active_support/fork_tracker.rb +10 -2
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +35 -17
- data/lib/active_support/html_safe_translation.rb +16 -6
- data/lib/active_support/i18n.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +20 -13
- data/lib/active_support/inflector/inflections.rb +2 -0
- data/lib/active_support/inflector/methods.rb +28 -18
- data/lib/active_support/inflector/transliterate.rb +3 -1
- data/lib/active_support/isolated_execution_state.rb +26 -22
- data/lib/active_support/json/decoding.rb +2 -1
- data/lib/active_support/json/encoding.rb +25 -43
- data/lib/active_support/key_generator.rb +9 -1
- data/lib/active_support/lazy_load_hooks.rb +7 -5
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +85 -33
- data/lib/active_support/logger.rb +9 -60
- data/lib/active_support/logger_thread_safe_level.rb +10 -24
- data/lib/active_support/message_encryptor.rb +197 -53
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +292 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +212 -93
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +111 -45
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +34 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +2 -0
- data/lib/active_support/multibyte/unicode.rb +9 -37
- data/lib/active_support/notifications/fanout.rb +245 -81
- data/lib/active_support/notifications/instrumenter.rb +87 -22
- data/lib/active_support/notifications.rb +3 -3
- data/lib/active_support/number_helper/number_converter.rb +14 -5
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
- data/lib/active_support/number_helper.rb +379 -317
- data/lib/active_support/ordered_hash.rb +3 -3
- data/lib/active_support/ordered_options.rb +14 -0
- data/lib/active_support/parameter_filter.rb +103 -84
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/railtie.rb +33 -21
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +2 -0
- data/lib/active_support/secure_compare_rotator.rb +16 -9
- data/lib/active_support/string_inquirer.rb +3 -1
- data/lib/active_support/subscriber.rb +9 -27
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +64 -24
- data/lib/active_support/test_case.rb +153 -6
- data/lib/active_support/testing/assertions.rb +26 -10
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +32 -0
- data/lib/active_support/testing/deprecation.rb +25 -25
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +29 -28
- data/lib/active_support/testing/method_call_assertions.rb +21 -8
- data/lib/active_support/testing/parallelize_executor.rb +8 -3
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/strict_warnings.rb +39 -0
- data/lib/active_support/testing/time_helpers.rb +37 -15
- data/lib/active_support/time_with_zone.rb +8 -37
- data/lib/active_support/values/time_zone.rb +18 -7
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -10
- data/lib/active_support/xml_mini/nokogiri.rb +1 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +2 -2
- data/lib/active_support.rb +14 -3
- metadata +148 -19
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -7
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/uri.rb +0 -5
- data/lib/active_support/per_thread_registry.rb +0 -65
@@ -7,7 +7,7 @@ YAML.add_builtin_type("omap") do |type, val|
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ActiveSupport
|
10
|
-
# DEPRECATED:
|
10
|
+
# DEPRECATED: +ActiveSupport::OrderedHash+ implements a hash that preserves
|
11
11
|
# insertion order.
|
12
12
|
#
|
13
13
|
# oh = ActiveSupport::OrderedHash.new
|
@@ -17,9 +17,9 @@ module ActiveSupport
|
|
17
17
|
#
|
18
18
|
# Also, maps the +omap+ feature for YAML files
|
19
19
|
# (See https://yaml.org/type/omap.html) to support ordered items
|
20
|
-
# when loading from
|
20
|
+
# when loading from YAML.
|
21
21
|
#
|
22
|
-
#
|
22
|
+
# +ActiveSupport::OrderedHash+ is namespaced to prevent conflicts
|
23
23
|
# with other implementations.
|
24
24
|
class OrderedHash < ::Hash # :nodoc:
|
25
25
|
def to_yaml_type
|
@@ -3,6 +3,8 @@
|
|
3
3
|
require "active_support/core_ext/object/blank"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
+
# = Ordered Options
|
7
|
+
#
|
6
8
|
# +OrderedOptions+ inherits from +Hash+ and provides dynamic accessor methods.
|
7
9
|
#
|
8
10
|
# With a +Hash+, key-value pairs are typically managed like this:
|
@@ -40,6 +42,10 @@ module ActiveSupport
|
|
40
42
|
super(key.to_sym)
|
41
43
|
end
|
42
44
|
|
45
|
+
def dig(key, *identifiers)
|
46
|
+
super(key.to_sym, *identifiers)
|
47
|
+
end
|
48
|
+
|
43
49
|
def method_missing(name, *args)
|
44
50
|
name_string = +name.to_s
|
45
51
|
if name_string.chomp!("=")
|
@@ -68,6 +74,8 @@ module ActiveSupport
|
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
77
|
+
# = Inheritable Options
|
78
|
+
#
|
71
79
|
# +InheritableOptions+ provides a constructor to build an OrderedOptions
|
72
80
|
# hash inherited from another hash.
|
73
81
|
#
|
@@ -76,6 +84,12 @@ module ActiveSupport
|
|
76
84
|
# h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
|
77
85
|
# h.girl # => 'Mary'
|
78
86
|
# h.boy # => 'John'
|
87
|
+
#
|
88
|
+
# If the existing hash has string keys, call Hash#symbolize_keys on it.
|
89
|
+
#
|
90
|
+
# h = ActiveSupport::InheritableOptions.new({ 'girl' => 'Mary', 'boy' => 'John' }.symbolize_keys)
|
91
|
+
# h.girl # => 'Mary'
|
92
|
+
# h.boy # => 'John'
|
79
93
|
class InheritableOptions < OrderedOptions
|
80
94
|
def initialize(parent = nil)
|
81
95
|
if parent.kind_of?(OrderedOptions)
|
@@ -1,37 +1,72 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/duplicable"
|
4
|
+
require "active_support/core_ext/array/extract"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
|
-
#
|
7
|
-
# hash-like object and replace corresponding value. Filtering only certain
|
8
|
-
# sub-keys from a hash is possible by using the dot notation:
|
9
|
-
# 'credit_card.number'. If a proc is given, each key and value of a hash and
|
10
|
-
# all sub-hashes are passed to it, where the value or the key can be replaced
|
11
|
-
# using String#replace or similar methods.
|
7
|
+
# = Active Support Parameter Filter
|
12
8
|
#
|
9
|
+
# +ParameterFilter+ replaces values in a <tt>Hash</tt>-like object if their
|
10
|
+
# keys match one of the specified filters.
|
11
|
+
#
|
12
|
+
# Matching based on nested keys is possible by using dot notation, e.g.
|
13
|
+
# <tt>"credit_card.number"</tt>.
|
14
|
+
#
|
15
|
+
# If a proc is given as a filter, each key and value of the <tt>Hash</tt>-like
|
16
|
+
# and of any nested <tt>Hash</tt>es will be passed to it. The value or key can
|
17
|
+
# then be mutated as desired using methods such as <tt>String#replace</tt>.
|
18
|
+
#
|
19
|
+
# # Replaces values with "[FILTERED]" for keys that match /password/i.
|
13
20
|
# ActiveSupport::ParameterFilter.new([:password])
|
14
|
-
# => replaces the value to all keys matching /password/i with "[FILTERED]"
|
15
21
|
#
|
22
|
+
# # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
|
16
23
|
# ActiveSupport::ParameterFilter.new([:foo, "bar"])
|
17
|
-
# => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
|
18
24
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
25
|
+
# # Replaces values for the exact key "pin" and for keys that begin with
|
26
|
+
# # "pin_". Does not match keys that otherwise include "pin" as a
|
27
|
+
# # substring, such as "shipping_id".
|
28
|
+
# ActiveSupport::ParameterFilter.new([/\Apin\z/, /\Apin_/])
|
23
29
|
#
|
30
|
+
# # Replaces the value for :code in `{ credit_card: { code: "xxxx" } }`.
|
31
|
+
# # Does not change `{ file: { code: "xxxx" } }`.
|
24
32
|
# ActiveSupport::ParameterFilter.new(["credit_card.code"])
|
25
|
-
# => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
|
26
|
-
# change { file: { code: "xxxx"} }
|
27
33
|
#
|
34
|
+
# # Reverses values for keys that match /secret/i.
|
28
35
|
# ActiveSupport::ParameterFilter.new([-> (k, v) do
|
29
36
|
# v.reverse! if /secret/i.match?(k)
|
30
37
|
# end])
|
31
|
-
#
|
38
|
+
#
|
32
39
|
class ParameterFilter
|
33
40
|
FILTERED = "[FILTERED]" # :nodoc:
|
34
41
|
|
42
|
+
# Precompiles an array of filters that otherwise would be passed directly to
|
43
|
+
# #initialize. Depending on the quantity and types of filters,
|
44
|
+
# precompilation can improve filtering performance, especially in the case
|
45
|
+
# where the ParameterFilter instance itself cannot be retained (but the
|
46
|
+
# precompiled filters can be retained).
|
47
|
+
#
|
48
|
+
# filters = [/foo/, :bar, "nested.baz", /nested\.qux/]
|
49
|
+
#
|
50
|
+
# precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters)
|
51
|
+
# # => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/]
|
52
|
+
#
|
53
|
+
# ActiveSupport::ParameterFilter.new(precompiled)
|
54
|
+
#
|
55
|
+
def self.precompile_filters(filters)
|
56
|
+
filters, patterns = filters.partition { |filter| filter.is_a?(Proc) }
|
57
|
+
|
58
|
+
patterns.map! do |pattern|
|
59
|
+
pattern.is_a?(Regexp) ? pattern : "(?i:#{Regexp.escape pattern.to_s})"
|
60
|
+
end
|
61
|
+
|
62
|
+
deep_patterns = patterns.extract! { |pattern| pattern.to_s.include?("\\.") }
|
63
|
+
|
64
|
+
filters << Regexp.new(patterns.join("|")) if patterns.any?
|
65
|
+
filters << Regexp.new(deep_patterns.join("|")) if deep_patterns.any?
|
66
|
+
|
67
|
+
filters
|
68
|
+
end
|
69
|
+
|
35
70
|
# Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
|
36
71
|
# Other types of filters are treated as +String+ using +to_s+.
|
37
72
|
# For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
|
@@ -40,99 +75,83 @@ module ActiveSupport
|
|
40
75
|
#
|
41
76
|
# * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
|
42
77
|
def initialize(filters = [], mask: FILTERED)
|
43
|
-
@filters = filters
|
44
78
|
@mask = mask
|
79
|
+
compile_filters!(filters)
|
45
80
|
end
|
46
81
|
|
47
82
|
# Mask value of +params+ if key matches one of filters.
|
48
83
|
def filter(params)
|
49
|
-
|
84
|
+
@no_filters ? params.dup : call(params)
|
50
85
|
end
|
51
86
|
|
52
87
|
# Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
|
53
88
|
def filter_param(key, value)
|
54
|
-
@
|
89
|
+
@no_filters ? value : value_for_key(key, value)
|
55
90
|
end
|
56
91
|
|
57
92
|
private
|
58
|
-
def
|
59
|
-
@
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
if item.to_s.include?("\\.")
|
74
|
-
(deep_regexps ||= []) << item
|
75
|
-
else
|
76
|
-
regexps << item
|
77
|
-
end
|
93
|
+
def compile_filters!(filters)
|
94
|
+
@no_filters = filters.empty?
|
95
|
+
return if @no_filters
|
96
|
+
|
97
|
+
@regexps, strings = [], []
|
98
|
+
@deep_regexps, deep_strings = nil, nil
|
99
|
+
@blocks = nil
|
100
|
+
|
101
|
+
filters.each do |item|
|
102
|
+
case item
|
103
|
+
when Proc
|
104
|
+
(@blocks ||= []) << item
|
105
|
+
when Regexp
|
106
|
+
if item.to_s.include?("\\.")
|
107
|
+
(@deep_regexps ||= []) << item
|
78
108
|
else
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
109
|
+
@regexps << item
|
110
|
+
end
|
111
|
+
else
|
112
|
+
s = Regexp.escape(item.to_s)
|
113
|
+
if s.include?("\\.")
|
114
|
+
(deep_strings ||= []) << s
|
115
|
+
else
|
116
|
+
strings << s
|
85
117
|
end
|
86
118
|
end
|
87
|
-
|
88
|
-
regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
|
89
|
-
(deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings&.any?
|
90
|
-
|
91
|
-
new regexps, deep_regexps, blocks, mask: mask
|
92
119
|
end
|
93
120
|
|
94
|
-
|
121
|
+
@regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
|
122
|
+
(@deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings
|
123
|
+
end
|
95
124
|
|
96
|
-
|
97
|
-
|
98
|
-
@deep_regexps = deep_regexps&.any? ? deep_regexps : nil
|
99
|
-
@blocks = blocks
|
100
|
-
@mask = mask
|
101
|
-
end
|
125
|
+
def call(params, full_parent_key = nil, original_params = params)
|
126
|
+
filtered_params = params.class.new
|
102
127
|
|
103
|
-
|
104
|
-
filtered_params =
|
128
|
+
params.each do |key, value|
|
129
|
+
filtered_params[key] = value_for_key(key, value, full_parent_key, original_params)
|
130
|
+
end
|
105
131
|
|
106
|
-
|
107
|
-
|
108
|
-
end
|
132
|
+
filtered_params
|
133
|
+
end
|
109
134
|
|
110
|
-
|
135
|
+
def value_for_key(key, value, full_parent_key = nil, original_params = nil)
|
136
|
+
if @deep_regexps
|
137
|
+
full_key = full_parent_key ? "#{full_parent_key}.#{key}" : key.to_s
|
111
138
|
end
|
112
139
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
value = value.map { |v| value_for_key(key, v, parents, original_params) }
|
126
|
-
# Restore the parent stack after processing the array.
|
127
|
-
parents.push(key) if deep_regexps
|
128
|
-
elsif blocks.any?
|
129
|
-
key = key.dup if key.duplicable?
|
130
|
-
value = value.dup if value.duplicable?
|
131
|
-
blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
|
132
|
-
end
|
133
|
-
parents.pop if deep_regexps
|
134
|
-
value
|
140
|
+
if @regexps.any? { |r| r.match?(key.to_s) }
|
141
|
+
value = @mask
|
142
|
+
elsif @deep_regexps&.any? { |r| r.match?(full_key) }
|
143
|
+
value = @mask
|
144
|
+
elsif value.is_a?(Hash)
|
145
|
+
value = call(value, full_key, original_params)
|
146
|
+
elsif value.is_a?(Array)
|
147
|
+
value = value.map { |v| value_for_key(key, v, full_parent_key, original_params) }
|
148
|
+
elsif @blocks
|
149
|
+
key = key.dup if key.duplicable?
|
150
|
+
value = value.dup if value.duplicable?
|
151
|
+
@blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
|
135
152
|
end
|
153
|
+
|
154
|
+
value
|
136
155
|
end
|
137
156
|
end
|
138
157
|
end
|
@@ -6,10 +6,13 @@ require "active_support/i18n_railtie"
|
|
6
6
|
module ActiveSupport
|
7
7
|
class Railtie < Rails::Railtie # :nodoc:
|
8
8
|
config.active_support = ActiveSupport::OrderedOptions.new
|
9
|
-
config.active_support.disable_to_s_conversion = false
|
10
9
|
|
11
10
|
config.eager_load_namespaces << ActiveSupport
|
12
11
|
|
12
|
+
initializer "active_support.deprecator", before: :load_environment_config do |app|
|
13
|
+
app.deprecators[:active_support] = ActiveSupport.deprecator
|
14
|
+
end
|
15
|
+
|
13
16
|
initializer "active_support.isolation_level" do |app|
|
14
17
|
config.after_initialize do
|
15
18
|
if level = app.config.active_support.delete(:isolation_level)
|
@@ -18,11 +21,10 @@ module ActiveSupport
|
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
21
|
-
initializer "active_support.
|
24
|
+
initializer "active_support.raise_on_invalid_cache_expiration_time" do |app|
|
22
25
|
config.after_initialize do
|
23
|
-
if app.config.active_support.
|
24
|
-
|
25
|
-
TimeWithZone.singleton_class.remove_method(:name)
|
26
|
+
if app.config.active_support.raise_on_invalid_cache_expiration_time
|
27
|
+
ActiveSupport::Cache::Store.raise_on_invalid_cache_expiration_time = true
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
@@ -63,20 +65,20 @@ module ActiveSupport
|
|
63
65
|
|
64
66
|
initializer "active_support.deprecation_behavior" do |app|
|
65
67
|
if app.config.active_support.report_deprecations == false
|
66
|
-
|
67
|
-
|
68
|
-
|
68
|
+
app.deprecators.silenced = true
|
69
|
+
app.deprecators.behavior = :silence
|
70
|
+
app.deprecators.disallowed_behavior = :silence
|
69
71
|
else
|
70
72
|
if deprecation = app.config.active_support.deprecation
|
71
|
-
|
73
|
+
app.deprecators.behavior = deprecation
|
72
74
|
end
|
73
75
|
|
74
76
|
if disallowed_deprecation = app.config.active_support.disallowed_deprecation
|
75
|
-
|
77
|
+
app.deprecators.disallowed_behavior = disallowed_deprecation
|
76
78
|
end
|
77
79
|
|
78
80
|
if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
|
79
|
-
|
81
|
+
app.deprecators.disallowed_warnings = disallowed_warnings
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
@@ -113,14 +115,18 @@ module ActiveSupport
|
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|
116
|
-
initializer "active_support.set_error_reporter" do |app|
|
117
|
-
ActiveSupport.error_reporter = app.executor.error_reporter
|
118
|
-
end
|
119
|
-
|
120
118
|
initializer "active_support.set_configs" do |app|
|
121
119
|
app.config.active_support.each do |k, v|
|
122
|
-
k
|
123
|
-
|
120
|
+
if k == :disable_to_s_conversion
|
121
|
+
ActiveSupport.deprecator.warn("config.active_support.disable_to_s_conversion is deprecated and will be removed in Rails 7.2.")
|
122
|
+
elsif k == :remove_deprecated_time_with_zone_name
|
123
|
+
ActiveSupport.deprecator.warn("config.active_support.remove_deprecated_time_with_zone_name is deprecated and will be removed in Rails 7.2.")
|
124
|
+
elsif k == :use_rfc4122_namespaced_uuids
|
125
|
+
ActiveSupport.deprecator.warn("config.active_support.use_rfc4122_namespaced_uuids is deprecated and will be removed in Rails 7.2.")
|
126
|
+
else
|
127
|
+
k = "#{k}="
|
128
|
+
ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k
|
129
|
+
end
|
124
130
|
end
|
125
131
|
end
|
126
132
|
|
@@ -140,13 +146,19 @@ module ActiveSupport
|
|
140
146
|
end
|
141
147
|
end
|
142
148
|
|
143
|
-
initializer "active_support.
|
149
|
+
initializer "active_support.set_default_message_serializer" do |app|
|
144
150
|
config.after_initialize do
|
145
|
-
if app.config.active_support.
|
146
|
-
|
147
|
-
::Digest::UUID.use_rfc4122_namespaced_uuids = app.config.active_support.use_rfc4122_namespaced_uuids
|
151
|
+
if message_serializer = app.config.active_support.message_serializer
|
152
|
+
ActiveSupport::Messages::Codec.default_serializer = message_serializer
|
148
153
|
end
|
149
154
|
end
|
150
155
|
end
|
156
|
+
|
157
|
+
initializer "active_support.set_use_message_serializer_for_metadata" do |app|
|
158
|
+
config.after_initialize do
|
159
|
+
ActiveSupport::Messages::Metadata.use_message_serializer_for_metadata =
|
160
|
+
app.config.active_support.use_message_serializer_for_metadata
|
161
|
+
end
|
162
|
+
end
|
151
163
|
end
|
152
164
|
end
|
@@ -4,7 +4,8 @@ require "active_support/execution_wrapper"
|
|
4
4
|
require "active_support/executor"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
-
|
7
|
+
# = Active Support \Reloader
|
8
|
+
#
|
8
9
|
# This class defines several callbacks:
|
9
10
|
#
|
10
11
|
# to_prepare -- Run once at application startup, and also from
|
@@ -67,9 +68,16 @@ module ActiveSupport
|
|
67
68
|
end
|
68
69
|
|
69
70
|
# Run the supplied block as a work unit, reloading code as needed
|
70
|
-
def self.wrap
|
71
|
-
|
72
|
-
|
71
|
+
def self.wrap(**kwargs)
|
72
|
+
return yield if active?
|
73
|
+
|
74
|
+
executor.wrap(**kwargs) do
|
75
|
+
instance = run!
|
76
|
+
begin
|
77
|
+
yield
|
78
|
+
ensure
|
79
|
+
instance.complete!
|
80
|
+
end
|
73
81
|
end
|
74
82
|
end
|
75
83
|
|
@@ -5,6 +5,8 @@ require "active_support/core_ext/class/attribute"
|
|
5
5
|
require "active_support/core_ext/string/inflections"
|
6
6
|
|
7
7
|
module ActiveSupport
|
8
|
+
# = Active Support \Rescuable
|
9
|
+
#
|
8
10
|
# Rescuable module adds support for easier exception handling.
|
9
11
|
module Rescuable
|
10
12
|
extend Concern
|
@@ -4,6 +4,8 @@ require "active_support/security_utils"
|
|
4
4
|
require "active_support/messages/rotator"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
+
# = Secure Compare Rotator
|
8
|
+
#
|
7
9
|
# The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare
|
8
10
|
# and allows you to rotate a previously defined value to a new one.
|
9
11
|
#
|
@@ -29,23 +31,28 @@ module ActiveSupport
|
|
29
31
|
# end
|
30
32
|
class SecureCompareRotator
|
31
33
|
include SecurityUtils
|
32
|
-
prepend Messages::Rotator
|
33
34
|
|
34
35
|
InvalidMatch = Class.new(StandardError)
|
35
36
|
|
36
|
-
def initialize(value,
|
37
|
+
def initialize(value, on_rotation: nil)
|
37
38
|
@value = value
|
39
|
+
@rotate_values = []
|
40
|
+
@on_rotation = on_rotation
|
38
41
|
end
|
39
42
|
|
40
|
-
def
|
41
|
-
|
42
|
-
run_rotations(on_rotation) { |wrapper| wrapper.secure_compare!(other_value) } ||
|
43
|
-
raise(InvalidMatch)
|
43
|
+
def rotate(previous_value)
|
44
|
+
@rotate_values << previous_value
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
def secure_compare!(other_value, on_rotation: @on_rotation)
|
48
|
+
if secure_compare(@value, other_value)
|
49
|
+
true
|
50
|
+
elsif @rotate_values.any? { |value| secure_compare(value, other_value) }
|
51
|
+
on_rotation&.call
|
52
|
+
true
|
53
|
+
else
|
54
|
+
raise InvalidMatch
|
49
55
|
end
|
56
|
+
end
|
50
57
|
end
|
51
58
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
|
+
# = \String Inquirer
|
5
|
+
#
|
4
6
|
# Wrapping a string in this class gives you a prettier way to test
|
5
7
|
# for equality. The value returned by <tt>Rails.env</tt> is wrapped
|
6
8
|
# in a StringInquirer object, so instead of calling this:
|
@@ -11,7 +13,7 @@ module ActiveSupport
|
|
11
13
|
#
|
12
14
|
# Rails.env.production?
|
13
15
|
#
|
14
|
-
# == Instantiating a new StringInquirer
|
16
|
+
# == Instantiating a new \StringInquirer
|
15
17
|
#
|
16
18
|
# vehicle = ActiveSupport::StringInquirer.new('car')
|
17
19
|
# vehicle.car? # => true
|
@@ -3,7 +3,9 @@
|
|
3
3
|
require "active_support/notifications"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
-
#
|
6
|
+
# = Active Support \Subscriber
|
7
|
+
#
|
8
|
+
# +ActiveSupport::Subscriber+ is an object set to consume
|
7
9
|
# ActiveSupport::Notifications. The subscriber dispatches notifications to
|
8
10
|
# a registered object based on its given namespace.
|
9
11
|
#
|
@@ -20,9 +22,9 @@ module ActiveSupport
|
|
20
22
|
# end
|
21
23
|
# end
|
22
24
|
#
|
23
|
-
# After configured, whenever a "sql.active_record" notification is
|
24
|
-
# it will properly dispatch the event
|
25
|
-
# the +sql+ method.
|
25
|
+
# After configured, whenever a <tt>"sql.active_record"</tt> notification is
|
26
|
+
# published, it will properly dispatch the event
|
27
|
+
# (ActiveSupport::Notifications::Event) to the +sql+ method.
|
26
28
|
#
|
27
29
|
# We can detach a subscriber as well:
|
28
30
|
#
|
@@ -126,38 +128,18 @@ module ActiveSupport
|
|
126
128
|
attr_reader :patterns # :nodoc:
|
127
129
|
|
128
130
|
def initialize
|
129
|
-
@queue_key = [self.class.name, object_id].join "-"
|
130
131
|
@patterns = {}
|
131
132
|
super
|
132
133
|
end
|
133
134
|
|
134
|
-
def
|
135
|
-
|
136
|
-
event.start!
|
137
|
-
parent = event_stack.last
|
138
|
-
parent << event if parent
|
139
|
-
|
140
|
-
event_stack.push event
|
141
|
-
end
|
142
|
-
|
143
|
-
def finish(name, id, payload)
|
144
|
-
event = event_stack.pop
|
145
|
-
event.finish!
|
146
|
-
event.payload.merge!(payload)
|
147
|
-
|
148
|
-
method = name.split(".").first
|
135
|
+
def call(event)
|
136
|
+
method = event.name[0, event.name.index(".")]
|
149
137
|
send(method, event)
|
150
138
|
end
|
151
139
|
|
152
140
|
def publish_event(event) # :nodoc:
|
153
|
-
method = event.name.
|
141
|
+
method = event.name[0, event.name.index(".")]
|
154
142
|
send(method, event)
|
155
143
|
end
|
156
|
-
|
157
|
-
private
|
158
|
-
def event_stack
|
159
|
-
registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
|
160
|
-
registry[@queue_key] ||= []
|
161
|
-
end
|
162
144
|
end
|
163
145
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
# This is a class for wrapping syntax errors. The purpose of this class
|
7
|
+
# is to enhance the backtraces on SyntaxError exceptions to include the
|
8
|
+
# source location of the syntax error. That way we can display the error
|
9
|
+
# source on error pages in development.
|
10
|
+
class SyntaxErrorProxy < DelegateClass(SyntaxError) # :nodoc:
|
11
|
+
def backtrace
|
12
|
+
parse_message_for_trace + super
|
13
|
+
end
|
14
|
+
|
15
|
+
class BacktraceLocation < Struct.new(:path, :lineno, :to_s) # :nodoc:
|
16
|
+
def spot(_)
|
17
|
+
end
|
18
|
+
|
19
|
+
def label
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class BacktraceLocationProxy < DelegateClass(Thread::Backtrace::Location) # :nodoc:
|
24
|
+
def initialize(loc, ex)
|
25
|
+
super(loc)
|
26
|
+
@ex = ex
|
27
|
+
end
|
28
|
+
|
29
|
+
def spot(_)
|
30
|
+
super(@ex.__getobj__)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def backtrace_locations
|
35
|
+
return nil if super.nil?
|
36
|
+
|
37
|
+
parse_message_for_trace.map { |trace|
|
38
|
+
file, line = trace.match(/^(.+?):(\d+).*$/, &:captures) || trace
|
39
|
+
BacktraceLocation.new(file, line.to_i, trace)
|
40
|
+
# We have to wrap these backtrace locations because we need the
|
41
|
+
# spot information to come from the originating exception, not the
|
42
|
+
# proxy object that's generating these
|
43
|
+
} + super.map { |loc| BacktraceLocationProxy.new(loc, self) }
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def parse_message_for_trace
|
48
|
+
if __getobj__.to_s.start_with?("(eval")
|
49
|
+
# If the exception is coming from a call to eval, we need to keep
|
50
|
+
# the path of the file in which eval was called to ensure we can
|
51
|
+
# return the right source fragment to show the location of the
|
52
|
+
# error
|
53
|
+
location = __getobj__.backtrace_locations[0]
|
54
|
+
["#{location.path}:#{location.lineno}: #{__getobj__}"]
|
55
|
+
else
|
56
|
+
__getobj__.to_s.split("\n")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|