activesupport 4.2.11.1 → 6.0.3.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 +399 -411
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +34 -6
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +58 -53
- data/lib/active_support/cache/mem_cache_store.rb +95 -91
- data/lib/active_support/cache/memory_store.rb +39 -36
- data/lib/active_support/cache/null_store.rb +11 -7
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +75 -42
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +331 -217
- data/lib/active_support/callbacks.rb +650 -592
- data/lib/active_support/concern.rb +35 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +13 -14
- data/lib/active_support/core_ext/array/access.rb +41 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -20
- 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 +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +45 -31
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +114 -22
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +4 -23
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +19 -42
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +5 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
- data/lib/active_support/core_ext/hash.rb +10 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +133 -30
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +44 -19
- data/lib/active_support/core_ext/module/reachable.rb +5 -7
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +5 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -3
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +13 -93
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +51 -20
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +81 -23
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_range.rb +7 -21
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +16 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +48 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +16 -7
- data/lib/active_support/core_ext/string/output_safety.rb +93 -40
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +115 -52
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -7
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +208 -166
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +61 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +57 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +53 -0
- data/lib/active_support/duration.rb +315 -40
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +234 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +129 -30
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +50 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +58 -13
- data/lib/active_support/inflector/methods.rb +159 -145
- data/lib/active_support/inflector/transliterate.rb +84 -34
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +32 -30
- data/lib/active_support/json/encoding.rb +17 -60
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +11 -43
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +44 -19
- data/lib/active_support/logger.rb +9 -23
- data/lib/active_support/logger_silence.rb +32 -14
- data/lib/active_support/logger_thread_safe_level.rb +32 -8
- data/lib/active_support/message_encryptor.rb +166 -53
- data/lib/active_support/message_verifier.rb +149 -16
- data/lib/active_support/messages/metadata.rb +72 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +56 -63
- data/lib/active_support/multibyte/unicode.rb +56 -290
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +109 -22
- data/lib/active_support/notifications/instrumenter.rb +107 -16
- data/lib/active_support/notifications.rb +51 -10
- data/lib/active_support/number_helper/number_converter.rb +16 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +105 -68
- data/lib/active_support/option_merger.rb +24 -4
- data/lib/active_support/ordered_hash.rb +7 -5
- data/lib/active_support/ordered_options.rb +27 -5
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +74 -30
- data/lib/active_support/tagged_logging.rb +25 -13
- data/lib/active_support/test_case.rb +107 -44
- data/lib/active_support/testing/assertions.rb +151 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +13 -10
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +35 -26
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +43 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +84 -20
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +179 -39
- data/lib/active_support/values/time_zone.rb +203 -63
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -115
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +38 -46
- data/lib/active_support.rb +13 -11
- metadata +84 -26
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,34 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "active_support/core_ext/kernel/singleton_class"
|
5
|
+
require "active_support/core_ext/module/redefine_method"
|
6
|
+
require "active_support/multibyte/unicode"
|
4
7
|
|
5
8
|
class ERB
|
6
9
|
module Util
|
7
|
-
HTML_ESCAPE = {
|
8
|
-
JSON_ESCAPE = {
|
9
|
-
HTML_ESCAPE_REGEXP = /[&"'><]/
|
10
|
+
HTML_ESCAPE = { "&" => "&", ">" => ">", "<" => "<", '"' => """, "'" => "'" }
|
11
|
+
JSON_ESCAPE = { "&" => '\u0026', ">" => '\u003e', "<" => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
|
10
12
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
11
13
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
12
14
|
|
13
15
|
# A utility method for escaping HTML tag characters.
|
14
16
|
# This method is also aliased as <tt>h</tt>.
|
15
17
|
#
|
16
|
-
# In your ERB templates, use this method to escape any unsafe content. For example:
|
17
|
-
# <%=h @person.name %>
|
18
|
-
#
|
19
18
|
# puts html_escape('is a > 0 & a < 10?')
|
20
19
|
# # => is a > 0 & a < 10?
|
21
20
|
def html_escape(s)
|
22
21
|
unwrapped_html_escape(s).html_safe
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
remove_method(:h)
|
24
|
+
silence_redefinition_of_method :h
|
27
25
|
alias h html_escape
|
28
26
|
|
29
27
|
module_function :h
|
30
28
|
|
31
|
-
singleton_class.
|
29
|
+
singleton_class.silence_redefinition_of_method :html_escape
|
32
30
|
module_function :html_escape
|
33
31
|
|
34
32
|
# HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
|
@@ -38,7 +36,7 @@ class ERB
|
|
38
36
|
if s.html_safe?
|
39
37
|
s
|
40
38
|
else
|
41
|
-
|
39
|
+
CGI.escapeHTML(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
|
42
40
|
end
|
43
41
|
end
|
44
42
|
module_function :unwrapped_html_escape
|
@@ -51,7 +49,7 @@ class ERB
|
|
51
49
|
# html_escape_once('<< Accept & Checkout')
|
52
50
|
# # => "<< Accept & Checkout"
|
53
51
|
def html_escape_once(s)
|
54
|
-
result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
|
52
|
+
result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
|
55
53
|
s.html_safe? ? result.html_safe : result
|
56
54
|
end
|
57
55
|
|
@@ -86,6 +84,11 @@ class ERB
|
|
86
84
|
# automatically flag the result as HTML safe, since the raw value is unsafe to
|
87
85
|
# use inside HTML attributes.
|
88
86
|
#
|
87
|
+
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
88
|
+
# whether or not it is being inserted via +html()+. Most jQuery plugins do this.
|
89
|
+
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
90
|
+
# content returned by your JSON.
|
91
|
+
#
|
89
92
|
# If you need to output JSON elsewhere in your HTML, you can just do something
|
90
93
|
# like this, as any unsafe characters (including quotation marks) will be
|
91
94
|
# automatically escaped for you:
|
@@ -131,34 +134,34 @@ end
|
|
131
134
|
module ActiveSupport #:nodoc:
|
132
135
|
class SafeBuffer < String
|
133
136
|
UNSAFE_STRING_METHODS = %w(
|
134
|
-
capitalize chomp chop delete
|
135
|
-
|
137
|
+
capitalize chomp chop delete delete_prefix delete_suffix
|
138
|
+
downcase lstrip next reverse rstrip slice squeeze strip
|
139
|
+
succ swapcase tr tr_s unicode_normalize upcase
|
136
140
|
)
|
137
141
|
|
142
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF = %w(gsub sub)
|
143
|
+
|
138
144
|
alias_method :original_concat, :concat
|
139
145
|
private :original_concat
|
140
146
|
|
147
|
+
# Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
|
141
148
|
class SafeConcatError < StandardError
|
142
149
|
def initialize
|
143
|
-
super
|
150
|
+
super "Could not concatenate to the buffer because it is not html safe."
|
144
151
|
end
|
145
152
|
end
|
146
153
|
|
147
154
|
def [](*args)
|
148
|
-
if
|
149
|
-
super
|
150
|
-
else
|
151
|
-
if html_safe?
|
152
|
-
new_safe_buffer = super
|
153
|
-
|
154
|
-
if new_safe_buffer
|
155
|
-
new_safe_buffer.instance_variable_set :@html_safe, true
|
156
|
-
end
|
155
|
+
if html_safe?
|
156
|
+
new_safe_buffer = super
|
157
157
|
|
158
|
-
|
159
|
-
|
160
|
-
to_str[*args]
|
158
|
+
if new_safe_buffer
|
159
|
+
new_safe_buffer.instance_variable_set :@html_safe, true
|
161
160
|
end
|
161
|
+
|
162
|
+
new_safe_buffer
|
163
|
+
else
|
164
|
+
to_str[*args]
|
162
165
|
end
|
163
166
|
end
|
164
167
|
|
@@ -167,7 +170,7 @@ module ActiveSupport #:nodoc:
|
|
167
170
|
original_concat(value)
|
168
171
|
end
|
169
172
|
|
170
|
-
def initialize(
|
173
|
+
def initialize(str = "")
|
171
174
|
@html_safe = true
|
172
175
|
super
|
173
176
|
end
|
@@ -186,23 +189,40 @@ module ActiveSupport #:nodoc:
|
|
186
189
|
end
|
187
190
|
alias << concat
|
188
191
|
|
192
|
+
def insert(index, value)
|
193
|
+
super(index, html_escape_interpolated_argument(value))
|
194
|
+
end
|
195
|
+
|
189
196
|
def prepend(value)
|
190
197
|
super(html_escape_interpolated_argument(value))
|
191
198
|
end
|
192
199
|
|
193
|
-
def
|
194
|
-
|
195
|
-
|
200
|
+
def replace(value)
|
201
|
+
super(html_escape_interpolated_argument(value))
|
202
|
+
end
|
203
|
+
|
204
|
+
def []=(*args)
|
205
|
+
if args.count == 3
|
206
|
+
super(args[0], args[1], html_escape_interpolated_argument(args[2]))
|
207
|
+
else
|
208
|
+
super(args[0], html_escape_interpolated_argument(args[1]))
|
209
|
+
end
|
196
210
|
end
|
197
211
|
|
198
212
|
def +(other)
|
199
213
|
dup.concat(other)
|
200
214
|
end
|
201
215
|
|
216
|
+
def *(*)
|
217
|
+
new_safe_buffer = super
|
218
|
+
new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
|
219
|
+
new_safe_buffer
|
220
|
+
end
|
221
|
+
|
202
222
|
def %(args)
|
203
223
|
case args
|
204
224
|
when Hash
|
205
|
-
escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }]
|
225
|
+
escaped_args = Hash[args.map { |k, arg| [k, html_escape_interpolated_argument(arg)] }]
|
206
226
|
else
|
207
227
|
escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
|
208
228
|
end
|
@@ -241,20 +261,53 @@ module ActiveSupport #:nodoc:
|
|
241
261
|
end
|
242
262
|
end
|
243
263
|
|
264
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
|
265
|
+
if unsafe_method.respond_to?(unsafe_method)
|
266
|
+
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
267
|
+
def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
|
268
|
+
if block # if block
|
269
|
+
to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params|
|
270
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
271
|
+
block.call(*params) # block.call(*params)
|
272
|
+
} # }
|
273
|
+
else # else
|
274
|
+
to_str.#{unsafe_method}(*args) # to_str.gsub(*args)
|
275
|
+
end # end
|
276
|
+
end # end
|
277
|
+
|
278
|
+
def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
|
279
|
+
@html_safe = false # @html_safe = false
|
280
|
+
if block # if block
|
281
|
+
super(*args) { |*params| # super(*args) { |*params|
|
282
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
283
|
+
block.call(*params) # block.call(*params)
|
284
|
+
} # }
|
285
|
+
else # else
|
286
|
+
super # super
|
287
|
+
end # end
|
288
|
+
end # end
|
289
|
+
EOT
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
244
293
|
private
|
294
|
+
def html_escape_interpolated_argument(arg)
|
295
|
+
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
296
|
+
end
|
245
297
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
298
|
+
def set_block_back_references(block, match_data)
|
299
|
+
block.binding.eval("proc { |m| $~ = m }").call(match_data)
|
300
|
+
rescue ArgumentError
|
301
|
+
# Can't create binding from C level Proc
|
302
|
+
end
|
250
303
|
end
|
251
304
|
end
|
252
305
|
|
253
306
|
class String
|
254
307
|
# Marks a string as trusted safe. It will be inserted into HTML with no
|
255
|
-
# additional escaping performed. It is your
|
308
|
+
# additional escaping performed. It is your responsibility to ensure that the
|
256
309
|
# string contains no malicious content. This method is equivalent to the
|
257
|
-
#
|
310
|
+
# +raw+ helper in views. It is recommended that you use +sanitize+ instead of
|
258
311
|
# this method. It should never be called on user input.
|
259
312
|
def html_safe
|
260
313
|
ActiveSupport::SafeBuffer.new(self)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class String
|
4
4
|
# Strips indentation in heredocs.
|
@@ -17,10 +17,11 @@ class String
|
|
17
17
|
#
|
18
18
|
# the user would see the usage message aligned against the left margin.
|
19
19
|
#
|
20
|
-
# Technically, it looks for the least indented line
|
21
|
-
# that amount of leading whitespace.
|
20
|
+
# Technically, it looks for the least indented non-empty line
|
21
|
+
# in the whole string, and removes that amount of leading whitespace.
|
22
22
|
def strip_heredoc
|
23
|
-
|
24
|
-
|
23
|
+
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "").tap do |stripped|
|
24
|
+
stripped.freeze if frozen?
|
25
|
+
end
|
25
26
|
end
|
26
27
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/conversions"
|
4
|
+
require "active_support/core_ext/time/zones"
|
3
5
|
|
4
6
|
class String
|
5
7
|
# Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/conversions"
|
4
|
+
require "active_support/core_ext/string/filters"
|
5
|
+
require "active_support/core_ext/string/multibyte"
|
6
|
+
require "active_support/core_ext/string/starts_ends_with"
|
7
|
+
require "active_support/core_ext/string/inflections"
|
8
|
+
require "active_support/core_ext/string/access"
|
9
|
+
require "active_support/core_ext/string/behavior"
|
10
|
+
require "active_support/core_ext/string/output_safety"
|
11
|
+
require "active_support/core_ext/string/exclude"
|
12
|
+
require "active_support/core_ext/string/strip"
|
13
|
+
require "active_support/core_ext/string/inquiry"
|
14
|
+
require "active_support/core_ext/string/indent"
|
15
|
+
require "active_support/core_ext/string/zones"
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/duration"
|
4
|
+
require "active_support/core_ext/time/conversions"
|
5
|
+
require "active_support/time_with_zone"
|
6
|
+
require "active_support/core_ext/time/zones"
|
7
|
+
require "active_support/core_ext/date_and_time/calculations"
|
8
|
+
require "active_support/core_ext/date/calculations"
|
7
9
|
|
8
10
|
class Time
|
9
11
|
include DateAndTime::Calculations
|
@@ -16,9 +18,9 @@ class Time
|
|
16
18
|
super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
|
17
19
|
end
|
18
20
|
|
19
|
-
#
|
21
|
+
# Returns the number of days in the given month.
|
20
22
|
# If no year is specified, it will use the current year.
|
21
|
-
def days_in_month(month, year =
|
23
|
+
def days_in_month(month, year = current.year)
|
22
24
|
if month == 2 && ::Date.gregorian_leap?(year)
|
23
25
|
29
|
24
26
|
else
|
@@ -26,6 +28,12 @@ class Time
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
31
|
+
# Returns the number of days in the given year.
|
32
|
+
# If no year is specified, it will use the current year.
|
33
|
+
def days_in_year(year = current.year)
|
34
|
+
days_in_month(2, year) + 337
|
35
|
+
end
|
36
|
+
|
29
37
|
# Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
|
30
38
|
def current
|
31
39
|
::Time.zone ? ::Time.zone.now : ::Time.now
|
@@ -47,11 +55,38 @@ class Time
|
|
47
55
|
end
|
48
56
|
alias_method :at_without_coercion, :at
|
49
57
|
alias_method :at, :at_with_coercion
|
58
|
+
|
59
|
+
# Creates a +Time+ instance from an RFC 3339 string.
|
60
|
+
#
|
61
|
+
# Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
|
62
|
+
#
|
63
|
+
# If the time or offset components are missing then an +ArgumentError+ will be raised.
|
64
|
+
#
|
65
|
+
# Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
|
66
|
+
def rfc3339(str)
|
67
|
+
parts = Date._rfc3339(str)
|
68
|
+
|
69
|
+
raise ArgumentError, "invalid date" if parts.empty?
|
70
|
+
|
71
|
+
Time.new(
|
72
|
+
parts.fetch(:year),
|
73
|
+
parts.fetch(:mon),
|
74
|
+
parts.fetch(:mday),
|
75
|
+
parts.fetch(:hour),
|
76
|
+
parts.fetch(:min),
|
77
|
+
parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
|
78
|
+
parts.fetch(:offset)
|
79
|
+
)
|
80
|
+
end
|
50
81
|
end
|
51
82
|
|
52
|
-
#
|
83
|
+
# Returns the number of seconds since 00:00:00.
|
84
|
+
#
|
85
|
+
# Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
|
86
|
+
# Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
|
87
|
+
# Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
|
53
88
|
def seconds_since_midnight
|
54
|
-
to_i - change(:
|
89
|
+
to_i - change(hour: 0).to_i + (usec / 1.0e+6)
|
55
90
|
end
|
56
91
|
|
57
92
|
# Returns the number of seconds until 23:59:59.
|
@@ -74,36 +109,42 @@ class Time
|
|
74
109
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
75
110
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
76
111
|
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
77
|
-
# and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
78
|
-
#
|
79
|
-
# <tt>:
|
80
|
-
# <tt>:
|
112
|
+
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
113
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
114
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
115
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
81
116
|
#
|
82
117
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
83
118
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
84
119
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
85
120
|
def change(options)
|
86
|
-
new_year
|
87
|
-
new_month
|
88
|
-
new_day
|
89
|
-
new_hour
|
90
|
-
new_min
|
91
|
-
new_sec
|
121
|
+
new_year = options.fetch(:year, year)
|
122
|
+
new_month = options.fetch(:month, month)
|
123
|
+
new_day = options.fetch(:day, day)
|
124
|
+
new_hour = options.fetch(:hour, hour)
|
125
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
126
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
127
|
+
new_offset = options.fetch(:offset, nil)
|
92
128
|
|
93
129
|
if new_nsec = options[:nsec]
|
94
130
|
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
95
131
|
new_usec = Rational(new_nsec, 1000)
|
96
132
|
else
|
97
|
-
new_usec
|
133
|
+
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
98
134
|
end
|
99
135
|
|
100
|
-
if
|
101
|
-
|
136
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
137
|
+
|
138
|
+
new_sec += Rational(new_usec, 1000000)
|
139
|
+
|
140
|
+
if new_offset
|
141
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
142
|
+
elsif utc?
|
143
|
+
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
102
144
|
elsif zone
|
103
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
145
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
104
146
|
else
|
105
|
-
|
106
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
|
147
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
107
148
|
end
|
108
149
|
end
|
109
150
|
|
@@ -129,9 +170,8 @@ class Time
|
|
129
170
|
options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
|
130
171
|
end
|
131
172
|
|
132
|
-
d = to_date.advance(options)
|
133
|
-
|
134
|
-
time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
|
173
|
+
d = to_date.gregorian.advance(options)
|
174
|
+
time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
135
175
|
seconds_to_advance = \
|
136
176
|
options.fetch(:seconds, 0) +
|
137
177
|
options.fetch(:minutes, 0) * 60 +
|
@@ -159,8 +199,7 @@ class Time
|
|
159
199
|
|
160
200
|
# Returns a new Time representing the start of the day (0:00)
|
161
201
|
def beginning_of_day
|
162
|
-
|
163
|
-
change(:hour => 0)
|
202
|
+
change(hour: 0)
|
164
203
|
end
|
165
204
|
alias :midnight :beginning_of_day
|
166
205
|
alias :at_midnight :beginning_of_day
|
@@ -168,7 +207,7 @@ class Time
|
|
168
207
|
|
169
208
|
# Returns a new Time representing the middle of the day (12:00)
|
170
209
|
def middle_of_day
|
171
|
-
change(:
|
210
|
+
change(hour: 12)
|
172
211
|
end
|
173
212
|
alias :midday :middle_of_day
|
174
213
|
alias :noon :middle_of_day
|
@@ -176,53 +215,48 @@ class Time
|
|
176
215
|
alias :at_noon :middle_of_day
|
177
216
|
alias :at_middle_of_day :middle_of_day
|
178
217
|
|
179
|
-
# Returns a new Time representing the end of the day, 23:59:59.999999
|
218
|
+
# Returns a new Time representing the end of the day, 23:59:59.999999
|
180
219
|
def end_of_day
|
181
220
|
change(
|
182
|
-
:
|
183
|
-
:
|
184
|
-
:
|
185
|
-
:
|
221
|
+
hour: 23,
|
222
|
+
min: 59,
|
223
|
+
sec: 59,
|
224
|
+
usec: Rational(999999999, 1000)
|
186
225
|
)
|
187
226
|
end
|
188
227
|
alias :at_end_of_day :end_of_day
|
189
228
|
|
190
229
|
# Returns a new Time representing the start of the hour (x:00)
|
191
230
|
def beginning_of_hour
|
192
|
-
change(:
|
231
|
+
change(min: 0)
|
193
232
|
end
|
194
233
|
alias :at_beginning_of_hour :beginning_of_hour
|
195
234
|
|
196
|
-
# Returns a new Time representing the end of the hour, x:59:59.999999
|
235
|
+
# Returns a new Time representing the end of the hour, x:59:59.999999
|
197
236
|
def end_of_hour
|
198
237
|
change(
|
199
|
-
:
|
200
|
-
:
|
201
|
-
:
|
238
|
+
min: 59,
|
239
|
+
sec: 59,
|
240
|
+
usec: Rational(999999999, 1000)
|
202
241
|
)
|
203
242
|
end
|
204
243
|
alias :at_end_of_hour :end_of_hour
|
205
244
|
|
206
245
|
# Returns a new Time representing the start of the minute (x:xx:00)
|
207
246
|
def beginning_of_minute
|
208
|
-
change(:
|
247
|
+
change(sec: 0)
|
209
248
|
end
|
210
249
|
alias :at_beginning_of_minute :beginning_of_minute
|
211
250
|
|
212
|
-
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
251
|
+
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
213
252
|
def end_of_minute
|
214
253
|
change(
|
215
|
-
:
|
216
|
-
:
|
254
|
+
sec: 59,
|
255
|
+
usec: Rational(999999999, 1000)
|
217
256
|
)
|
218
257
|
end
|
219
258
|
alias :at_end_of_minute :end_of_minute
|
220
259
|
|
221
|
-
# Returns a Range representing the whole day of the current time.
|
222
|
-
def all_day
|
223
|
-
beginning_of_day..end_of_day
|
224
|
-
end
|
225
|
-
|
226
260
|
def plus_with_duration(other) #:nodoc:
|
227
261
|
if ActiveSupport::Duration === other
|
228
262
|
other.since(self)
|
@@ -256,7 +290,7 @@ class Time
|
|
256
290
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
257
291
|
# can be chronologically compared with a Time
|
258
292
|
def compare_with_coercion(other)
|
259
|
-
# we're avoiding Time#to_datetime
|
293
|
+
# we're avoiding Time#to_datetime and Time#to_time because they're expensive
|
260
294
|
if other.class == Time
|
261
295
|
compare_without_coercion(other)
|
262
296
|
elsif other.is_a?(Time)
|
@@ -278,4 +312,33 @@ class Time
|
|
278
312
|
alias_method :eql_without_coercion, :eql?
|
279
313
|
alias_method :eql?, :eql_with_coercion
|
280
314
|
|
315
|
+
# Returns a new time the specified number of days ago.
|
316
|
+
def prev_day(days = 1)
|
317
|
+
advance(days: -days)
|
318
|
+
end
|
319
|
+
|
320
|
+
# Returns a new time the specified number of days in the future.
|
321
|
+
def next_day(days = 1)
|
322
|
+
advance(days: days)
|
323
|
+
end
|
324
|
+
|
325
|
+
# Returns a new time the specified number of months ago.
|
326
|
+
def prev_month(months = 1)
|
327
|
+
advance(months: -months)
|
328
|
+
end
|
329
|
+
|
330
|
+
# Returns a new time the specified number of months in the future.
|
331
|
+
def next_month(months = 1)
|
332
|
+
advance(months: months)
|
333
|
+
end
|
334
|
+
|
335
|
+
# Returns a new time the specified number of years ago.
|
336
|
+
def prev_year(years = 1)
|
337
|
+
advance(years: -years)
|
338
|
+
end
|
339
|
+
|
340
|
+
# Returns a new time the specified number of years in the future.
|
341
|
+
def next_year(years = 1)
|
342
|
+
advance(years: years)
|
343
|
+
end
|
281
344
|
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+.
|