activesupport 6.1.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +263 -352
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/backtrace_cleaner.rb +2 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +16 -10
- data/lib/active_support/cache/mem_cache_store.rb +154 -39
- data/lib/active_support/cache/memory_store.rb +24 -16
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +59 -78
- data/lib/active_support/cache/strategy/local_cache.rb +38 -61
- data/lib/active_support/cache.rb +306 -148
- data/lib/active_support/callbacks.rb +184 -85
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +5 -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 +8 -5
- data/lib/active_support/configuration_file.rb +7 -2
- 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/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +25 -17
- 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 +14 -14
- 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 +4 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- 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 +101 -32
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +0 -1
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
- 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 +37 -25
- 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 +0 -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 -25
- 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/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -1
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +91 -39
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +9 -7
- data/lib/active_support/core_ext/time/conversions.rb +14 -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 -27
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes.rb +32 -14
- 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 -788
- data/lib/active_support/deprecation/behaviors.rb +8 -5
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +174 -68
- 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 +9 -1
- data/lib/active_support/duration.rb +81 -51
- data/lib/active_support/encrypted_configuration.rb +13 -2
- data/lib/active_support/encrypted_file.rb +13 -1
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +3 -5
- 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 +19 -10
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +9 -2
- 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 +1 -1
- data/lib/active_support/inflector/inflections.rb +23 -7
- data/lib/active_support/inflector/methods.rb +24 -48
- data/lib/active_support/inflector/transliterate.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +22 -5
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +2 -2
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +15 -5
- data/lib/active_support/logger_thread_safe_level.rb +4 -13
- data/lib/active_support/message_encryptor.rb +12 -6
- data/lib/active_support/message_verifier.rb +46 -14
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +91 -65
- data/lib/active_support/notifications/instrumenter.rb +32 -15
- data/lib/active_support/notifications.rb +24 -24
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- 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_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +10 -6
- data/lib/active_support/number_helper/rounding_helper.rb +2 -6
- data/lib/active_support/number_helper.rb +0 -2
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +6 -1
- data/lib/active_support/per_thread_registry.rb +5 -0
- data/lib/active_support/railtie.rb +69 -19
- 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 +2 -2
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +7 -18
- data/lib/active_support/tagged_logging.rb +2 -2
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +36 -6
- 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 +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- 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 +13 -2
- data/lib/active_support/time_with_zone.rb +60 -20
- data/lib/active_support/values/time_zone.rb +36 -15
- 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 +1 -1
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +17 -1
- metadata +29 -26
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/range/conversions"
|
|
4
|
+
require "active_support/core_ext/range/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
|
4
5
|
require "active_support/core_ext/range/compare_range"
|
|
5
|
-
require "active_support/core_ext/range/include_time_with_zone"
|
|
6
6
|
require "active_support/core_ext/range/overlaps"
|
|
7
7
|
require "active_support/core_ext/range/each"
|
|
@@ -12,7 +12,7 @@ module SecureRandom
|
|
|
12
12
|
#
|
|
13
13
|
# If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future.
|
|
14
14
|
#
|
|
15
|
-
# The result may contain alphanumeric characters except 0, O, I and l.
|
|
15
|
+
# The result may contain alphanumeric characters except 0, O, I, and l.
|
|
16
16
|
#
|
|
17
17
|
# p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
|
|
18
18
|
# p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
|
|
@@ -5,10 +5,10 @@ require "active_support/core_ext/time/calculations"
|
|
|
5
5
|
|
|
6
6
|
class String
|
|
7
7
|
# Converts a string to a Time value.
|
|
8
|
-
# The +form+ can be either
|
|
8
|
+
# The +form+ can be either +:utc+ or +:local+ (default +:local+).
|
|
9
9
|
#
|
|
10
10
|
# The time is parsed using Time.parse method.
|
|
11
|
-
# If +form+ is
|
|
11
|
+
# If +form+ is +:local+, then the time is in the system timezone.
|
|
12
12
|
# If the date part is missing then the current date is used and if
|
|
13
13
|
# the time part is missing then it is assumed to be 00:00:00.
|
|
14
14
|
#
|
|
@@ -260,7 +260,7 @@ class String
|
|
|
260
260
|
# 'author_id'.humanize # => "Author"
|
|
261
261
|
# 'author_id'.humanize(capitalize: false) # => "author"
|
|
262
262
|
# '_id'.humanize # => "Id"
|
|
263
|
-
# 'author_id'.humanize(keep_id_suffix: true) # => "Author
|
|
263
|
+
# 'author_id'.humanize(keep_id_suffix: true) # => "Author id"
|
|
264
264
|
#
|
|
265
265
|
# See ActiveSupport::Inflector.humanize.
|
|
266
266
|
def humanize(capitalize: true, keep_id_suffix: false)
|
|
@@ -4,7 +4,7 @@ require "active_support/string_inquirer"
|
|
|
4
4
|
require "active_support/environment_inquirer"
|
|
5
5
|
|
|
6
6
|
class String
|
|
7
|
-
# Wraps the current string in the
|
|
7
|
+
# Wraps the current string in the ActiveSupport::StringInquirer class,
|
|
8
8
|
# which gives you a prettier way to test for equality.
|
|
9
9
|
#
|
|
10
10
|
# env = 'production'.inquiry
|
|
@@ -11,6 +11,14 @@ class ERB
|
|
|
11
11
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
|
12
12
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
|
13
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
|
+
|
|
14
22
|
# A utility method for escaping HTML tag characters.
|
|
15
23
|
# This method is also aliased as <tt>h</tt>.
|
|
16
24
|
#
|
|
@@ -84,7 +92,7 @@ class ERB
|
|
|
84
92
|
# use inside HTML attributes.
|
|
85
93
|
#
|
|
86
94
|
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
|
87
|
-
# 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.
|
|
88
96
|
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
|
89
97
|
# content returned by your JSON.
|
|
90
98
|
#
|
|
@@ -97,7 +105,7 @@ class ERB
|
|
|
97
105
|
# WARNING: this helper only works with valid JSON. Using this on non-JSON values
|
|
98
106
|
# will open up serious XSS vulnerabilities. For example, if you replace the
|
|
99
107
|
# +current_user.to_json+ in the example above with user input instead, the browser
|
|
100
|
-
# will happily eval() that string as JavaScript.
|
|
108
|
+
# will happily <tt>eval()</tt> that string as JavaScript.
|
|
101
109
|
#
|
|
102
110
|
# The escaping performed in this method is identical to those performed in the
|
|
103
111
|
# Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
|
|
@@ -115,6 +123,26 @@ class ERB
|
|
|
115
123
|
end
|
|
116
124
|
|
|
117
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
|
|
118
146
|
end
|
|
119
147
|
end
|
|
120
148
|
|
|
@@ -130,7 +158,7 @@ class Numeric
|
|
|
130
158
|
end
|
|
131
159
|
end
|
|
132
160
|
|
|
133
|
-
module ActiveSupport
|
|
161
|
+
module ActiveSupport # :nodoc:
|
|
134
162
|
class SafeBuffer < String
|
|
135
163
|
UNSAFE_STRING_METHODS = %w(
|
|
136
164
|
capitalize chomp chop delete delete_prefix delete_suffix
|
|
@@ -143,7 +171,7 @@ module ActiveSupport #:nodoc:
|
|
|
143
171
|
alias_method :original_concat, :concat
|
|
144
172
|
private :original_concat
|
|
145
173
|
|
|
146
|
-
# Raised when
|
|
174
|
+
# Raised when ActiveSupport::SafeBuffer#safe_concat is called on unsafe buffers.
|
|
147
175
|
class SafeConcatError < StandardError
|
|
148
176
|
def initialize
|
|
149
177
|
super "Could not concatenate to the buffer because it is not html safe."
|
|
@@ -184,27 +212,30 @@ module ActiveSupport #:nodoc:
|
|
|
184
212
|
end
|
|
185
213
|
|
|
186
214
|
def concat(value)
|
|
187
|
-
|
|
215
|
+
unless value.nil?
|
|
216
|
+
super(implicit_html_escape_interpolated_argument(value))
|
|
217
|
+
end
|
|
218
|
+
self
|
|
188
219
|
end
|
|
189
220
|
alias << concat
|
|
190
221
|
|
|
191
222
|
def insert(index, value)
|
|
192
|
-
super(index,
|
|
223
|
+
super(index, implicit_html_escape_interpolated_argument(value))
|
|
193
224
|
end
|
|
194
225
|
|
|
195
226
|
def prepend(value)
|
|
196
|
-
super(
|
|
227
|
+
super(implicit_html_escape_interpolated_argument(value))
|
|
197
228
|
end
|
|
198
229
|
|
|
199
230
|
def replace(value)
|
|
200
|
-
super(
|
|
231
|
+
super(implicit_html_escape_interpolated_argument(value))
|
|
201
232
|
end
|
|
202
233
|
|
|
203
234
|
def []=(*args)
|
|
204
235
|
if args.length == 3
|
|
205
|
-
super(args[0], args[1],
|
|
236
|
+
super(args[0], args[1], implicit_html_escape_interpolated_argument(args[2]))
|
|
206
237
|
else
|
|
207
|
-
super(args[0],
|
|
238
|
+
super(args[0], implicit_html_escape_interpolated_argument(args[1]))
|
|
208
239
|
end
|
|
209
240
|
end
|
|
210
241
|
|
|
@@ -222,9 +253,9 @@ module ActiveSupport #:nodoc:
|
|
|
222
253
|
def %(args)
|
|
223
254
|
case args
|
|
224
255
|
when Hash
|
|
225
|
-
escaped_args = args.transform_values { |arg|
|
|
256
|
+
escaped_args = args.transform_values { |arg| explicit_html_escape_interpolated_argument(arg) }
|
|
226
257
|
else
|
|
227
|
-
escaped_args = Array(args).map { |arg|
|
|
258
|
+
escaped_args = Array(args).map { |arg| explicit_html_escape_interpolated_argument(arg) }
|
|
228
259
|
end
|
|
229
260
|
|
|
230
261
|
self.class.new(super(escaped_args))
|
|
@@ -262,39 +293,60 @@ module ActiveSupport #:nodoc:
|
|
|
262
293
|
end
|
|
263
294
|
|
|
264
295
|
UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
EOT
|
|
290
|
-
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
|
|
291
320
|
end
|
|
292
321
|
|
|
293
322
|
private
|
|
294
|
-
def
|
|
323
|
+
def explicit_html_escape_interpolated_argument(arg)
|
|
295
324
|
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
|
296
325
|
end
|
|
297
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
|
+
|
|
298
350
|
def set_block_back_references(block, match_data)
|
|
299
351
|
block.binding.eval("proc { |m| $~ = m }").call(match_data)
|
|
300
352
|
rescue ArgumentError
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Symbol
|
|
4
|
-
def start_with?(*prefixes)
|
|
5
|
-
to_s.start_with?(*prefixes)
|
|
6
|
-
end unless method_defined?(:start_with?)
|
|
7
|
-
|
|
8
|
-
def end_with?(*suffixes)
|
|
9
|
-
to_s.end_with?(*suffixes)
|
|
10
|
-
end unless method_defined?(:end_with?)
|
|
11
|
-
|
|
12
4
|
alias :starts_with? :start_with?
|
|
13
5
|
alias :ends_with? :end_with?
|
|
14
6
|
end
|
|
@@ -42,8 +42,8 @@ class Time
|
|
|
42
42
|
|
|
43
43
|
# Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
|
|
44
44
|
# instances can be used when called with a single argument
|
|
45
|
-
def at_with_coercion(*args)
|
|
46
|
-
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?
|
|
47
47
|
|
|
48
48
|
# Time.at can be called with a time or numerical value
|
|
49
49
|
time_or_number = args.first
|
|
@@ -126,8 +126,8 @@ class Time
|
|
|
126
126
|
# Returns a new Time where one or more of the elements have been changed according
|
|
127
127
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
|
128
128
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
|
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
|
|
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
|
|
131
131
|
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
|
132
132
|
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
|
133
133
|
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
|
@@ -159,6 +159,8 @@ class Time
|
|
|
159
159
|
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
|
160
160
|
elsif utc?
|
|
161
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)
|
|
162
164
|
elsif zone
|
|
163
165
|
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
|
164
166
|
else
|
|
@@ -275,7 +277,7 @@ class Time
|
|
|
275
277
|
end
|
|
276
278
|
alias :at_end_of_minute :end_of_minute
|
|
277
279
|
|
|
278
|
-
def plus_with_duration(other)
|
|
280
|
+
def plus_with_duration(other) # :nodoc:
|
|
279
281
|
if ActiveSupport::Duration === other
|
|
280
282
|
other.since(self)
|
|
281
283
|
else
|
|
@@ -285,7 +287,7 @@ class Time
|
|
|
285
287
|
alias_method :plus_without_duration, :+
|
|
286
288
|
alias_method :+, :plus_with_duration
|
|
287
289
|
|
|
288
|
-
def minus_with_duration(other)
|
|
290
|
+
def minus_with_duration(other) # :nodoc:
|
|
289
291
|
if ActiveSupport::Duration === other
|
|
290
292
|
other.until(self)
|
|
291
293
|
else
|
|
@@ -303,7 +305,7 @@ class Time
|
|
|
303
305
|
other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
|
|
304
306
|
end
|
|
305
307
|
alias_method :minus_without_coercion, :-
|
|
306
|
-
alias_method :-, :minus_with_coercion
|
|
308
|
+
alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
|
|
307
309
|
|
|
308
310
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
|
309
311
|
# can be chronologically compared with a Time
|
|
@@ -1,5 +1,6 @@
|
|
|
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
|
|
|
@@ -26,22 +27,22 @@ class Time
|
|
|
26
27
|
|
|
27
28
|
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
|
28
29
|
#
|
|
29
|
-
# This method is aliased to <tt>
|
|
30
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
|
30
31
|
#
|
|
31
32
|
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
|
32
33
|
#
|
|
34
|
+
# time.to_fs(:time) # => "06:10"
|
|
33
35
|
# time.to_formatted_s(:time) # => "06:10"
|
|
34
|
-
# time.to_s(:time) # => "06:10"
|
|
35
36
|
#
|
|
36
|
-
# time.
|
|
37
|
-
# time.
|
|
38
|
-
# time.
|
|
39
|
-
# time.
|
|
40
|
-
# time.
|
|
41
|
-
# time.
|
|
42
|
-
# 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"
|
|
43
44
|
#
|
|
44
|
-
# == Adding your own time formats to +
|
|
45
|
+
# == Adding your own time formats to +to_fs+
|
|
45
46
|
# You can add your own formats to the Time::DATE_FORMATS hash.
|
|
46
47
|
# Use the format name as the hash key and either a strftime string
|
|
47
48
|
# or Proc instance that takes a time argument as the value.
|
|
@@ -49,15 +50,16 @@ class Time
|
|
|
49
50
|
# # config/initializers/time_formats.rb
|
|
50
51
|
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
|
|
51
52
|
# Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
|
|
52
|
-
def
|
|
53
|
+
def to_fs(format = :default)
|
|
53
54
|
if formatter = DATE_FORMATS[format]
|
|
54
55
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
|
55
56
|
else
|
|
57
|
+
# Change to `to_s` when deprecation is gone. Also deprecate `to_default_s`.
|
|
56
58
|
to_default_s
|
|
57
59
|
end
|
|
58
60
|
end
|
|
61
|
+
alias_method :to_formatted_s, :to_fs
|
|
59
62
|
alias_method :to_default_s, :to_s
|
|
60
|
-
alias_method :to_s, :to_formatted_s
|
|
61
63
|
|
|
62
64
|
# Returns a formatted string of the offset from UTC, or an alternative
|
|
63
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,29 +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
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
|
23
|
-
URI.parser is deprecated and will be removed in Rails 6.2.
|
|
24
|
-
Use `URI::DEFAULT_PARSER` instead.
|
|
25
|
-
MSG
|
|
26
|
-
URI::DEFAULT_PARSER
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
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
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "active_support/callbacks"
|
|
4
4
|
require "active_support/core_ext/enumerable"
|
|
5
|
+
require "active_support/core_ext/module/delegation"
|
|
5
6
|
|
|
6
7
|
module ActiveSupport
|
|
7
8
|
# Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
|
|
@@ -97,25 +98,37 @@ module ActiveSupport
|
|
|
97
98
|
|
|
98
99
|
# Declares one or more attributes that will be given both class and instance accessor methods.
|
|
99
100
|
def attribute(*names)
|
|
100
|
-
generated_attribute_methods
|
|
101
|
+
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
|
|
101
102
|
names.each do |name|
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
owner.define_cached_method(name, namespace: :current_attributes) do |batch|
|
|
104
|
+
batch <<
|
|
105
|
+
"def #{name}" <<
|
|
106
|
+
"attributes[:#{name}]" <<
|
|
107
|
+
"end"
|
|
104
108
|
end
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
owner.define_cached_method("#{name}=", namespace: :current_attributes) do |batch|
|
|
110
|
+
batch <<
|
|
111
|
+
"def #{name}=(value)" <<
|
|
112
|
+
"attributes[:#{name}] = value" <<
|
|
113
|
+
"end"
|
|
108
114
|
end
|
|
109
115
|
end
|
|
110
116
|
end
|
|
111
117
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
|
119
132
|
end
|
|
120
133
|
end
|
|
121
134
|
end
|
|
@@ -148,7 +161,7 @@ module ActiveSupport
|
|
|
148
161
|
end
|
|
149
162
|
|
|
150
163
|
def current_instances
|
|
151
|
-
|
|
164
|
+
IsolatedExecutionState[:current_attributes_instances] ||= {}
|
|
152
165
|
end
|
|
153
166
|
|
|
154
167
|
def current_instances_key
|
|
@@ -163,6 +176,11 @@ module ActiveSupport
|
|
|
163
176
|
|
|
164
177
|
send(name, *args, &block)
|
|
165
178
|
end
|
|
179
|
+
ruby2_keywords(:method_missing)
|
|
180
|
+
|
|
181
|
+
def respond_to_missing?(name, _)
|
|
182
|
+
super || instance.respond_to?(name)
|
|
183
|
+
end
|
|
166
184
|
end
|
|
167
185
|
|
|
168
186
|
attr_accessor :attributes
|