activesupport 5.1.7 → 7.0.4.1

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.

Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +259 -585
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +4 -2
  8. data/lib/active_support/backtrace_cleaner.rb +33 -5
  9. data/lib/active_support/benchmarkable.rb +5 -3
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +50 -43
  12. data/lib/active_support/cache/mem_cache_store.rb +194 -67
  13. data/lib/active_support/cache/memory_store.rb +70 -34
  14. data/lib/active_support/cache/null_store.rb +18 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +474 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +73 -50
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +556 -220
  19. data/lib/active_support/callbacks.rb +264 -159
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +81 -8
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
  23. data/lib/active_support/concurrency/share_lock.rb +4 -3
  24. data/lib/active_support/configurable.rb +17 -16
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +18 -8
  27. data/lib/active_support/core_ext/array/conversions.rb +20 -17
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +8 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +4 -2
  33. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  34. data/lib/active_support/core_ext/array.rb +4 -1
  35. data/lib/active_support/core_ext/benchmark.rb +4 -2
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
  37. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  38. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  40. data/lib/active_support/core_ext/class/subclasses.rb +10 -24
  41. data/lib/active_support/core_ext/class.rb +2 -0
  42. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  43. data/lib/active_support/core_ext/date/blank.rb +3 -1
  44. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  45. data/lib/active_support/core_ext/date/conversions.rb +24 -22
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +2 -0
  48. data/lib/active_support/core_ext/date.rb +3 -0
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +3 -1
  54. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  56. data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +3 -0
  59. data/lib/active_support/core_ext/digest/uuid.rb +42 -14
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +244 -72
  62. data/lib/active_support/core_ext/file/atomic.rb +6 -2
  63. data/lib/active_support/core_ext/file.rb +2 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +7 -6
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +4 -2
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +4 -31
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  72. data/lib/active_support/core_ext/hash.rb +3 -2
  73. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +7 -14
  76. data/lib/active_support/core_ext/integer.rb +2 -0
  77. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
  80. data/lib/active_support/core_ext/kernel.rb +2 -1
  81. data/lib/active_support/core_ext/load_error.rb +3 -8
  82. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  83. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  84. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
  87. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  88. data/lib/active_support/core_ext/module/delegation.rb +97 -58
  89. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  90. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  93. data/lib/active_support/core_ext/module.rb +3 -1
  94. data/lib/active_support/core_ext/name_error.rb +30 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  99. data/lib/active_support/core_ext/numeric.rb +3 -1
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +15 -5
  102. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  103. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  104. data/lib/active_support/core_ext/object/duplicable.rb +16 -110
  105. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  106. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  107. data/lib/active_support/core_ext/object/json.rb +51 -26
  108. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  109. data/lib/active_support/core_ext/object/to_query.rb +4 -2
  110. data/lib/active_support/core_ext/object/try.rb +26 -14
  111. data/lib/active_support/core_ext/object/with_options.rb +24 -3
  112. data/lib/active_support/core_ext/object.rb +2 -0
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +6 -3
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +3 -1
  121. data/lib/active_support/core_ext/range.rb +4 -1
  122. data/lib/active_support/core_ext/regexp.rb +10 -5
  123. data/lib/active_support/core_ext/securerandom.rb +25 -3
  124. data/lib/active_support/core_ext/string/access.rb +7 -16
  125. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  126. data/lib/active_support/core_ext/string/conversions.rb +5 -2
  127. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  128. data/lib/active_support/core_ext/string/filters.rb +44 -1
  129. data/lib/active_support/core_ext/string/indent.rb +2 -0
  130. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  133. data/lib/active_support/core_ext/string/output_safety.rb +135 -27
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +5 -1
  136. data/lib/active_support/core_ext/string/zones.rb +2 -0
  137. data/lib/active_support/core_ext/string.rb +2 -0
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  141. data/lib/active_support/core_ext/time/calculations.rb +81 -24
  142. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  143. data/lib/active_support/core_ext/time/conversions.rb +17 -12
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +12 -25
  146. data/lib/active_support/core_ext/time.rb +3 -0
  147. data/lib/active_support/core_ext/uri.rb +4 -23
  148. data/lib/active_support/core_ext.rb +4 -1
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +2 -0
  152. data/lib/active_support/dependencies/interlock.rb +12 -18
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +59 -715
  155. data/lib/active_support/deprecation/behaviors.rb +48 -13
  156. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  159. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
  161. data/lib/active_support/deprecation/reporting.rb +54 -9
  162. data/lib/active_support/deprecation.rb +10 -3
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +9 -9
  166. data/lib/active_support/duration/iso8601_serializer.rb +29 -15
  167. data/lib/active_support/duration.rb +158 -72
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +129 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +87 -122
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +46 -21
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +2 -0
  178. data/lib/active_support/file_update_checker.rb +2 -1
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +7 -5
  181. data/lib/active_support/gzip.rb +2 -0
  182. data/lib/active_support/hash_with_indifferent_access.rb +126 -42
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +5 -1
  185. data/lib/active_support/i18n_railtie.rb +19 -14
  186. data/lib/active_support/inflections.rb +2 -0
  187. data/lib/active_support/inflector/inflections.rb +41 -14
  188. data/lib/active_support/inflector/methods.rb +73 -87
  189. data/lib/active_support/inflector/transliterate.rb +56 -18
  190. data/lib/active_support/inflector.rb +2 -0
  191. data/lib/active_support/isolated_execution_state.rb +72 -0
  192. data/lib/active_support/json/decoding.rb +27 -26
  193. data/lib/active_support/json/encoding.rb +16 -6
  194. data/lib/active_support/json.rb +2 -0
  195. data/lib/active_support/key_generator.rb +25 -38
  196. data/lib/active_support/lazy_load_hooks.rb +35 -6
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +8 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +4 -2
  200. data/lib/active_support/log_subscriber.rb +54 -13
  201. data/lib/active_support/logger.rb +4 -17
  202. data/lib/active_support/logger_silence.rb +13 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +48 -10
  204. data/lib/active_support/message_encryptor.rb +111 -37
  205. data/lib/active_support/message_verifier.rb +124 -21
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +19 -76
  210. data/lib/active_support/multibyte/unicode.rb +9 -331
  211. data/lib/active_support/multibyte.rb +3 -1
  212. data/lib/active_support/notifications/fanout.rb +165 -37
  213. data/lib/active_support/notifications/instrumenter.rb +92 -11
  214. data/lib/active_support/notifications.rb +96 -30
  215. data/lib/active_support/number_helper/number_converter.rb +8 -9
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  223. data/lib/active_support/number_helper/rounding_helper.rb +16 -34
  224. data/lib/active_support/number_helper.rb +38 -12
  225. data/lib/active_support/option_merger.rb +19 -6
  226. data/lib/active_support/ordered_hash.rb +4 -2
  227. data/lib/active_support/ordered_options.rb +18 -6
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +8 -1
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +3 -10
  232. data/lib/active_support/railtie.rb +112 -11
  233. data/lib/active_support/reloader.rb +12 -11
  234. data/lib/active_support/rescuable.rb +19 -18
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +26 -15
  238. data/lib/active_support/string_inquirer.rb +4 -3
  239. data/lib/active_support/subscriber.rb +81 -42
  240. data/lib/active_support/tagged_logging.rb +45 -9
  241. data/lib/active_support/test_case.rb +86 -2
  242. data/lib/active_support/testing/assertions.rb +89 -21
  243. data/lib/active_support/testing/autorun.rb +2 -0
  244. data/lib/active_support/testing/constant_lookup.rb +2 -0
  245. data/lib/active_support/testing/declarative.rb +2 -0
  246. data/lib/active_support/testing/deprecation.rb +54 -2
  247. data/lib/active_support/testing/file_fixtures.rb +4 -0
  248. data/lib/active_support/testing/isolation.rb +6 -4
  249. data/lib/active_support/testing/method_call_assertions.rb +34 -5
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  255. data/lib/active_support/testing/stream.rb +6 -7
  256. data/lib/active_support/testing/tagged_logging.rb +3 -1
  257. data/lib/active_support/testing/time_helpers.rb +91 -15
  258. data/lib/active_support/time.rb +2 -0
  259. data/lib/active_support/time_with_zone.rb +168 -56
  260. data/lib/active_support/values/time_zone.rb +85 -37
  261. data/lib/active_support/version.rb +3 -1
  262. data/lib/active_support/xml_mini/jdom.rb +6 -5
  263. data/lib/active_support/xml_mini/libxml.rb +9 -7
  264. data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
  265. data/lib/active_support/xml_mini/nokogiri.rb +8 -6
  266. data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
  267. data/lib/active_support/xml_mini/rexml.rb +13 -4
  268. data/lib/active_support/xml_mini.rb +10 -15
  269. data/lib/active_support.rb +30 -9
  270. metadata +76 -35
  271. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  272. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  273. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  274. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  275. data/lib/active_support/core_ext/marshal.rb +0 -22
  276. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  277. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  278. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  279. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/duplicable"
4
+
5
+ module ActiveSupport
6
+ # +ParameterFilter+ allows you to specify keys for sensitive data from
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.
12
+ #
13
+ # ActiveSupport::ParameterFilter.new([:password])
14
+ # => replaces the value to all keys matching /password/i with "[FILTERED]"
15
+ #
16
+ # ActiveSupport::ParameterFilter.new([:foo, "bar"])
17
+ # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
18
+ #
19
+ # ActiveSupport::ParameterFilter.new([/\Apin\z/i, /\Apin_/i])
20
+ # => replaces the value for the exact (case-insensitive) key 'pin' and all
21
+ # (case-insensitive) keys beginning with 'pin_', with "[FILTERED]".
22
+ # Does not match keys with 'pin' as a substring, such as 'shipping_id'.
23
+ #
24
+ # ActiveSupport::ParameterFilter.new(["credit_card.code"])
25
+ # => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
26
+ # change { file: { code: "xxxx"} }
27
+ #
28
+ # ActiveSupport::ParameterFilter.new([-> (k, v) do
29
+ # v.reverse! if /secret/i.match?(k)
30
+ # end])
31
+ # => reverses the value to all keys matching /secret/i
32
+ class ParameterFilter
33
+ FILTERED = "[FILTERED]" # :nodoc:
34
+
35
+ # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
36
+ # Other types of filters are treated as +String+ using +to_s+.
37
+ # For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
38
+ #
39
+ # ==== Options
40
+ #
41
+ # * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
42
+ def initialize(filters = [], mask: FILTERED)
43
+ @filters = filters
44
+ @mask = mask
45
+ end
46
+
47
+ # Mask value of +params+ if key matches one of filters.
48
+ def filter(params)
49
+ compiled_filter.call(params)
50
+ end
51
+
52
+ # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
53
+ def filter_param(key, value)
54
+ @filters.empty? ? value : compiled_filter.value_for_key(key, value)
55
+ end
56
+
57
+ private
58
+ def compiled_filter
59
+ @compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
60
+ end
61
+
62
+ class CompiledFilter # :nodoc:
63
+ def self.compile(filters, mask:)
64
+ return lambda { |params| params.dup } if filters.empty?
65
+
66
+ strings, regexps, blocks, deep_regexps, deep_strings = [], [], [], nil, nil
67
+
68
+ filters.each do |item|
69
+ case item
70
+ when Proc
71
+ blocks << item
72
+ when Regexp
73
+ if item.to_s.include?("\\.")
74
+ (deep_regexps ||= []) << item
75
+ else
76
+ regexps << item
77
+ end
78
+ else
79
+ s = Regexp.escape(item.to_s)
80
+ if s.include?("\\.")
81
+ (deep_strings ||= []) << s
82
+ else
83
+ strings << s
84
+ end
85
+ end
86
+ 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
+ end
93
+
94
+ attr_reader :regexps, :deep_regexps, :blocks
95
+
96
+ def initialize(regexps, deep_regexps, blocks, mask:)
97
+ @regexps = regexps
98
+ @deep_regexps = deep_regexps&.any? ? deep_regexps : nil
99
+ @blocks = blocks
100
+ @mask = mask
101
+ end
102
+
103
+ def call(params, parents = [], original_params = params)
104
+ filtered_params = params.class.new
105
+
106
+ params.each do |key, value|
107
+ filtered_params[key] = value_for_key(key, value, parents, original_params)
108
+ end
109
+
110
+ filtered_params
111
+ end
112
+
113
+ def value_for_key(key, value, parents = [], original_params = nil)
114
+ parents.push(key) if deep_regexps
115
+ if regexps.any? { |r| r.match?(key.to_s) }
116
+ value = @mask
117
+ elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
118
+ value = @mask
119
+ elsif value.is_a?(Hash)
120
+ value = call(value, parents, original_params)
121
+ elsif value.is_a?(Array)
122
+ # If we don't pop the current parent it will be duplicated as we
123
+ # process each array value.
124
+ parents.pop if deep_regexps
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
135
+ end
136
+ end
137
+ end
138
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/delegation"
2
4
 
3
5
  module ActiveSupport
@@ -38,7 +40,11 @@ module ActiveSupport
38
40
  # If the class has an initializer, it must accept no arguments.
39
41
  module PerThreadRegistry
40
42
  def self.extended(object)
41
- object.instance_variable_set "@per_thread_registry_key", object.name.freeze
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
42
48
  end
43
49
 
44
50
  def instance
@@ -54,5 +60,6 @@ module ActiveSupport
54
60
 
55
61
  send(name, *args, &block)
56
62
  end
63
+ ruby2_keywords(:method_missing)
57
64
  end
58
65
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # A class with no predefined methods that behaves similarly to Builder's
3
5
  # BlankSlate. Used for proxy classes.
@@ -1,4 +1,6 @@
1
- # This is private interface.
1
+ # frozen_string_literal: true
2
+
3
+ # This is a private interface.
2
4
  #
3
5
  # Rails components cherry pick from Active Support as needed, but there are a
4
6
  # few features that are used for sure in some way or another and it is not worth
@@ -11,9 +13,6 @@
11
13
  # Defines Object#blank? and Object#present?.
12
14
  require "active_support/core_ext/object/blank"
13
15
 
14
- # Rails own autoload, eager_load, etc.
15
- require "active_support/dependencies/autoload"
16
-
17
16
  # Support for ClassMethods and the included macro.
18
17
  require "active_support/concern"
19
18
 
@@ -25,9 +24,3 @@ require "active_support/core_ext/module/delegation"
25
24
 
26
25
  # Defines ActiveSupport::Deprecation.
27
26
  require "active_support/deprecation"
28
-
29
- # Defines Regexp#match?.
30
- #
31
- # This should be removed when Rails needs Ruby 2.4 or later, and the require
32
- # added where other Regexp extensions are being used (easy to grep).
33
- require "active_support/core_ext/regexp"
@@ -1,15 +1,83 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support"
2
4
  require "active_support/i18n_railtie"
3
5
 
4
6
  module ActiveSupport
5
7
  class Railtie < Rails::Railtie # :nodoc:
6
8
  config.active_support = ActiveSupport::OrderedOptions.new
9
+ config.active_support.disable_to_s_conversion = false
7
10
 
8
11
  config.eager_load_namespaces << ActiveSupport
9
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
+
30
+ initializer "active_support.set_authenticated_message_encryption" do |app|
31
+ config.after_initialize do
32
+ unless app.config.active_support.use_authenticated_message_encryption.nil?
33
+ ActiveSupport::MessageEncryptor.use_authenticated_message_encryption =
34
+ app.config.active_support.use_authenticated_message_encryption
35
+ end
36
+ end
37
+ end
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
+
45
+ initializer "active_support.reset_all_current_attributes_instances" do |app|
46
+ app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
47
+ app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
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
62
+ end
63
+
10
64
  initializer "active_support.deprecation_behavior" do |app|
11
- if deprecation = app.config.active_support.deprecation
12
- ActiveSupport::Deprecation.behavior = 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
13
81
  end
14
82
  end
15
83
 
@@ -22,14 +90,7 @@ module ActiveSupport
22
90
  raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
23
91
  end
24
92
  require "active_support/core_ext/time/zones"
25
- zone_default = Time.find_zone!(app.config.time_zone)
26
-
27
- unless zone_default
28
- raise "Value assigned to config.time_zone not recognized. " \
29
- 'Run "rake time:zones:all" for a time zone names list.'
30
- end
31
-
32
- Time.zone_default = zone_default
93
+ Time.zone_default = Time.find_zone!(app.config.time_zone)
33
94
  end
34
95
 
35
96
  # Sets the default week start
@@ -41,10 +102,50 @@ module ActiveSupport
41
102
  Date.beginning_of_week_default = beginning_of_week_default
42
103
  end
43
104
 
105
+ initializer "active_support.require_master_key" do |app|
106
+ if app.config.respond_to?(:require_master_key) && app.config.require_master_key
107
+ begin
108
+ app.credentials.key
109
+ rescue ActiveSupport::EncryptedFile::MissingKeyError => error
110
+ $stderr.puts error.message
111
+ exit 1
112
+ end
113
+ end
114
+ end
115
+
116
+ initializer "active_support.set_error_reporter" do |app|
117
+ ActiveSupport.error_reporter = app.executor.error_reporter
118
+ end
119
+
44
120
  initializer "active_support.set_configs" do |app|
45
121
  app.config.active_support.each do |k, v|
46
122
  k = "#{k}="
47
- ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
123
+ ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k
124
+ end
125
+ end
126
+
127
+ initializer "active_support.set_hash_digest_class" do |app|
128
+ config.after_initialize do
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
148
+ end
48
149
  end
49
150
  end
50
151
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/execution_wrapper"
4
+ require "active_support/executor"
2
5
 
3
6
  module ActiveSupport
4
7
  #--
@@ -26,14 +29,17 @@ module ActiveSupport
26
29
 
27
30
  define_callbacks :class_unload
28
31
 
32
+ # Registers a callback that will run once at application startup and every time the code is reloaded.
29
33
  def self.to_prepare(*args, &block)
30
34
  set_callback(:prepare, *args, &block)
31
35
  end
32
36
 
37
+ # Registers a callback that will run immediately before the classes are unloaded.
33
38
  def self.before_class_unload(*args, &block)
34
39
  set_callback(:class_unload, *args, &block)
35
40
  end
36
41
 
42
+ # Registers a callback that will run immediately after the classes are unloaded.
37
43
  def self.after_class_unload(*args, &block)
38
44
  set_callback(:class_unload, :after, *args, &block)
39
45
  end
@@ -44,17 +50,15 @@ module ActiveSupport
44
50
  def self.reload!
45
51
  executor.wrap do
46
52
  new.tap do |instance|
47
- begin
48
- instance.run!
49
- ensure
50
- instance.complete!
51
- end
53
+ instance.run!
54
+ ensure
55
+ instance.complete!
52
56
  end
53
57
  end
54
58
  prepare!
55
59
  end
56
60
 
57
- def self.run! # :nodoc:
61
+ def self.run!(reset: false) # :nodoc:
58
62
  if check!
59
63
  super
60
64
  else
@@ -69,11 +73,8 @@ module ActiveSupport
69
73
  end
70
74
  end
71
75
 
72
- class_attribute :executor
73
- class_attribute :check
74
-
75
- self.executor = Executor
76
- self.check = lambda { false }
76
+ class_attribute :executor, default: Executor
77
+ class_attribute :check, default: lambda { false }
77
78
 
78
79
  def self.check! # :nodoc:
79
80
  @should_reload ||= check.call
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/core_ext/class/attribute"
3
5
  require "active_support/core_ext/string/inflections"
@@ -8,17 +10,16 @@ module ActiveSupport
8
10
  extend Concern
9
11
 
10
12
  included do
11
- class_attribute :rescue_handlers
12
- self.rescue_handlers = []
13
+ class_attribute :rescue_handlers, default: []
13
14
  end
14
15
 
15
16
  module ClassMethods
16
- # Rescue exceptions raised in controller actions.
17
+ # Registers exception classes with a handler to be called by <tt>rescue_with_handler</tt>.
17
18
  #
18
19
  # <tt>rescue_from</tt> receives a series of exception classes or class
19
- # names, and a trailing <tt>:with</tt> option with the name of a method
20
- # or a Proc object to be called to handle them. Alternatively a block can
21
- # 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.
22
23
  #
23
24
  # Handlers that take one argument will be called with the exception, so
24
25
  # that the exception can be inspected when dealing with it.
@@ -29,20 +30,20 @@ module ActiveSupport
29
30
  # any.
30
31
  #
31
32
  # class ApplicationController < ActionController::Base
32
- # rescue_from User::NotAuthorized, with: :deny_access # self defined exception
33
- # rescue_from ActiveRecord::RecordInvalid, with: :show_errors
33
+ # rescue_from User::NotAuthorized, with: :deny_access
34
+ # rescue_from ActiveRecord::RecordInvalid, with: :show_record_errors
34
35
  #
35
- # rescue_from 'MyAppError::Base' do |exception|
36
- # render xml: exception, status: 500
36
+ # rescue_from "MyApp::BaseError" do |exception|
37
+ # redirect_to root_url, alert: exception.message
37
38
  # end
38
39
  #
39
40
  # private
40
41
  # def deny_access
41
- # ...
42
+ # head :forbidden
42
43
  # end
43
44
  #
44
- # def show_errors(exception)
45
- # exception.record.new_record? ? ...
45
+ # def show_record_errors(exception)
46
+ # redirect_back_or_to root_url, alert: exception.record.errors.full_messages.to_sentence
46
47
  # end
47
48
  # end
48
49
  #
@@ -73,12 +74,12 @@ module ActiveSupport
73
74
  # Matches an exception to a handler based on the exception class.
74
75
  #
75
76
  # If no handler matches the exception, check for a handler matching the
76
- # (optional) exception.cause. If no handler matches the exception or its
77
+ # (optional) +exception.cause+. If no handler matches the exception or its
77
78
  # cause, this returns +nil+, so you can deal with unhandled exceptions.
78
79
  # Be sure to re-raise unhandled exceptions if this is what you expect.
79
80
  #
80
81
  # begin
81
- #
82
+ # # ...
82
83
  # rescue => exception
83
84
  # rescue_with_handler(exception) || raise
84
85
  # end
@@ -99,7 +100,7 @@ module ActiveSupport
99
100
  end
100
101
  end
101
102
 
102
- def handler_for_rescue(exception, object: self) #:nodoc:
103
+ def handler_for_rescue(exception, object: self) # :nodoc:
103
104
  case rescuer = find_rescue_handler(exception)
104
105
  when Symbol
105
106
  method = object.method(rescuer)
@@ -159,14 +160,14 @@ module ActiveSupport
159
160
  end
160
161
 
161
162
  # Delegates to the class method, but uses the instance as the subject for
162
- # rescue_from handlers (method calls, instance_exec blocks).
163
+ # rescue_from handlers (method calls, +instance_exec+ blocks).
163
164
  def rescue_with_handler(exception)
164
165
  self.class.rescue_with_handler exception, object: self
165
166
  end
166
167
 
167
168
  # Internal handler lookup. Delegates to class method. Some libraries call
168
169
  # this directly, so keeping it around for compatibility.
169
- def handler_for_rescue(exception) #:nodoc:
170
+ def handler_for_rescue(exception) # :nodoc:
170
171
  self.class.handler_for_rescue exception, object: self
171
172
  end
172
173
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module RubyFeatures # :nodoc:
5
+ CLASS_SUBCLASSES = Class.method_defined?(:subclasses) # RUBY_VERSION >= "3.1"
6
+ end
7
+ 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,27 +1,38 @@
1
- require "digest"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
4
  module SecurityUtils
5
- # Constant time string comparison.
5
+ # Constant time string comparison, for fixed length strings.
6
6
  #
7
7
  # The values compared should be of fixed length, such as strings
8
- # that have already been processed by HMAC. This should not be used
9
- # on variable length plaintext strings because it could leak length info
10
- # via timing attacks.
11
- def secure_compare(a, b)
12
- return false unless a.bytesize == b.bytesize
8
+ # that have already been processed by HMAC. Raises in case of length mismatch.
9
+
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
13
17
 
14
- l = a.unpack "C#{a.bytesize}"
18
+ l = a.unpack "C#{a.bytesize}"
15
19
 
16
- res = 0
17
- b.each_byte { |byte| res |= byte ^ l.shift }
18
- res == 0
20
+ res = 0
21
+ b.each_byte { |byte| res |= byte ^ l.shift }
22
+ res == 0
23
+ end
19
24
  end
20
- module_function :secure_compare
25
+ module_function :fixed_length_secure_compare
21
26
 
22
- def variable_size_secure_compare(a, b) # :nodoc:
23
- secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b))
27
+ # Secure string comparison for strings of variable length.
28
+ #
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.
33
+ def secure_compare(a, b)
34
+ a.bytesize == b.bytesize && fixed_length_secure_compare(a, b)
24
35
  end
25
- module_function :variable_size_secure_compare
36
+ module_function :secure_compare
26
37
  end
27
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # Wrapping a string in this class gives you a prettier way to test
3
5
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
@@ -16,13 +18,12 @@ module ActiveSupport
16
18
  # vehicle.bike? # => false
17
19
  class StringInquirer < String
18
20
  private
19
-
20
21
  def respond_to_missing?(method_name, include_private = false)
21
- (method_name[-1] == "?") || super
22
+ method_name.end_with?("?") || super
22
23
  end
23
24
 
24
25
  def method_missing(method_name, *arguments)
25
- if method_name[-1] == "?"
26
+ if method_name.end_with?("?")
26
27
  self == method_name[0..-2]
27
28
  else
28
29
  super