activesupport 5.2.4.3 → 7.0.3
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 +244 -459
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -5
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache/file_store.rb +47 -41
- data/lib/active_support/cache/mem_cache_store.rb +151 -40
- data/lib/active_support/cache/memory_store.rb +68 -34
- data/lib/active_support/cache/null_store.rb +16 -3
- data/lib/active_support/cache/redis_cache_store.rb +103 -101
- data/lib/active_support/cache/strategy/local_cache.rb +56 -64
- data/lib/active_support/cache.rb +333 -116
- data/lib/active_support/callbacks.rb +244 -128
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +72 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -3
- data/lib/active_support/configurable.rb +15 -16
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +15 -7
- data/lib/active_support/core_ext/array/conversions.rb +18 -17
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +2 -1
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +32 -47
- data/lib/active_support/core_ext/class/subclasses.rb +9 -22
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +15 -14
- data/lib/active_support/core_ext/date/conversions.rb +16 -15
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -51
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -14
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +241 -76
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +3 -4
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +2 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +2 -31
- data/lib/active_support/core_ext/hash/slice.rb +6 -27
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +32 -39
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +35 -28
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +70 -33
- data/lib/active_support/core_ext/module/introspection.rb +16 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +132 -129
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -1
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +3 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +14 -110
- data/lib/active_support/core_ext/object/json.rb +44 -27
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +24 -14
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +23 -27
- data/lib/active_support/core_ext/range/conversions.rb +32 -30
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +1 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -20
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/regexp.rb +8 -5
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +5 -16
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +46 -7
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +6 -5
- data/lib/active_support/core_ext/string/output_safety.rb +129 -20
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +59 -10
- data/lib/active_support/core_ext/time/conversions.rb +15 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +7 -22
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -22
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +47 -16
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +60 -715
- data/lib/active_support/deprecation/behaviors.rb +21 -5
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +18 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +31 -8
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +7 -2
- data/lib/active_support/descendants_tracker.rb +190 -34
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +5 -7
- data/lib/active_support/duration/iso8601_serializer.rb +27 -15
- data/lib/active_support/duration.rb +149 -67
- data/lib/active_support/encrypted_configuration.rb +12 -5
- data/lib/active_support/encrypted_file.rb +23 -5
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +85 -122
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +44 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +73 -43
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +2 -0
- data/lib/active_support/i18n_railtie.rb +15 -8
- data/lib/active_support/inflector/inflections.rb +25 -14
- data/lib/active_support/inflector/methods.rb +38 -71
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +25 -26
- data/lib/active_support/json/encoding.rb +14 -6
- data/lib/active_support/key_generator.rb +23 -38
- data/lib/active_support/lazy_load_hooks.rb +19 -5
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +51 -11
- data/lib/active_support/logger.rb +6 -22
- data/lib/active_support/logger_silence.rb +11 -19
- data/lib/active_support/logger_thread_safe_level.rb +45 -10
- data/lib/active_support/message_encryptor.rb +20 -19
- data/lib/active_support/message_verifier.rb +53 -21
- data/lib/active_support/messages/metadata.rb +13 -4
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +10 -9
- data/lib/active_support/multibyte/chars.rb +17 -76
- data/lib/active_support/multibyte/unicode.rb +7 -331
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +163 -37
- data/lib/active_support/notifications/instrumenter.rb +90 -11
- data/lib/active_support/notifications.rb +88 -30
- data/lib/active_support/number_helper/number_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_currency_converter.rb +12 -12
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -4
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -7
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +36 -12
- data/lib/active_support/option_merger.rb +15 -4
- data/lib/active_support/ordered_hash.rb +2 -2
- data/lib/active_support/ordered_options.rb +14 -4
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +6 -1
- data/lib/active_support/rails.rb +1 -10
- data/lib/active_support/railtie.rb +77 -5
- data/lib/active_support/reloader.rb +5 -6
- data/lib/active_support/rescuable.rb +8 -8
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +2 -3
- data/lib/active_support/subscriber.rb +79 -46
- data/lib/active_support/tagged_logging.rb +58 -9
- data/lib/active_support/test_case.rb +79 -0
- data/lib/active_support/testing/assertions.rb +62 -11
- data/lib/active_support/testing/deprecation.rb +52 -2
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +4 -4
- data/lib/active_support/testing/method_call_assertions.rb +32 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +4 -7
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +60 -14
- data/lib/active_support/time_with_zone.rb +139 -64
- data/lib/active_support/values/time_zone.rb +66 -30
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -4
- data/lib/active_support/xml_mini/libxml.rb +7 -7
- data/lib/active_support/xml_mini/libxmlsax.rb +5 -5
- data/lib/active_support/xml_mini/nokogiri.rb +6 -6
- data/lib/active_support/xml_mini/nokogirisax.rb +4 -4
- data/lib/active_support/xml_mini/rexml.rb +11 -4
- data/lib/active_support/xml_mini.rb +7 -14
- data/lib/active_support.rb +30 -1
- metadata +64 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
- data/lib/active_support/core_ext/hash/compact.rb +0 -29
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -11
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
- data/lib/active_support/core_ext/range/include_range.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -40,7 +40,11 @@ module ActiveSupport
|
|
40
40
|
# If the class has an initializer, it must accept no arguments.
|
41
41
|
module PerThreadRegistry
|
42
42
|
def self.extended(object)
|
43
|
-
|
43
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
44
|
+
ActiveSupport::PerThreadRegistry is deprecated and will be removed in Rails 7.1.
|
45
|
+
Use `Module#thread_mattr_accessor` instead.
|
46
|
+
MSG
|
47
|
+
object.instance_variable_set :@per_thread_registry_key, object.name.freeze
|
44
48
|
end
|
45
49
|
|
46
50
|
def instance
|
@@ -56,5 +60,6 @@ module ActiveSupport
|
|
56
60
|
|
57
61
|
send(name, *args, &block)
|
58
62
|
end
|
63
|
+
ruby2_keywords(:method_missing)
|
59
64
|
end
|
60
65
|
end
|
data/lib/active_support/rails.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# This is private interface.
|
3
|
+
# This is a private interface.
|
4
4
|
#
|
5
5
|
# Rails components cherry pick from Active Support as needed, but there are a
|
6
6
|
# few features that are used for sure in some way or another and it is not worth
|
@@ -13,9 +13,6 @@
|
|
13
13
|
# Defines Object#blank? and Object#present?.
|
14
14
|
require "active_support/core_ext/object/blank"
|
15
15
|
|
16
|
-
# Rails own autoload, eager_load, etc.
|
17
|
-
require "active_support/dependencies/autoload"
|
18
|
-
|
19
16
|
# Support for ClassMethods and the included macro.
|
20
17
|
require "active_support/concern"
|
21
18
|
|
@@ -27,9 +24,3 @@ require "active_support/core_ext/module/delegation"
|
|
27
24
|
|
28
25
|
# Defines ActiveSupport::Deprecation.
|
29
26
|
require "active_support/deprecation"
|
30
|
-
|
31
|
-
# Defines Regexp#match?.
|
32
|
-
#
|
33
|
-
# This should be removed when Rails needs Ruby 2.4 or later, and the require
|
34
|
-
# added where other Regexp extensions are being used (easy to grep).
|
35
|
-
require "active_support/core_ext/regexp"
|
@@ -6,9 +6,27 @@ 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
|
9
10
|
|
10
11
|
config.eager_load_namespaces << ActiveSupport
|
11
12
|
|
13
|
+
initializer "active_support.isolation_level" do |app|
|
14
|
+
config.after_initialize do
|
15
|
+
if level = app.config.active_support.delete(:isolation_level)
|
16
|
+
ActiveSupport::IsolatedExecutionState.isolation_level = level
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
initializer "active_support.remove_deprecated_time_with_zone_name" do |app|
|
22
|
+
config.after_initialize do
|
23
|
+
if app.config.active_support.remove_deprecated_time_with_zone_name
|
24
|
+
require "active_support/time_with_zone"
|
25
|
+
TimeWithZone.singleton_class.remove_method(:name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
12
30
|
initializer "active_support.set_authenticated_message_encryption" do |app|
|
13
31
|
config.after_initialize do
|
14
32
|
unless app.config.active_support.use_authenticated_message_encryption.nil?
|
@@ -18,15 +36,48 @@ module ActiveSupport
|
|
18
36
|
end
|
19
37
|
end
|
20
38
|
|
39
|
+
initializer "active_support.reset_execution_context" do |app|
|
40
|
+
app.reloader.before_class_unload { ActiveSupport::ExecutionContext.clear }
|
41
|
+
app.executor.to_run { ActiveSupport::ExecutionContext.clear }
|
42
|
+
app.executor.to_complete { ActiveSupport::ExecutionContext.clear }
|
43
|
+
end
|
44
|
+
|
21
45
|
initializer "active_support.reset_all_current_attributes_instances" do |app|
|
22
46
|
app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
|
23
47
|
app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
|
24
48
|
app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
|
49
|
+
|
50
|
+
ActiveSupport.on_load(:active_support_test_case) do
|
51
|
+
if app.config.active_support.executor_around_test_case
|
52
|
+
require "active_support/executor/test_helper"
|
53
|
+
include ActiveSupport::Executor::TestHelper
|
54
|
+
else
|
55
|
+
require "active_support/current_attributes/test_helper"
|
56
|
+
include ActiveSupport::CurrentAttributes::TestHelper
|
57
|
+
|
58
|
+
require "active_support/execution_context/test_helper"
|
59
|
+
include ActiveSupport::ExecutionContext::TestHelper
|
60
|
+
end
|
61
|
+
end
|
25
62
|
end
|
26
63
|
|
27
64
|
initializer "active_support.deprecation_behavior" do |app|
|
28
|
-
if
|
29
|
-
ActiveSupport::Deprecation.
|
65
|
+
if app.config.active_support.report_deprecations == false
|
66
|
+
ActiveSupport::Deprecation.silenced = true
|
67
|
+
ActiveSupport::Deprecation.behavior = :silence
|
68
|
+
ActiveSupport::Deprecation.disallowed_behavior = :silence
|
69
|
+
else
|
70
|
+
if deprecation = app.config.active_support.deprecation
|
71
|
+
ActiveSupport::Deprecation.behavior = deprecation
|
72
|
+
end
|
73
|
+
|
74
|
+
if disallowed_deprecation = app.config.active_support.disallowed_deprecation
|
75
|
+
ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
|
76
|
+
end
|
77
|
+
|
78
|
+
if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
|
79
|
+
ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
|
80
|
+
end
|
30
81
|
end
|
31
82
|
end
|
32
83
|
|
@@ -62,17 +113,38 @@ module ActiveSupport
|
|
62
113
|
end
|
63
114
|
end
|
64
115
|
|
116
|
+
initializer "active_support.set_error_reporter" do |app|
|
117
|
+
ActiveSupport.error_reporter = app.executor.error_reporter
|
118
|
+
end
|
119
|
+
|
65
120
|
initializer "active_support.set_configs" do |app|
|
66
121
|
app.config.active_support.each do |k, v|
|
67
122
|
k = "#{k}="
|
68
|
-
ActiveSupport.
|
123
|
+
ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k
|
69
124
|
end
|
70
125
|
end
|
71
126
|
|
72
127
|
initializer "active_support.set_hash_digest_class" do |app|
|
73
128
|
config.after_initialize do
|
74
|
-
if app.config.active_support.
|
75
|
-
ActiveSupport::Digest.hash_digest_class =
|
129
|
+
if klass = app.config.active_support.hash_digest_class
|
130
|
+
ActiveSupport::Digest.hash_digest_class = klass
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
initializer "active_support.set_key_generator_hash_digest_class" do |app|
|
136
|
+
config.after_initialize do
|
137
|
+
if klass = app.config.active_support.key_generator_hash_digest_class
|
138
|
+
ActiveSupport::KeyGenerator.hash_digest_class = klass
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
initializer "active_support.set_rfc4122_namespaced_uuids" do |app|
|
144
|
+
config.after_initialize do
|
145
|
+
if app.config.active_support.use_rfc4122_namespaced_uuids
|
146
|
+
require "active_support/core_ext/digest"
|
147
|
+
::Digest::UUID.use_rfc4122_namespaced_uuids = app.config.active_support.use_rfc4122_namespaced_uuids
|
76
148
|
end
|
77
149
|
end
|
78
150
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/execution_wrapper"
|
4
|
+
require "active_support/executor"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
#--
|
@@ -49,17 +50,15 @@ module ActiveSupport
|
|
49
50
|
def self.reload!
|
50
51
|
executor.wrap do
|
51
52
|
new.tap do |instance|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
instance.complete!
|
56
|
-
end
|
53
|
+
instance.run!
|
54
|
+
ensure
|
55
|
+
instance.complete!
|
57
56
|
end
|
58
57
|
end
|
59
58
|
prepare!
|
60
59
|
end
|
61
60
|
|
62
|
-
def self.run! # :nodoc:
|
61
|
+
def self.run!(reset: false) # :nodoc:
|
63
62
|
if check!
|
64
63
|
super
|
65
64
|
else
|
@@ -14,12 +14,12 @@ module ActiveSupport
|
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
17
|
-
#
|
17
|
+
# Registers exception classes with a handler to be called by <tt>rescue_with_handler</tt>.
|
18
18
|
#
|
19
19
|
# <tt>rescue_from</tt> receives a series of exception classes or class
|
20
|
-
# names, and a trailing <tt>:with</tt>
|
21
|
-
#
|
22
|
-
# be given.
|
20
|
+
# names, and an exception handler specified by a trailing <tt>:with</tt>
|
21
|
+
# option containing the name of a method or a Proc object. Alternatively, a block
|
22
|
+
# can be given as the handler.
|
23
23
|
#
|
24
24
|
# Handlers that take one argument will be called with the exception, so
|
25
25
|
# that the exception can be inspected when dealing with it.
|
@@ -74,7 +74,7 @@ module ActiveSupport
|
|
74
74
|
# Matches an exception to a handler based on the exception class.
|
75
75
|
#
|
76
76
|
# If no handler matches the exception, check for a handler matching the
|
77
|
-
# (optional) exception.cause
|
77
|
+
# (optional) +exception.cause+. If no handler matches the exception or its
|
78
78
|
# cause, this returns +nil+, so you can deal with unhandled exceptions.
|
79
79
|
# Be sure to re-raise unhandled exceptions if this is what you expect.
|
80
80
|
#
|
@@ -100,7 +100,7 @@ module ActiveSupport
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
-
def handler_for_rescue(exception, object: self)
|
103
|
+
def handler_for_rescue(exception, object: self) # :nodoc:
|
104
104
|
case rescuer = find_rescue_handler(exception)
|
105
105
|
when Symbol
|
106
106
|
method = object.method(rescuer)
|
@@ -160,14 +160,14 @@ module ActiveSupport
|
|
160
160
|
end
|
161
161
|
|
162
162
|
# Delegates to the class method, but uses the instance as the subject for
|
163
|
-
# rescue_from handlers (method calls, instance_exec blocks).
|
163
|
+
# rescue_from handlers (method calls, +instance_exec+ blocks).
|
164
164
|
def rescue_with_handler(exception)
|
165
165
|
self.class.rescue_with_handler exception, object: self
|
166
166
|
end
|
167
167
|
|
168
168
|
# Internal handler lookup. Delegates to class method. Some libraries call
|
169
169
|
# this directly, so keeping it around for compatibility.
|
170
|
-
def handler_for_rescue(exception)
|
170
|
+
def handler_for_rescue(exception) # :nodoc:
|
171
171
|
self.class.handler_for_rescue exception, object: self
|
172
172
|
end
|
173
173
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/security_utils"
|
4
|
+
require "active_support/messages/rotator"
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
# The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare
|
8
|
+
# and allows you to rotate a previously defined value to a new one.
|
9
|
+
#
|
10
|
+
# It can be used as follow:
|
11
|
+
#
|
12
|
+
# rotator = ActiveSupport::SecureCompareRotator.new('new_production_value')
|
13
|
+
# rotator.rotate('previous_production_value')
|
14
|
+
# rotator.secure_compare!('previous_production_value')
|
15
|
+
#
|
16
|
+
# One real use case example would be to rotate a basic auth credentials:
|
17
|
+
#
|
18
|
+
# class MyController < ApplicationController
|
19
|
+
# def authenticate_request
|
20
|
+
# rotator = ActiveSupport::SecureCompareRotator.new('new_password')
|
21
|
+
# rotator.rotate('old_password')
|
22
|
+
#
|
23
|
+
# authenticate_or_request_with_http_basic do |username, password|
|
24
|
+
# rotator.secure_compare!(password)
|
25
|
+
# rescue ActiveSupport::SecureCompareRotator::InvalidMatch
|
26
|
+
# false
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
class SecureCompareRotator
|
31
|
+
include SecurityUtils
|
32
|
+
prepend Messages::Rotator
|
33
|
+
|
34
|
+
InvalidMatch = Class.new(StandardError)
|
35
|
+
|
36
|
+
def initialize(value, **_options)
|
37
|
+
@value = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def secure_compare!(other_value, on_rotation: @on_rotation)
|
41
|
+
secure_compare(@value, other_value) ||
|
42
|
+
run_rotations(on_rotation) { |wrapper| wrapper.secure_compare!(other_value) } ||
|
43
|
+
raise(InvalidMatch)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def build_rotation(previous_value, _options)
|
48
|
+
self.class.new(previous_value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,30 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest/sha2"
|
4
|
-
|
5
3
|
module ActiveSupport
|
6
4
|
module SecurityUtils
|
7
5
|
# Constant time string comparison, for fixed length strings.
|
8
6
|
#
|
9
7
|
# The values compared should be of fixed length, such as strings
|
10
8
|
# 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
9
|
|
14
|
-
|
10
|
+
if defined?(OpenSSL.fixed_length_secure_compare)
|
11
|
+
def fixed_length_secure_compare(a, b)
|
12
|
+
OpenSSL.fixed_length_secure_compare(a, b)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
def fixed_length_secure_compare(a, b)
|
16
|
+
raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
|
17
|
+
|
18
|
+
l = a.unpack "C#{a.bytesize}"
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
res = 0
|
21
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
22
|
+
res == 0
|
23
|
+
end
|
19
24
|
end
|
20
25
|
module_function :fixed_length_secure_compare
|
21
26
|
|
22
|
-
#
|
27
|
+
# Secure string comparison for strings of variable length.
|
23
28
|
#
|
24
|
-
#
|
25
|
-
# via
|
29
|
+
# While a timing attack would not be able to discern the content of
|
30
|
+
# a secret compared via secure_compare, it is possible to determine
|
31
|
+
# the secret length. This should be considered when using secure_compare
|
32
|
+
# to compare weak, short secrets to user input.
|
26
33
|
def secure_compare(a, b)
|
27
|
-
|
34
|
+
a.bytesize == b.bytesize && fixed_length_secure_compare(a, b)
|
28
35
|
end
|
29
36
|
module_function :secure_compare
|
30
37
|
end
|
@@ -18,13 +18,12 @@ module ActiveSupport
|
|
18
18
|
# vehicle.bike? # => false
|
19
19
|
class StringInquirer < String
|
20
20
|
private
|
21
|
-
|
22
21
|
def respond_to_missing?(method_name, include_private = false)
|
23
|
-
(
|
22
|
+
method_name.end_with?("?") || super
|
24
23
|
end
|
25
24
|
|
26
25
|
def method_missing(method_name, *arguments)
|
27
|
-
if method_name
|
26
|
+
if method_name.end_with?("?")
|
28
27
|
self == method_name[0..-2]
|
29
28
|
else
|
30
29
|
super
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/per_thread_registry"
|
4
3
|
require "active_support/notifications"
|
5
4
|
|
6
5
|
module ActiveSupport
|
@@ -24,22 +23,46 @@ module ActiveSupport
|
|
24
23
|
# After configured, whenever a "sql.active_record" notification is published,
|
25
24
|
# it will properly dispatch the event (ActiveSupport::Notifications::Event) to
|
26
25
|
# the +sql+ method.
|
26
|
+
#
|
27
|
+
# We can detach a subscriber as well:
|
28
|
+
#
|
29
|
+
# ActiveRecord::StatsSubscriber.detach_from(:active_record)
|
27
30
|
class Subscriber
|
28
31
|
class << self
|
29
32
|
# Attach the subscriber to a namespace.
|
30
|
-
def attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications)
|
33
|
+
def attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications, inherit_all: false)
|
31
34
|
@namespace = namespace
|
32
35
|
@subscriber = subscriber
|
33
36
|
@notifier = notifier
|
37
|
+
@inherit_all = inherit_all
|
34
38
|
|
35
39
|
subscribers << subscriber
|
36
40
|
|
37
41
|
# Add event subscribers for all existing methods on the class.
|
38
|
-
subscriber
|
42
|
+
fetch_public_methods(subscriber, inherit_all).each do |event|
|
39
43
|
add_event_subscriber(event)
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
47
|
+
# Detach the subscriber from a namespace.
|
48
|
+
def detach_from(namespace, notifier = ActiveSupport::Notifications)
|
49
|
+
@namespace = namespace
|
50
|
+
@subscriber = find_attached_subscriber
|
51
|
+
@notifier = notifier
|
52
|
+
|
53
|
+
return unless subscriber
|
54
|
+
|
55
|
+
subscribers.delete(subscriber)
|
56
|
+
|
57
|
+
# Remove event subscribers of all existing methods on the class.
|
58
|
+
fetch_public_methods(subscriber, true).each do |event|
|
59
|
+
remove_event_subscriber(event)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Reset notifier so that event subscribers will not add for new methods added to the class.
|
63
|
+
@notifier = nil
|
64
|
+
end
|
65
|
+
|
43
66
|
# Adds event subscribers for all new methods added to the class.
|
44
67
|
def method_added(event)
|
45
68
|
# Only public methods are added as subscribers, and only if a notifier
|
@@ -54,77 +77,87 @@ module ActiveSupport
|
|
54
77
|
@@subscribers ||= []
|
55
78
|
end
|
56
79
|
|
57
|
-
|
58
|
-
|
59
|
-
protected
|
80
|
+
private
|
81
|
+
attr_reader :subscriber, :notifier, :namespace
|
60
82
|
|
61
|
-
|
83
|
+
def add_event_subscriber(event) # :doc:
|
84
|
+
return if invalid_event?(event)
|
62
85
|
|
63
|
-
|
86
|
+
pattern = prepare_pattern(event)
|
64
87
|
|
65
|
-
|
66
|
-
|
88
|
+
# Don't add multiple subscribers (e.g. if methods are redefined).
|
89
|
+
return if pattern_subscribed?(pattern)
|
67
90
|
|
68
|
-
|
91
|
+
subscriber.patterns[pattern] = notifier.subscribe(pattern, subscriber)
|
92
|
+
end
|
69
93
|
|
70
|
-
|
71
|
-
|
94
|
+
def remove_event_subscriber(event) # :doc:
|
95
|
+
return if invalid_event?(event)
|
72
96
|
|
73
|
-
|
74
|
-
|
75
|
-
|
97
|
+
pattern = prepare_pattern(event)
|
98
|
+
|
99
|
+
return unless pattern_subscribed?(pattern)
|
100
|
+
|
101
|
+
notifier.unsubscribe(subscriber.patterns[pattern])
|
102
|
+
subscriber.patterns.delete(pattern)
|
103
|
+
end
|
104
|
+
|
105
|
+
def find_attached_subscriber
|
106
|
+
subscribers.find { |attached_subscriber| attached_subscriber.instance_of?(self) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def invalid_event?(event)
|
110
|
+
%i{ start finish }.include?(event.to_sym)
|
111
|
+
end
|
112
|
+
|
113
|
+
def prepare_pattern(event)
|
114
|
+
"#{event}.#{namespace}"
|
115
|
+
end
|
116
|
+
|
117
|
+
def pattern_subscribed?(pattern)
|
118
|
+
subscriber.patterns.key?(pattern)
|
119
|
+
end
|
120
|
+
|
121
|
+
def fetch_public_methods(subscriber, inherit_all)
|
122
|
+
subscriber.public_methods(inherit_all) - Subscriber.public_instance_methods(true)
|
123
|
+
end
|
76
124
|
end
|
77
125
|
|
78
126
|
attr_reader :patterns # :nodoc:
|
79
127
|
|
80
128
|
def initialize
|
81
129
|
@queue_key = [self.class.name, object_id].join "-"
|
82
|
-
@patterns =
|
130
|
+
@patterns = {}
|
83
131
|
super
|
84
132
|
end
|
85
133
|
|
86
134
|
def start(name, id, payload)
|
87
|
-
|
135
|
+
event = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload)
|
136
|
+
event.start!
|
88
137
|
parent = event_stack.last
|
89
|
-
parent <<
|
138
|
+
parent << event if parent
|
90
139
|
|
91
|
-
event_stack.push
|
140
|
+
event_stack.push event
|
92
141
|
end
|
93
142
|
|
94
143
|
def finish(name, id, payload)
|
95
|
-
|
96
|
-
event
|
97
|
-
event.end = finished
|
144
|
+
event = event_stack.pop
|
145
|
+
event.finish!
|
98
146
|
event.payload.merge!(payload)
|
99
147
|
|
100
|
-
method = name.split("."
|
148
|
+
method = name.split(".").first
|
101
149
|
send(method, event)
|
102
150
|
end
|
103
151
|
|
104
|
-
|
152
|
+
def publish_event(event) # :nodoc:
|
153
|
+
method = event.name.split(".").first
|
154
|
+
send(method, event)
|
155
|
+
end
|
105
156
|
|
157
|
+
private
|
106
158
|
def event_stack
|
107
|
-
|
159
|
+
registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
|
160
|
+
registry[@queue_key] ||= []
|
108
161
|
end
|
109
|
-
|
110
|
-
def now
|
111
|
-
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# This is a registry for all the event stacks kept for subscribers.
|
116
|
-
#
|
117
|
-
# See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
|
118
|
-
# for further details.
|
119
|
-
class SubscriberQueueRegistry # :nodoc:
|
120
|
-
extend PerThreadRegistry
|
121
|
-
|
122
|
-
def initialize
|
123
|
-
@registry = {}
|
124
|
-
end
|
125
|
-
|
126
|
-
def get_queue(queue_key)
|
127
|
-
@registry[queue_key] ||= []
|
128
|
-
end
|
129
162
|
end
|
130
163
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/module/delegation"
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
4
5
|
require "active_support/core_ext/object/blank"
|
5
6
|
require "logger"
|
6
7
|
require "active_support/logger"
|
@@ -8,11 +9,20 @@ require "active_support/logger"
|
|
8
9
|
module ActiveSupport
|
9
10
|
# Wraps any standard Logger object to provide tagging capabilities.
|
10
11
|
#
|
12
|
+
# May be called with a block:
|
13
|
+
#
|
11
14
|
# logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
12
15
|
# logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff"
|
13
16
|
# logger.tagged('BCX', "Jason") { logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff"
|
14
17
|
# logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
|
15
18
|
#
|
19
|
+
# If called without a block, a new logger will be returned with applied tags:
|
20
|
+
#
|
21
|
+
# logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
22
|
+
# logger.tagged("BCX").info "Stuff" # Logs "[BCX] Stuff"
|
23
|
+
# logger.tagged("BCX", "Jason").info "Stuff" # Logs "[BCX] [Jason] Stuff"
|
24
|
+
# logger.tagged("BCX").tagged("Jason").info "Stuff" # Logs "[BCX] [Jason] Stuff"
|
25
|
+
#
|
16
26
|
# This is used by the default Rails.logger as configured by Railties to make
|
17
27
|
# it easy to stamp log lines with subdomains, request ids, and anything else
|
18
28
|
# to aid debugging of multi-user production applications.
|
@@ -31,9 +41,10 @@ module ActiveSupport
|
|
31
41
|
end
|
32
42
|
|
33
43
|
def push_tags(*tags)
|
34
|
-
tags.flatten
|
35
|
-
|
36
|
-
|
44
|
+
tags.flatten!
|
45
|
+
tags.reject!(&:blank?)
|
46
|
+
current_tags.concat tags
|
47
|
+
tags
|
37
48
|
end
|
38
49
|
|
39
50
|
def pop_tags(size = 1)
|
@@ -46,29 +57,67 @@ module ActiveSupport
|
|
46
57
|
|
47
58
|
def current_tags
|
48
59
|
# We use our object ID here to avoid conflicting with other instances
|
49
|
-
thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}"
|
50
|
-
|
60
|
+
thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}"
|
61
|
+
IsolatedExecutionState[thread_key] ||= []
|
51
62
|
end
|
52
63
|
|
53
64
|
def tags_text
|
54
65
|
tags = current_tags
|
55
|
-
if tags.
|
66
|
+
if tags.one?
|
67
|
+
"[#{tags[0]}] "
|
68
|
+
elsif tags.any?
|
56
69
|
tags.collect { |tag| "[#{tag}] " }.join
|
57
70
|
end
|
58
71
|
end
|
59
72
|
end
|
60
73
|
|
74
|
+
module LocalTagStorage # :nodoc:
|
75
|
+
attr_accessor :current_tags
|
76
|
+
|
77
|
+
def self.extended(base)
|
78
|
+
base.current_tags = []
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
61
82
|
def self.new(logger)
|
62
|
-
|
63
|
-
|
83
|
+
logger = logger.clone
|
84
|
+
|
85
|
+
if logger.formatter
|
86
|
+
logger.formatter = logger.formatter.dup
|
87
|
+
else
|
88
|
+
# Ensure we set a default formatter so we aren't extending nil!
|
89
|
+
logger.formatter = ActiveSupport::Logger::SimpleFormatter.new
|
90
|
+
end
|
91
|
+
|
64
92
|
logger.formatter.extend Formatter
|
65
93
|
logger.extend(self)
|
66
94
|
end
|
67
95
|
|
68
96
|
delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
|
69
97
|
|
98
|
+
def broadcast_to(other_logger) # :nodoc:
|
99
|
+
define_singleton_method(:formatter=) do |formatter|
|
100
|
+
other_logger.formatter ||= formatter
|
101
|
+
|
102
|
+
other_logger.formatter.singleton_class.redefine_method(:current_tags) do
|
103
|
+
formatter.current_tags
|
104
|
+
end
|
105
|
+
|
106
|
+
super(formatter)
|
107
|
+
end
|
108
|
+
|
109
|
+
self.formatter = self.formatter.clone
|
110
|
+
end
|
111
|
+
|
70
112
|
def tagged(*tags)
|
71
|
-
|
113
|
+
if block_given?
|
114
|
+
formatter.tagged(*tags) { yield self }
|
115
|
+
else
|
116
|
+
logger = ActiveSupport::TaggedLogging.new(self)
|
117
|
+
logger.formatter.extend LocalTagStorage
|
118
|
+
logger.push_tags(*formatter.current_tags, *tags)
|
119
|
+
logger
|
120
|
+
end
|
72
121
|
end
|
73
122
|
|
74
123
|
def flush
|