activesupport 6.0.4.4 → 7.0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +257 -532
- data/MIT-LICENSE +1 -1
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +5 -5
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache/file_store.rb +16 -10
- data/lib/active_support/cache/mem_cache_store.rb +163 -42
- data/lib/active_support/cache/memory_store.rb +57 -29
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +79 -98
- data/lib/active_support/cache/strategy/local_cache.rb +49 -57
- data/lib/active_support/cache.rb +378 -179
- data/lib/active_support/callbacks.rb +230 -122
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +49 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +9 -6
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +13 -12
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -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 +1 -0
- 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 +34 -44
- 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 +9 -9
- 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 +17 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- 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 +164 -23
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +2 -3
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +2 -2
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- 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/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 +25 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +26 -13
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +40 -36
- data/lib/active_support/core_ext/module/introspection.rb +1 -25
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -73
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +11 -0
- data/lib/active_support/core_ext/object/json.rb +42 -26
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +20 -1
- 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 +6 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- 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 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +39 -5
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +92 -41
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- 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 +25 -7
- 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 -23
- 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 +39 -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 +58 -769
- data/lib/active_support/deprecation/behaviors.rb +23 -7
- 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 +6 -5
- data/lib/active_support/deprecation/proxy_wrappers.rb +4 -4
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +7 -2
- data/lib/active_support/descendants_tracker.rb +174 -64
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +24 -10
- data/lib/active_support/duration.rb +134 -55
- data/lib/active_support/encrypted_configuration.rb +13 -2
- data/lib/active_support/encrypted_file.rb +32 -3
- 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 +72 -138
- 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 +43 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +51 -25
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +14 -19
- data/lib/active_support/inflector/inflections.rb +24 -9
- data/lib/active_support/inflector/methods.rb +29 -49
- data/lib/active_support/inflector/transliterate.rb +5 -5
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +4 -4
- data/lib/active_support/json/encoding.rb +8 -4
- data/lib/active_support/key_generator.rb +23 -6
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- 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 +23 -5
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +34 -21
- data/lib/active_support/message_encryptor.rb +16 -13
- data/lib/active_support/message_verifier.rb +50 -18
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +6 -5
- data/lib/active_support/multibyte/chars.rb +13 -52
- data/lib/active_support/multibyte/unicode.rb +1 -87
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +110 -69
- data/lib/active_support/notifications/instrumenter.rb +37 -29
- data/lib/active_support/notifications.rb +55 -28
- data/lib/active_support/number_helper/number_converter.rb +2 -4
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -2
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +29 -16
- data/lib/active_support/option_merger.rb +11 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +9 -3
- data/lib/active_support/parameter_filter.rb +21 -11
- data/lib/active_support/per_thread_registry.rb +6 -1
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +77 -5
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +16 -16
- 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 -2
- data/lib/active_support/subscriber.rb +19 -25
- data/lib/active_support/tagged_logging.rb +31 -6
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +50 -13
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +5 -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 +16 -95
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +53 -5
- data/lib/active_support/time_with_zone.rb +126 -62
- data/lib/active_support/values/time_zone.rb +54 -23
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +9 -2
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +29 -1
- metadata +46 -45
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "erb"
|
4
|
-
require "active_support/core_ext/kernel/singleton_class"
|
5
4
|
require "active_support/core_ext/module/redefine_method"
|
6
5
|
require "active_support/multibyte/unicode"
|
7
6
|
|
@@ -12,6 +11,14 @@ class ERB
|
|
12
11
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
13
12
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
14
13
|
|
14
|
+
# Following XML requirements: https://www.w3.org/TR/REC-xml/#NT-Name
|
15
|
+
TAG_NAME_START_REGEXP_SET = "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
|
16
|
+
"\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \
|
17
|
+
"\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
|
18
|
+
TAG_NAME_START_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}]/
|
19
|
+
TAG_NAME_FOLLOWING_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}]/
|
20
|
+
TAG_NAME_REPLACEMENT_CHAR = "_"
|
21
|
+
|
15
22
|
# A utility method for escaping HTML tag characters.
|
16
23
|
# This method is also aliased as <tt>h</tt>.
|
17
24
|
#
|
@@ -85,7 +92,7 @@ class ERB
|
|
85
92
|
# use inside HTML attributes.
|
86
93
|
#
|
87
94
|
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
88
|
-
# whether or not it is being inserted via
|
95
|
+
# whether or not it is being inserted via <tt>html()</tt>. Most jQuery plugins do this.
|
89
96
|
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
90
97
|
# content returned by your JSON.
|
91
98
|
#
|
@@ -98,7 +105,7 @@ class ERB
|
|
98
105
|
# WARNING: this helper only works with valid JSON. Using this on non-JSON values
|
99
106
|
# will open up serious XSS vulnerabilities. For example, if you replace the
|
100
107
|
# +current_user.to_json+ in the example above with user input instead, the browser
|
101
|
-
# will happily eval() that string as JavaScript.
|
108
|
+
# will happily <tt>eval()</tt> that string as JavaScript.
|
102
109
|
#
|
103
110
|
# The escaping performed in this method is identical to those performed in the
|
104
111
|
# Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
|
@@ -116,6 +123,26 @@ class ERB
|
|
116
123
|
end
|
117
124
|
|
118
125
|
module_function :json_escape
|
126
|
+
|
127
|
+
# A utility method for escaping XML names of tags and names of attributes.
|
128
|
+
#
|
129
|
+
# xml_name_escape('1 < 2 & 3')
|
130
|
+
# # => "1___2___3"
|
131
|
+
#
|
132
|
+
# It follows the requirements of the specification: https://www.w3.org/TR/REC-xml/#NT-Name
|
133
|
+
def xml_name_escape(name)
|
134
|
+
name = name.to_s
|
135
|
+
return "" if name.blank?
|
136
|
+
|
137
|
+
starting_char = name[0].gsub(TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
138
|
+
|
139
|
+
return starting_char if name.size == 1
|
140
|
+
|
141
|
+
following_chars = name[1..-1].gsub(TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
142
|
+
|
143
|
+
starting_char + following_chars
|
144
|
+
end
|
145
|
+
module_function :xml_name_escape
|
119
146
|
end
|
120
147
|
end
|
121
148
|
|
@@ -131,7 +158,7 @@ class Numeric
|
|
131
158
|
end
|
132
159
|
end
|
133
160
|
|
134
|
-
module ActiveSupport
|
161
|
+
module ActiveSupport # :nodoc:
|
135
162
|
class SafeBuffer < String
|
136
163
|
UNSAFE_STRING_METHODS = %w(
|
137
164
|
capitalize chomp chop delete delete_prefix delete_suffix
|
@@ -144,7 +171,7 @@ module ActiveSupport #:nodoc:
|
|
144
171
|
alias_method :original_concat, :concat
|
145
172
|
private :original_concat
|
146
173
|
|
147
|
-
# Raised when
|
174
|
+
# Raised when ActiveSupport::SafeBuffer#safe_concat is called on unsafe buffers.
|
148
175
|
class SafeConcatError < StandardError
|
149
176
|
def initialize
|
150
177
|
super "Could not concatenate to the buffer because it is not html safe."
|
@@ -185,27 +212,30 @@ module ActiveSupport #:nodoc:
|
|
185
212
|
end
|
186
213
|
|
187
214
|
def concat(value)
|
188
|
-
|
215
|
+
unless value.nil?
|
216
|
+
super(implicit_html_escape_interpolated_argument(value))
|
217
|
+
end
|
218
|
+
self
|
189
219
|
end
|
190
220
|
alias << concat
|
191
221
|
|
192
222
|
def insert(index, value)
|
193
|
-
super(index,
|
223
|
+
super(index, implicit_html_escape_interpolated_argument(value))
|
194
224
|
end
|
195
225
|
|
196
226
|
def prepend(value)
|
197
|
-
super(
|
227
|
+
super(implicit_html_escape_interpolated_argument(value))
|
198
228
|
end
|
199
229
|
|
200
230
|
def replace(value)
|
201
|
-
super(
|
231
|
+
super(implicit_html_escape_interpolated_argument(value))
|
202
232
|
end
|
203
233
|
|
204
234
|
def []=(*args)
|
205
|
-
if args.
|
206
|
-
super(args[0], args[1],
|
235
|
+
if args.length == 3
|
236
|
+
super(args[0], args[1], implicit_html_escape_interpolated_argument(args[2]))
|
207
237
|
else
|
208
|
-
super(args[0],
|
238
|
+
super(args[0], implicit_html_escape_interpolated_argument(args[1]))
|
209
239
|
end
|
210
240
|
end
|
211
241
|
|
@@ -223,9 +253,9 @@ module ActiveSupport #:nodoc:
|
|
223
253
|
def %(args)
|
224
254
|
case args
|
225
255
|
when Hash
|
226
|
-
escaped_args =
|
256
|
+
escaped_args = args.transform_values { |arg| explicit_html_escape_interpolated_argument(arg) }
|
227
257
|
else
|
228
|
-
escaped_args = Array(args).map { |arg|
|
258
|
+
escaped_args = Array(args).map { |arg| explicit_html_escape_interpolated_argument(arg) }
|
229
259
|
end
|
230
260
|
|
231
261
|
self.class.new(super(escaped_args))
|
@@ -263,39 +293,60 @@ module ActiveSupport #:nodoc:
|
|
263
293
|
end
|
264
294
|
|
265
295
|
UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
EOT
|
291
|
-
end
|
296
|
+
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
297
|
+
def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
|
298
|
+
if block # if block
|
299
|
+
to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params|
|
300
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
301
|
+
block.call(*params) # block.call(*params)
|
302
|
+
} # }
|
303
|
+
else # else
|
304
|
+
to_str.#{unsafe_method}(*args) # to_str.gsub(*args)
|
305
|
+
end # end
|
306
|
+
end # end
|
307
|
+
|
308
|
+
def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
|
309
|
+
@html_safe = false # @html_safe = false
|
310
|
+
if block # if block
|
311
|
+
super(*args) { |*params| # super(*args) { |*params|
|
312
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
313
|
+
block.call(*params) # block.call(*params)
|
314
|
+
} # }
|
315
|
+
else # else
|
316
|
+
super # super
|
317
|
+
end # end
|
318
|
+
end # end
|
319
|
+
EOT
|
292
320
|
end
|
293
321
|
|
294
322
|
private
|
295
|
-
def
|
323
|
+
def explicit_html_escape_interpolated_argument(arg)
|
296
324
|
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
297
325
|
end
|
298
326
|
|
327
|
+
def implicit_html_escape_interpolated_argument(arg)
|
328
|
+
if !html_safe? || arg.html_safe?
|
329
|
+
arg
|
330
|
+
else
|
331
|
+
arg_string = begin
|
332
|
+
arg.to_str
|
333
|
+
rescue NoMethodError => error
|
334
|
+
if error.name == :to_str
|
335
|
+
str = arg.to_s
|
336
|
+
ActiveSupport::Deprecation.warn <<~MSG.squish
|
337
|
+
Implicit conversion of #{arg.class} into String by ActiveSupport::SafeBuffer
|
338
|
+
is deprecated and will be removed in Rails 7.1.
|
339
|
+
You must explicitly cast it to a String.
|
340
|
+
MSG
|
341
|
+
str
|
342
|
+
else
|
343
|
+
raise
|
344
|
+
end
|
345
|
+
end
|
346
|
+
CGI.escapeHTML(arg_string)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
299
350
|
def set_block_back_references(block, match_data)
|
300
351
|
block.binding.eval("proc { |m| $~ = m }").call(match_data)
|
301
352
|
rescue ArgumentError
|
@@ -6,6 +6,7 @@ require "active_support/time_with_zone"
|
|
6
6
|
require "active_support/core_ext/time/zones"
|
7
7
|
require "active_support/core_ext/date_and_time/calculations"
|
8
8
|
require "active_support/core_ext/date/calculations"
|
9
|
+
require "active_support/core_ext/module/remove_method"
|
9
10
|
|
10
11
|
class Time
|
11
12
|
include DateAndTime::Calculations
|
@@ -41,8 +42,8 @@ class Time
|
|
41
42
|
|
42
43
|
# Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
|
43
44
|
# instances can be used when called with a single argument
|
44
|
-
def at_with_coercion(*args)
|
45
|
-
return at_without_coercion(*args) if args.size != 1
|
45
|
+
def at_with_coercion(*args, **kwargs)
|
46
|
+
return at_without_coercion(*args, **kwargs) if args.size != 1 || !kwargs.empty?
|
46
47
|
|
47
48
|
# Time.at can be called with a time or numerical value
|
48
49
|
time_or_number = args.first
|
@@ -107,11 +108,26 @@ class Time
|
|
107
108
|
subsec
|
108
109
|
end
|
109
110
|
|
111
|
+
unless Time.method_defined?(:floor)
|
112
|
+
def floor(precision = 0)
|
113
|
+
change(nsec: 0) + subsec.floor(precision)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Restricted Ruby version due to a bug in `Time#ceil`
|
118
|
+
# See https://bugs.ruby-lang.org/issues/17025 for more details
|
119
|
+
if RUBY_VERSION <= "2.8"
|
120
|
+
remove_possible_method :ceil
|
121
|
+
def ceil(precision = 0)
|
122
|
+
change(nsec: 0) + subsec.ceil(precision)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
110
126
|
# Returns a new Time where one or more of the elements have been changed according
|
111
127
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
112
128
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
113
|
-
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
114
|
-
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
129
|
+
# the hour is passed, then minute, sec, usec, and nsec is set to 0. If the hour
|
130
|
+
# and minute is passed, then sec, usec, and nsec is set to 0. The +options+ parameter
|
115
131
|
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
116
132
|
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
117
133
|
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
@@ -143,6 +159,8 @@ class Time
|
|
143
159
|
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
144
160
|
elsif utc?
|
145
161
|
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
162
|
+
elsif zone&.respond_to?(:utc_to_local)
|
163
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
|
146
164
|
elsif zone
|
147
165
|
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
148
166
|
else
|
@@ -259,7 +277,7 @@ class Time
|
|
259
277
|
end
|
260
278
|
alias :at_end_of_minute :end_of_minute
|
261
279
|
|
262
|
-
def plus_with_duration(other)
|
280
|
+
def plus_with_duration(other) # :nodoc:
|
263
281
|
if ActiveSupport::Duration === other
|
264
282
|
other.since(self)
|
265
283
|
else
|
@@ -269,7 +287,7 @@ class Time
|
|
269
287
|
alias_method :plus_without_duration, :+
|
270
288
|
alias_method :+, :plus_with_duration
|
271
289
|
|
272
|
-
def minus_with_duration(other)
|
290
|
+
def minus_with_duration(other) # :nodoc:
|
273
291
|
if ActiveSupport::Duration === other
|
274
292
|
other.until(self)
|
275
293
|
else
|
@@ -287,7 +305,7 @@ class Time
|
|
287
305
|
other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
|
288
306
|
end
|
289
307
|
alias_method :minus_without_coercion, :-
|
290
|
-
alias_method :-, :minus_with_coercion
|
308
|
+
alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
|
291
309
|
|
292
310
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
293
311
|
# can be chronologically compared with a Time
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "time"
|
3
4
|
require "active_support/inflector/methods"
|
4
5
|
require "active_support/values/time_zone"
|
5
6
|
|
6
7
|
class Time
|
7
8
|
DATE_FORMATS = {
|
8
9
|
db: "%Y-%m-%d %H:%M:%S",
|
10
|
+
inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
|
9
11
|
number: "%Y%m%d%H%M%S",
|
10
12
|
nsec: "%Y%m%d%H%M%S%9N",
|
11
13
|
usec: "%Y%m%d%H%M%S%6N",
|
@@ -25,22 +27,22 @@ class Time
|
|
25
27
|
|
26
28
|
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
27
29
|
#
|
28
|
-
# This method is aliased to <tt>
|
30
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
29
31
|
#
|
30
32
|
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
31
33
|
#
|
34
|
+
# time.to_fs(:time) # => "06:10"
|
32
35
|
# time.to_formatted_s(:time) # => "06:10"
|
33
|
-
# time.to_s(:time) # => "06:10"
|
34
36
|
#
|
35
|
-
# time.
|
36
|
-
# time.
|
37
|
-
# time.
|
38
|
-
# time.
|
39
|
-
# time.
|
40
|
-
# time.
|
41
|
-
# time.
|
37
|
+
# time.to_fs(:db) # => "2007-01-18 06:10:17"
|
38
|
+
# time.to_fs(:number) # => "20070118061017"
|
39
|
+
# time.to_fs(:short) # => "18 Jan 06:10"
|
40
|
+
# time.to_fs(:long) # => "January 18, 2007 06:10"
|
41
|
+
# time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10"
|
42
|
+
# time.to_fs(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
|
43
|
+
# time.to_fs(:iso8601) # => "2007-01-18T06:10:17-06:00"
|
42
44
|
#
|
43
|
-
# == Adding your own time formats to +
|
45
|
+
# == Adding your own time formats to +to_fs+
|
44
46
|
# You can add your own formats to the Time::DATE_FORMATS hash.
|
45
47
|
# Use the format name as the hash key and either a strftime string
|
46
48
|
# or Proc instance that takes a time argument as the value.
|
@@ -48,15 +50,16 @@ class Time
|
|
48
50
|
# # config/initializers/time_formats.rb
|
49
51
|
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
|
50
52
|
# Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
|
51
|
-
def
|
53
|
+
def to_fs(format = :default)
|
52
54
|
if formatter = DATE_FORMATS[format]
|
53
55
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
54
56
|
else
|
57
|
+
# Change to `to_s` when deprecation is gone. Also deprecate `to_default_s`.
|
55
58
|
to_default_s
|
56
59
|
end
|
57
60
|
end
|
61
|
+
alias_method :to_formatted_s, :to_fs
|
58
62
|
alias_method :to_default_s, :to_s
|
59
|
-
alias_method :to_s, :to_formatted_s
|
60
63
|
|
61
64
|
# Returns a formatted string of the offset from UTC, or an alternative
|
62
65
|
# string if the time zone is already UTC.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
class Time
|
6
|
+
NOT_SET = Object.new # :nodoc:
|
7
|
+
def to_s(format = NOT_SET) # :nodoc:
|
8
|
+
if formatter = DATE_FORMATS[format]
|
9
|
+
ActiveSupport::Deprecation.warn(
|
10
|
+
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
|
11
|
+
)
|
12
|
+
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
13
|
+
elsif format == NOT_SET
|
14
|
+
to_default_s
|
15
|
+
else
|
16
|
+
ActiveSupport::Deprecation.warn(
|
17
|
+
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
|
18
|
+
)
|
19
|
+
to_default_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -12,7 +12,7 @@ class Time
|
|
12
12
|
# Returns the TimeZone for the current request, if this has been set (via Time.zone=).
|
13
13
|
# If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
|
14
14
|
def zone
|
15
|
-
|
15
|
+
::ActiveSupport::IsolatedExecutionState[:time_zone] || zone_default
|
16
16
|
end
|
17
17
|
|
18
18
|
# Sets <tt>Time.zone</tt> to a TimeZone object for the current request/thread.
|
@@ -21,8 +21,8 @@ class Time
|
|
21
21
|
#
|
22
22
|
# * A Rails TimeZone object.
|
23
23
|
# * An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", <tt>-5.hours</tt>).
|
24
|
-
# * A TZInfo::Timezone object.
|
25
|
-
# * An identifier for a TZInfo::Timezone object (e.g., "America/New_York").
|
24
|
+
# * A <tt>TZInfo::Timezone</tt> object.
|
25
|
+
# * An identifier for a <tt>TZInfo::Timezone</tt> object (e.g., "America/New_York").
|
26
26
|
#
|
27
27
|
# Here's an example of how you might set <tt>Time.zone</tt> on a per request basis and reset it when the request is done.
|
28
28
|
# <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
|
@@ -39,7 +39,7 @@ class Time
|
|
39
39
|
# end
|
40
40
|
# end
|
41
41
|
def zone=(time_zone)
|
42
|
-
|
42
|
+
::ActiveSupport::IsolatedExecutionState[:time_zone] = find_zone!(time_zone)
|
43
43
|
end
|
44
44
|
|
45
45
|
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
@@ -55,7 +55,7 @@ class Time
|
|
55
55
|
# end
|
56
56
|
# end
|
57
57
|
#
|
58
|
-
# NOTE: This won't affect any
|
58
|
+
# NOTE: This won't affect any ActiveSupport::TimeWithZone
|
59
59
|
# objects that have already been created, e.g. any model timestamp
|
60
60
|
# attributes that have been read before the block will remain in
|
61
61
|
# the application's default timezone.
|
@@ -80,24 +80,9 @@ class Time
|
|
80
80
|
# Time.find_zone! false # => false
|
81
81
|
# Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
|
82
82
|
def find_zone!(time_zone)
|
83
|
-
|
84
|
-
time_zone
|
85
|
-
else
|
86
|
-
# Look up the timezone based on the identifier (unless we've been
|
87
|
-
# passed a TZInfo::Timezone)
|
88
|
-
unless time_zone.respond_to?(:period_for_local)
|
89
|
-
time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
|
90
|
-
end
|
83
|
+
return time_zone unless time_zone
|
91
84
|
|
92
|
-
|
93
|
-
if time_zone.is_a?(ActiveSupport::TimeZone)
|
94
|
-
time_zone
|
95
|
-
else
|
96
|
-
ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
rescue TZInfo::InvalidTimezoneIdentifier
|
100
|
-
raise ArgumentError, "Invalid Timezone: #{time_zone}"
|
85
|
+
ActiveSupport::TimeZone[time_zone] || raise(ArgumentError, "Invalid Timezone: #{time_zone}")
|
101
86
|
end
|
102
87
|
|
103
88
|
# Returns a TimeZone instance matching the time zone provided.
|
@@ -4,4 +4,5 @@ require "active_support/core_ext/time/acts_like"
|
|
4
4
|
require "active_support/core_ext/time/calculations"
|
5
5
|
require "active_support/core_ext/time/compatibility"
|
6
6
|
require "active_support/core_ext/time/conversions"
|
7
|
+
require "active_support/core_ext/time/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
7
8
|
require "active_support/core_ext/time/zones"
|
@@ -1,25 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require "active_support/core_ext/module/redefine_method"
|
7
|
-
URI::Parser.class_eval do
|
8
|
-
silence_redefinition_of_method :unescape
|
9
|
-
def unescape(str, escaped = /%[a-fA-F\d]{2}/)
|
10
|
-
# TODO: Are we actually sure that ASCII == UTF-8?
|
11
|
-
# YK: My initial experiments say yes, but let's be sure please
|
12
|
-
enc = str.encoding
|
13
|
-
enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
|
14
|
-
str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
module URI
|
20
|
-
class << self
|
21
|
-
def parser
|
22
|
-
@parser ||= URI::Parser.new
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
3
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
4
|
+
`active_support/core_ext/uri` is deprecated and will be removed in Rails 7.1.
|
5
|
+
MSG
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport::CurrentAttributes::TestHelper # :nodoc:
|
4
|
+
def before_setup
|
5
|
+
ActiveSupport::CurrentAttributes.reset_all
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def after_teardown
|
10
|
+
super
|
11
|
+
ActiveSupport::CurrentAttributes.reset_all
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/callbacks"
|
4
|
+
require "active_support/core_ext/enumerable"
|
5
|
+
require "active_support/core_ext/module/delegation"
|
4
6
|
|
5
7
|
module ActiveSupport
|
6
8
|
# Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
|
@@ -91,30 +93,42 @@ module ActiveSupport
|
|
91
93
|
class << self
|
92
94
|
# Returns singleton instance for this class in this thread. If none exists, one is created.
|
93
95
|
def instance
|
94
|
-
current_instances[
|
96
|
+
current_instances[current_instances_key] ||= new
|
95
97
|
end
|
96
98
|
|
97
99
|
# Declares one or more attributes that will be given both class and instance accessor methods.
|
98
100
|
def attribute(*names)
|
99
|
-
generated_attribute_methods
|
101
|
+
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
|
100
102
|
names.each do |name|
|
101
|
-
|
102
|
-
|
103
|
+
owner.define_cached_method(name, namespace: :current_attributes) do |batch|
|
104
|
+
batch <<
|
105
|
+
"def #{name}" <<
|
106
|
+
"attributes[:#{name}]" <<
|
107
|
+
"end"
|
103
108
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
109
|
+
owner.define_cached_method("#{name}=", namespace: :current_attributes) do |batch|
|
110
|
+
batch <<
|
111
|
+
"def #{name}=(value)" <<
|
112
|
+
"attributes[:#{name}] = value" <<
|
113
|
+
"end"
|
107
114
|
end
|
108
115
|
end
|
109
116
|
end
|
110
117
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
+
ActiveSupport::CodeGenerator.batch(singleton_class, __FILE__, __LINE__) do |owner|
|
119
|
+
names.each do |name|
|
120
|
+
owner.define_cached_method(name, namespace: :current_attributes_delegation) do |batch|
|
121
|
+
batch <<
|
122
|
+
"def #{name}" <<
|
123
|
+
"instance.#{name}" <<
|
124
|
+
"end"
|
125
|
+
end
|
126
|
+
owner.define_cached_method("#{name}=", namespace: :current_attributes_delegation) do |batch|
|
127
|
+
batch <<
|
128
|
+
"def #{name}=(value)" <<
|
129
|
+
"instance.#{name} = value" <<
|
130
|
+
"end"
|
131
|
+
end
|
118
132
|
end
|
119
133
|
end
|
120
134
|
end
|
@@ -147,7 +161,11 @@ module ActiveSupport
|
|
147
161
|
end
|
148
162
|
|
149
163
|
def current_instances
|
150
|
-
|
164
|
+
IsolatedExecutionState[:current_attributes_instances] ||= {}
|
165
|
+
end
|
166
|
+
|
167
|
+
def current_instances_key
|
168
|
+
@current_instances_key ||= name.to_sym
|
151
169
|
end
|
152
170
|
|
153
171
|
def method_missing(name, *args, &block)
|
@@ -158,6 +176,11 @@ module ActiveSupport
|
|
158
176
|
|
159
177
|
send(name, *args, &block)
|
160
178
|
end
|
179
|
+
ruby2_keywords(:method_missing)
|
180
|
+
|
181
|
+
def respond_to_missing?(name, _)
|
182
|
+
super || instance.respond_to?(name)
|
183
|
+
end
|
161
184
|
end
|
162
185
|
|
163
186
|
attr_accessor :attributes
|
@@ -197,7 +220,7 @@ module ActiveSupport
|
|
197
220
|
end
|
198
221
|
|
199
222
|
def compute_attributes(keys)
|
200
|
-
keys.
|
223
|
+
keys.index_with { |key| public_send(key) }
|
201
224
|
end
|
202
225
|
end
|
203
226
|
end
|