activesupport 4.2.11.1 → 6.0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

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