activesupport 5.1.7 → 7.0.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +259 -585
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +33 -5
- data/lib/active_support/benchmarkable.rb +5 -3
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +50 -43
- data/lib/active_support/cache/mem_cache_store.rb +194 -67
- data/lib/active_support/cache/memory_store.rb +70 -34
- data/lib/active_support/cache/null_store.rb +18 -3
- data/lib/active_support/cache/redis_cache_store.rb +474 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -50
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +556 -220
- data/lib/active_support/callbacks.rb +264 -159
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +81 -8
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
- data/lib/active_support/concurrency/share_lock.rb +4 -3
- data/lib/active_support/configurable.rb +17 -16
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +18 -8
- data/lib/active_support/core_ext/array/conversions.rb +20 -17
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +8 -6
- data/lib/active_support/core_ext/array/inquiry.rb +4 -2
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +4 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +50 -47
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +10 -24
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +3 -1
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +24 -22
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +3 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +3 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +3 -0
- data/lib/active_support/core_ext/digest/uuid.rb +42 -14
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +244 -72
- data/lib/active_support/core_ext/file/atomic.rb +6 -2
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -6
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -31
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
- data/lib/active_support/core_ext/kernel.rb +2 -1
- data/lib/active_support/core_ext/load_error.rb +3 -8
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +97 -58
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +18 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -1
- data/lib/active_support/core_ext/name_error.rb +30 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +3 -1
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +15 -5
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
- data/lib/active_support/core_ext/object/duplicable.rb +16 -110
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +51 -26
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +4 -2
- data/lib/active_support/core_ext/object/try.rb +26 -14
- data/lib/active_support/core_ext/object/with_options.rb +24 -3
- data/lib/active_support/core_ext/object.rb +2 -0
- 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 +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +6 -3
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
- data/lib/active_support/core_ext/range/overlaps.rb +3 -1
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/regexp.rb +10 -5
- data/lib/active_support/core_ext/securerandom.rb +25 -3
- data/lib/active_support/core_ext/string/access.rb +7 -16
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +5 -2
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +44 -1
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +69 -16
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +135 -27
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- 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/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +81 -24
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +17 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +12 -25
- data/lib/active_support/core_ext/time.rb +3 -0
- data/lib/active_support/core_ext/uri.rb +4 -23
- data/lib/active_support/core_ext.rb +4 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +12 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +59 -715
- data/lib/active_support/deprecation/behaviors.rb +48 -13
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -1
- data/lib/active_support/deprecation/method_wrappers.rb +29 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +10 -3
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +9 -9
- data/lib/active_support/duration/iso8601_serializer.rb +29 -15
- data/lib/active_support/duration.rb +158 -72
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +129 -0
- 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 +87 -122
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +46 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -1
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +7 -5
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +126 -42
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +5 -1
- data/lib/active_support/i18n_railtie.rb +19 -14
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +41 -14
- data/lib/active_support/inflector/methods.rb +73 -87
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +16 -6
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +25 -38
- data/lib/active_support/lazy_load_hooks.rb +35 -6
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber/test_helper.rb +4 -2
- data/lib/active_support/log_subscriber.rb +54 -13
- data/lib/active_support/logger.rb +4 -17
- data/lib/active_support/logger_silence.rb +13 -20
- data/lib/active_support/logger_thread_safe_level.rb +48 -10
- data/lib/active_support/message_encryptor.rb +111 -37
- data/lib/active_support/message_verifier.rb +124 -21
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +19 -76
- data/lib/active_support/multibyte/unicode.rb +9 -331
- data/lib/active_support/multibyte.rb +3 -1
- data/lib/active_support/notifications/fanout.rb +165 -37
- data/lib/active_support/notifications/instrumenter.rb +92 -11
- data/lib/active_support/notifications.rb +96 -30
- data/lib/active_support/number_helper/number_converter.rb +8 -9
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
- data/lib/active_support/number_helper/rounding_helper.rb +16 -34
- data/lib/active_support/number_helper.rb +38 -12
- data/lib/active_support/option_merger.rb +19 -6
- data/lib/active_support/ordered_hash.rb +4 -2
- data/lib/active_support/ordered_options.rb +18 -6
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +8 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +112 -11
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +19 -18
- 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 +26 -15
- data/lib/active_support/string_inquirer.rb +4 -3
- data/lib/active_support/subscriber.rb +81 -42
- data/lib/active_support/tagged_logging.rb +45 -9
- data/lib/active_support/test_case.rb +86 -2
- data/lib/active_support/testing/assertions.rb +89 -21
- data/lib/active_support/testing/autorun.rb +2 -0
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +54 -2
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +6 -4
- data/lib/active_support/testing/method_call_assertions.rb +34 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +6 -7
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +91 -15
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +168 -56
- data/lib/active_support/values/time_zone.rb +85 -37
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +6 -5
- data/lib/active_support/xml_mini/libxml.rb +9 -7
- data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
- data/lib/active_support/xml_mini/nokogiri.rb +8 -6
- data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
- data/lib/active_support/xml_mini/rexml.rb +13 -4
- data/lib/active_support/xml_mini.rb +10 -15
- data/lib/active_support.rb +30 -9
- metadata +76 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/marshal.rb +0 -22
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "erb"
|
2
|
-
require "active_support/core_ext/
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
3
5
|
require "active_support/multibyte/unicode"
|
4
6
|
|
5
7
|
class ERB
|
@@ -9,25 +11,29 @@ class ERB
|
|
9
11
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
10
12
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
11
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
|
+
|
12
22
|
# A utility method for escaping HTML tag characters.
|
13
23
|
# This method is also aliased as <tt>h</tt>.
|
14
24
|
#
|
15
|
-
# In your ERB templates, use this method to escape any unsafe content. For example:
|
16
|
-
# <%= h @person.name %>
|
17
|
-
#
|
18
25
|
# puts html_escape('is a > 0 & a < 10?')
|
19
26
|
# # => is a > 0 & a < 10?
|
20
27
|
def html_escape(s)
|
21
28
|
unwrapped_html_escape(s).html_safe
|
22
29
|
end
|
23
30
|
|
24
|
-
|
25
|
-
remove_method(:h)
|
31
|
+
silence_redefinition_of_method :h
|
26
32
|
alias h html_escape
|
27
33
|
|
28
34
|
module_function :h
|
29
35
|
|
30
|
-
singleton_class.
|
36
|
+
singleton_class.silence_redefinition_of_method :html_escape
|
31
37
|
module_function :html_escape
|
32
38
|
|
33
39
|
# HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
|
@@ -86,7 +92,7 @@ class ERB
|
|
86
92
|
# use inside HTML attributes.
|
87
93
|
#
|
88
94
|
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
89
|
-
# 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.
|
90
96
|
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
91
97
|
# content returned by your JSON.
|
92
98
|
#
|
@@ -99,7 +105,7 @@ class ERB
|
|
99
105
|
# WARNING: this helper only works with valid JSON. Using this on non-JSON values
|
100
106
|
# will open up serious XSS vulnerabilities. For example, if you replace the
|
101
107
|
# +current_user.to_json+ in the example above with user input instead, the browser
|
102
|
-
# will happily eval() that string as JavaScript.
|
108
|
+
# will happily <tt>eval()</tt> that string as JavaScript.
|
103
109
|
#
|
104
110
|
# The escaping performed in this method is identical to those performed in the
|
105
111
|
# Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
|
@@ -117,6 +123,26 @@ class ERB
|
|
117
123
|
end
|
118
124
|
|
119
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
|
120
146
|
end
|
121
147
|
end
|
122
148
|
|
@@ -132,17 +158,20 @@ class Numeric
|
|
132
158
|
end
|
133
159
|
end
|
134
160
|
|
135
|
-
module ActiveSupport
|
161
|
+
module ActiveSupport # :nodoc:
|
136
162
|
class SafeBuffer < String
|
137
163
|
UNSAFE_STRING_METHODS = %w(
|
138
|
-
capitalize chomp chop delete
|
139
|
-
|
164
|
+
capitalize chomp chop delete delete_prefix delete_suffix
|
165
|
+
downcase lstrip next reverse rstrip scrub slice squeeze strip
|
166
|
+
succ swapcase tr tr_s unicode_normalize upcase
|
140
167
|
)
|
141
168
|
|
169
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF = %w(gsub sub)
|
170
|
+
|
142
171
|
alias_method :original_concat, :concat
|
143
172
|
private :original_concat
|
144
173
|
|
145
|
-
# Raised when
|
174
|
+
# Raised when ActiveSupport::SafeBuffer#safe_concat is called on unsafe buffers.
|
146
175
|
class SafeConcatError < StandardError
|
147
176
|
def initialize
|
148
177
|
super "Could not concatenate to the buffer because it is not html safe."
|
@@ -150,15 +179,13 @@ module ActiveSupport #:nodoc:
|
|
150
179
|
end
|
151
180
|
|
152
181
|
def [](*args)
|
153
|
-
if
|
154
|
-
super
|
155
|
-
elsif html_safe?
|
156
|
-
new_safe_buffer = super
|
182
|
+
if html_safe?
|
183
|
+
new_string = super
|
157
184
|
|
158
|
-
|
159
|
-
new_safe_buffer.instance_variable_set :@html_safe, true
|
160
|
-
end
|
185
|
+
return unless new_string
|
161
186
|
|
187
|
+
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
188
|
+
new_safe_buffer.instance_variable_set :@html_safe, true
|
162
189
|
new_safe_buffer
|
163
190
|
else
|
164
191
|
to_str[*args]
|
@@ -185,24 +212,50 @@ 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
|
|
222
|
+
def insert(index, value)
|
223
|
+
super(index, implicit_html_escape_interpolated_argument(value))
|
224
|
+
end
|
225
|
+
|
192
226
|
def prepend(value)
|
193
|
-
super(
|
227
|
+
super(implicit_html_escape_interpolated_argument(value))
|
228
|
+
end
|
229
|
+
|
230
|
+
def replace(value)
|
231
|
+
super(implicit_html_escape_interpolated_argument(value))
|
232
|
+
end
|
233
|
+
|
234
|
+
def []=(*args)
|
235
|
+
if args.length == 3
|
236
|
+
super(args[0], args[1], implicit_html_escape_interpolated_argument(args[2]))
|
237
|
+
else
|
238
|
+
super(args[0], implicit_html_escape_interpolated_argument(args[1]))
|
239
|
+
end
|
194
240
|
end
|
195
241
|
|
196
242
|
def +(other)
|
197
243
|
dup.concat(other)
|
198
244
|
end
|
199
245
|
|
246
|
+
def *(*)
|
247
|
+
new_string = super
|
248
|
+
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
249
|
+
new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
|
250
|
+
new_safe_buffer
|
251
|
+
end
|
252
|
+
|
200
253
|
def %(args)
|
201
254
|
case args
|
202
255
|
when Hash
|
203
|
-
escaped_args =
|
256
|
+
escaped_args = args.transform_values { |arg| explicit_html_escape_interpolated_argument(arg) }
|
204
257
|
else
|
205
|
-
escaped_args = Array(args).map { |arg|
|
258
|
+
escaped_args = Array(args).map { |arg| explicit_html_escape_interpolated_argument(arg) }
|
206
259
|
end
|
207
260
|
|
208
261
|
self.class.new(super(escaped_args))
|
@@ -239,11 +292,66 @@ module ActiveSupport #:nodoc:
|
|
239
292
|
end
|
240
293
|
end
|
241
294
|
|
242
|
-
|
295
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
|
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
|
320
|
+
end
|
243
321
|
|
244
|
-
|
322
|
+
private
|
323
|
+
def explicit_html_escape_interpolated_argument(arg)
|
245
324
|
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
246
325
|
end
|
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
|
+
|
350
|
+
def set_block_back_references(block, match_data)
|
351
|
+
block.binding.eval("proc { |m| $~ = m }").call(match_data)
|
352
|
+
rescue ArgumentError
|
353
|
+
# Can't create binding from C level Proc
|
354
|
+
end
|
247
355
|
end
|
248
356
|
end
|
249
357
|
|
@@ -251,7 +359,7 @@ class String
|
|
251
359
|
# Marks a string as trusted safe. It will be inserted into HTML with no
|
252
360
|
# additional escaping performed. It is your responsibility to ensure that the
|
253
361
|
# string contains no malicious content. This method is equivalent to the
|
254
|
-
#
|
362
|
+
# +raw+ helper in views. It is recommended that you use +sanitize+ instead of
|
255
363
|
# this method. It should never be called on user input.
|
256
364
|
def html_safe
|
257
365
|
ActiveSupport::SafeBuffer.new(self)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class String
|
2
4
|
# Strips indentation in heredocs.
|
3
5
|
#
|
@@ -18,6 +20,8 @@ class String
|
|
18
20
|
# Technically, it looks for the least indented non-empty line
|
19
21
|
# in the whole string, and removes that amount of leading whitespace.
|
20
22
|
def strip_heredoc
|
21
|
-
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".
|
23
|
+
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "").tap do |stripped|
|
24
|
+
stripped.freeze if frozen?
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/duration"
|
2
4
|
require "active_support/core_ext/time/conversions"
|
3
5
|
require "active_support/time_with_zone"
|
4
6
|
require "active_support/core_ext/time/zones"
|
5
7
|
require "active_support/core_ext/date_and_time/calculations"
|
6
8
|
require "active_support/core_ext/date/calculations"
|
9
|
+
require "active_support/core_ext/module/remove_method"
|
7
10
|
|
8
11
|
class Time
|
9
12
|
include DateAndTime::Calculations
|
@@ -39,13 +42,15 @@ class Time
|
|
39
42
|
|
40
43
|
# Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
|
41
44
|
# instances can be used when called with a single argument
|
42
|
-
def at_with_coercion(*args)
|
43
|
-
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?
|
44
47
|
|
45
48
|
# Time.at can be called with a time or numerical value
|
46
49
|
time_or_number = args.first
|
47
50
|
|
48
|
-
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
51
|
+
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
52
|
+
at_without_coercion(time_or_number.to_r).getlocal
|
53
|
+
elsif time_or_number.is_a?(DateTime)
|
49
54
|
at_without_coercion(time_or_number.to_f).getlocal
|
50
55
|
else
|
51
56
|
at_without_coercion(time_or_number)
|
@@ -103,25 +108,41 @@ class Time
|
|
103
108
|
subsec
|
104
109
|
end
|
105
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
|
+
|
106
126
|
# Returns a new Time where one or more of the elements have been changed according
|
107
127
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
108
128
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
109
|
-
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
110
|
-
# and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
111
|
-
#
|
112
|
-
# <tt>:
|
113
|
-
# <tt>:
|
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
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
132
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
133
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
114
134
|
#
|
115
135
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
116
136
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
117
137
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
118
138
|
def change(options)
|
119
|
-
new_year
|
120
|
-
new_month
|
121
|
-
new_day
|
122
|
-
new_hour
|
123
|
-
new_min
|
124
|
-
new_sec
|
139
|
+
new_year = options.fetch(:year, year)
|
140
|
+
new_month = options.fetch(:month, month)
|
141
|
+
new_day = options.fetch(:day, day)
|
142
|
+
new_hour = options.fetch(:hour, hour)
|
143
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
144
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
145
|
+
new_offset = options.fetch(:offset, nil)
|
125
146
|
|
126
147
|
if new_nsec = options[:nsec]
|
127
148
|
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
@@ -130,13 +151,20 @@ class Time
|
|
130
151
|
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
131
152
|
end
|
132
153
|
|
133
|
-
if
|
134
|
-
|
154
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
155
|
+
|
156
|
+
new_sec += Rational(new_usec, 1000000)
|
157
|
+
|
158
|
+
if new_offset
|
159
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
160
|
+
elsif utc?
|
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)
|
135
164
|
elsif zone
|
136
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
165
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
137
166
|
else
|
138
|
-
|
139
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
|
167
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
140
168
|
end
|
141
169
|
end
|
142
170
|
|
@@ -162,8 +190,7 @@ class Time
|
|
162
190
|
options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
|
163
191
|
end
|
164
192
|
|
165
|
-
d = to_date.advance(options)
|
166
|
-
d = d.gregorian if d.julian?
|
193
|
+
d = to_date.gregorian.advance(options)
|
167
194
|
time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
168
195
|
seconds_to_advance = \
|
169
196
|
options.fetch(:seconds, 0) +
|
@@ -250,7 +277,7 @@ class Time
|
|
250
277
|
end
|
251
278
|
alias :at_end_of_minute :end_of_minute
|
252
279
|
|
253
|
-
def plus_with_duration(other)
|
280
|
+
def plus_with_duration(other) # :nodoc:
|
254
281
|
if ActiveSupport::Duration === other
|
255
282
|
other.since(self)
|
256
283
|
else
|
@@ -260,7 +287,7 @@ class Time
|
|
260
287
|
alias_method :plus_without_duration, :+
|
261
288
|
alias_method :+, :plus_with_duration
|
262
289
|
|
263
|
-
def minus_with_duration(other)
|
290
|
+
def minus_with_duration(other) # :nodoc:
|
264
291
|
if ActiveSupport::Duration === other
|
265
292
|
other.until(self)
|
266
293
|
else
|
@@ -278,7 +305,7 @@ class Time
|
|
278
305
|
other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
|
279
306
|
end
|
280
307
|
alias_method :minus_without_coercion, :-
|
281
|
-
alias_method :-, :minus_with_coercion
|
308
|
+
alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
|
282
309
|
|
283
310
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
284
311
|
# can be chronologically compared with a Time
|
@@ -304,4 +331,34 @@ class Time
|
|
304
331
|
end
|
305
332
|
alias_method :eql_without_coercion, :eql?
|
306
333
|
alias_method :eql?, :eql_with_coercion
|
334
|
+
|
335
|
+
# Returns a new time the specified number of days ago.
|
336
|
+
def prev_day(days = 1)
|
337
|
+
advance(days: -days)
|
338
|
+
end
|
339
|
+
|
340
|
+
# Returns a new time the specified number of days in the future.
|
341
|
+
def next_day(days = 1)
|
342
|
+
advance(days: days)
|
343
|
+
end
|
344
|
+
|
345
|
+
# Returns a new time the specified number of months ago.
|
346
|
+
def prev_month(months = 1)
|
347
|
+
advance(months: -months)
|
348
|
+
end
|
349
|
+
|
350
|
+
# Returns a new time the specified number of months in the future.
|
351
|
+
def next_month(months = 1)
|
352
|
+
advance(months: months)
|
353
|
+
end
|
354
|
+
|
355
|
+
# Returns a new time the specified number of years ago.
|
356
|
+
def prev_year(years = 1)
|
357
|
+
advance(years: -years)
|
358
|
+
end
|
359
|
+
|
360
|
+
# Returns a new time the specified number of years in the future.
|
361
|
+
def next_year(years = 1)
|
362
|
+
advance(years: years)
|
363
|
+
end
|
307
364
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/date_and_time/compatibility"
|
2
|
-
require "active_support/core_ext/module/
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
3
5
|
|
4
6
|
class Time
|
5
7
|
include DateAndTime::Compatibility
|
6
8
|
|
7
|
-
|
9
|
+
silence_redefinition_of_method :to_time
|
8
10
|
|
9
11
|
# Either return +self+ or the time in the local system timezone depending
|
10
12
|
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
1
4
|
require "active_support/inflector/methods"
|
2
5
|
require "active_support/values/time_zone"
|
3
6
|
|
4
7
|
class Time
|
5
8
|
DATE_FORMATS = {
|
6
9
|
db: "%Y-%m-%d %H:%M:%S",
|
10
|
+
inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
|
7
11
|
number: "%Y%m%d%H%M%S",
|
8
12
|
nsec: "%Y%m%d%H%M%S%9N",
|
9
13
|
usec: "%Y%m%d%H%M%S%6N",
|
@@ -23,22 +27,22 @@ class Time
|
|
23
27
|
|
24
28
|
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
25
29
|
#
|
26
|
-
# This method is aliased to <tt>
|
30
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
27
31
|
#
|
28
32
|
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
29
33
|
#
|
34
|
+
# time.to_fs(:time) # => "06:10"
|
30
35
|
# time.to_formatted_s(:time) # => "06:10"
|
31
|
-
# time.to_s(:time) # => "06:10"
|
32
36
|
#
|
33
|
-
# time.
|
34
|
-
# time.
|
35
|
-
# time.
|
36
|
-
# time.
|
37
|
-
# time.
|
38
|
-
# time.
|
39
|
-
# 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"
|
40
44
|
#
|
41
|
-
# == Adding your own time formats to +
|
45
|
+
# == Adding your own time formats to +to_fs+
|
42
46
|
# You can add your own formats to the Time::DATE_FORMATS hash.
|
43
47
|
# Use the format name as the hash key and either a strftime string
|
44
48
|
# or Proc instance that takes a time argument as the value.
|
@@ -46,15 +50,16 @@ class Time
|
|
46
50
|
# # config/initializers/time_formats.rb
|
47
51
|
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
|
48
52
|
# Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
|
49
|
-
def
|
53
|
+
def to_fs(format = :default)
|
50
54
|
if formatter = DATE_FORMATS[format]
|
51
55
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
52
56
|
else
|
57
|
+
# Change to `to_s` when deprecation is gone. Also deprecate `to_default_s`.
|
53
58
|
to_default_s
|
54
59
|
end
|
55
60
|
end
|
61
|
+
alias_method :to_formatted_s, :to_fs
|
56
62
|
alias_method :to_default_s, :to_s
|
57
|
-
alias_method :to_s, :to_formatted_s
|
58
63
|
|
59
64
|
# Returns a formatted string of the offset from UTC, or an alternative
|
60
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
|