activesupport 7.0.0.rc3 → 7.0.2.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.

Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/MIT-LICENSE +1 -1
  4. data/lib/active_support/core_ext/array/conversions.rb +6 -6
  5. data/lib/active_support/core_ext/array/deprecated_conversions.rb +2 -2
  6. data/lib/active_support/core_ext/class/subclasses.rb +23 -17
  7. data/lib/active_support/core_ext/date/conversions.rb +11 -11
  8. data/lib/active_support/core_ext/date/deprecated_conversions.rb +2 -2
  9. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  10. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +2 -2
  11. data/lib/active_support/core_ext/enumerable.rb +24 -24
  12. data/lib/active_support/core_ext/file/atomic.rb +2 -0
  13. data/lib/active_support/core_ext/numeric/conversions.rb +71 -71
  14. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +8 -8
  15. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  16. data/lib/active_support/core_ext/pathname/existence.rb +1 -1
  17. data/lib/active_support/core_ext/range/conversions.rb +6 -6
  18. data/lib/active_support/core_ext/range/deprecated_conversions.rb +2 -2
  19. data/lib/active_support/core_ext/time/conversions.rb +12 -12
  20. data/lib/active_support/core_ext/time/deprecated_conversions.rb +2 -2
  21. data/lib/active_support/descendants_tracker.rb +2 -5
  22. data/lib/active_support/duration.rb +4 -3
  23. data/lib/active_support/encrypted_configuration.rb +2 -1
  24. data/lib/active_support/execution_wrapper.rb +19 -23
  25. data/lib/active_support/gem_version.rb +2 -2
  26. data/lib/active_support/isolated_execution_state.rb +8 -0
  27. data/lib/active_support/message_verifier.rb +42 -10
  28. data/lib/active_support/time_with_zone.rb +11 -11
  29. data/lib/active_support/xml_mini.rb +1 -1
  30. data/lib/active_support.rb +1 -1
  31. metadata +8 -8
@@ -10,42 +10,42 @@ module ActiveSupport
10
10
  super(format)
11
11
  when :phone
12
12
  ActiveSupport::Deprecation.warn(
13
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
13
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
14
14
  )
15
15
  ActiveSupport::NumberHelper.number_to_phone(self, options || {})
16
16
  when :currency
17
17
  ActiveSupport::Deprecation.warn(
18
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
18
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
19
19
  )
20
20
  ActiveSupport::NumberHelper.number_to_currency(self, options || {})
21
21
  when :percentage
22
22
  ActiveSupport::Deprecation.warn(
23
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
23
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
24
24
  )
25
25
  ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
26
26
  when :delimited
27
27
  ActiveSupport::Deprecation.warn(
28
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
28
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
29
29
  )
30
30
  ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
31
31
  when :rounded
32
32
  ActiveSupport::Deprecation.warn(
33
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
33
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
34
34
  )
35
35
  ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
36
36
  when :human
37
37
  ActiveSupport::Deprecation.warn(
38
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
38
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
39
39
  )
40
40
  ActiveSupport::NumberHelper.number_to_human(self, options || {})
41
41
  when :human_size
42
42
  ActiveSupport::Deprecation.warn(
43
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
43
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
44
44
  )
45
45
  ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
46
46
  when Symbol
47
47
  ActiveSupport::Deprecation.warn(
48
- "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
48
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
49
49
  )
50
50
  super()
51
51
  else
@@ -1,11 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Object
4
- # A duck-type assistant method. For example, Active Support extends Date
5
- # to define an <tt>acts_like_date?</tt> method, and extends Time to define
6
- # <tt>acts_like_time?</tt>. As a result, we can do <tt>x.acts_like?(:time)</tt> and
7
- # <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
8
- # we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
4
+ # Provides a way to check whether some class acts like some other class based on the existence of
5
+ # an appropriately-named marker method.
6
+ #
7
+ # A class that provides the same interface as <tt>SomeClass</tt> may define a marker method named
8
+ # <tt>acts_like_some_class?</tt> to signal its compatibility to callers of
9
+ # <tt>acts_like?(:some_class)</tt>.
10
+ #
11
+ # For example, Active Support extends <tt>Date</tt> to define an <tt>acts_like_date?</tt> method,
12
+ # and extends <tt>Time</tt> to define <tt>acts_like_time?</tt>. As a result, developers can call
13
+ # <tt>x.acts_like?(:time)</tt> and <tt>x.acts_like?(:date)</tt> to test duck-type compatibility,
14
+ # and classes that are able to act like <tt>Time</tt> can also define an <tt>acts_like_time?</tt>
15
+ # method to interoperate.
16
+ #
17
+ # Note that the marker method is only expected to exist. It isn't called, so its body or return
18
+ # value are irrelevant.
19
+ #
20
+ # ==== Example: A class that provides the same interface as <tt>String</tt>
21
+ #
22
+ # This class may define:
23
+ #
24
+ # class Stringish
25
+ # def acts_like_string?
26
+ # end
27
+ # end
28
+ #
29
+ # Then client code can query for duck-type-safeness this way:
30
+ #
31
+ # Stringish.new.acts_like?(:string) # => true
32
+ #
9
33
  def acts_like?(duck)
10
34
  case duck
11
35
  when :time
@@ -4,7 +4,7 @@ class Pathname
4
4
  # Returns the receiver if the named file exists otherwise returns +nil+.
5
5
  # <tt>pathname.existence</tt> is equivalent to
6
6
  #
7
- # pathname.exists? ? pathname : nil
7
+ # pathname.exist? ? pathname : nil
8
8
  #
9
9
  # For example, something like
10
10
  #
@@ -7,34 +7,34 @@ module ActiveSupport
7
7
  case start
8
8
  when String then "BETWEEN '#{start}' AND '#{stop}'"
9
9
  else
10
- "BETWEEN '#{start.to_formatted_s(:db)}' AND '#{stop.to_formatted_s(:db)}'"
10
+ "BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'"
11
11
  end
12
12
  end
13
13
  }
14
14
 
15
15
  # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
16
16
  #
17
- # This method is aliased to <tt>to_fs</tt>.
17
+ # This method is aliased to <tt>to_formatted_s</tt>.
18
18
  #
19
19
  # range = (1..100) # => 1..100
20
20
  #
21
21
  # range.to_s # => "1..100"
22
- # range.to_formatted_s(:db) # => "BETWEEN '1' AND '100'"
22
+ # range.to_fs(:db) # => "BETWEEN '1' AND '100'"
23
23
  #
24
24
  # == Adding your own range formats to to_s
25
25
  # You can add your own formats to the Range::RANGE_FORMATS hash.
26
26
  # Use the format name as the hash key and a Proc instance.
27
27
  #
28
28
  # # config/initializers/range_formats.rb
29
- # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_formatted_s(:db)} and #{stop.to_formatted_s(:db)}" }
30
- def to_formatted_s(format = :default)
29
+ # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_fs(:db)} and #{stop.to_fs(:db)}" }
30
+ def to_fs(format = :default)
31
31
  if formatter = RANGE_FORMATS[format]
32
32
  formatter.call(first, last)
33
33
  else
34
34
  to_s
35
35
  end
36
36
  end
37
- alias_method :to_fs, :to_formatted_s
37
+ alias_method :to_formatted_s, :to_fs
38
38
  end
39
39
  end
40
40
 
@@ -6,14 +6,14 @@ module ActiveSupport
6
6
  def to_s(format = NOT_SET)
7
7
  if formatter = RangeWithFormat::RANGE_FORMATS[format]
8
8
  ActiveSupport::Deprecation.warn(
9
- "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_formatted_s(#{format.inspect}) instead."
9
+ "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_fs(#{format.inspect}) instead."
10
10
  )
11
11
  formatter.call(first, last)
12
12
  elsif format == NOT_SET
13
13
  super()
14
14
  else
15
15
  ActiveSupport::Deprecation.warn(
16
- "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_formatted_s(#{format.inspect}) instead."
16
+ "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_fs(#{format.inspect}) instead."
17
17
  )
18
18
  super()
19
19
  end
@@ -27,22 +27,22 @@ class Time
27
27
 
28
28
  # Converts to a formatted string. See DATE_FORMATS for built-in formats.
29
29
  #
30
- # This method is aliased to <tt>to_fs</tt>.
30
+ # This method is aliased to <tt>to_formatted_s</tt>.
31
31
  #
32
32
  # time = Time.now # => 2007-01-18 06:10:17 -06:00
33
33
  #
34
- # time.to_formatted_s(:time) # => "06:10"
34
+ # time.to_fs(:time) # => "06:10"
35
35
  # time.to_formatted_s(:time) # => "06:10"
36
36
  #
37
- # time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
38
- # time.to_formatted_s(:number) # => "20070118061017"
39
- # time.to_formatted_s(:short) # => "18 Jan 06:10"
40
- # time.to_formatted_s(:long) # => "January 18, 2007 06:10"
41
- # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
42
- # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
43
- # time.to_formatted_s(:iso8601) # => "2007-01-18T06:10:17-06:00"
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"
44
44
  #
45
- # == Adding your own time formats to +to_formatted_s+
45
+ # == Adding your own time formats to +to_fs+
46
46
  # You can add your own formats to the Time::DATE_FORMATS hash.
47
47
  # Use the format name as the hash key and either a strftime string
48
48
  # or Proc instance that takes a time argument as the value.
@@ -50,7 +50,7 @@ class Time
50
50
  # # config/initializers/time_formats.rb
51
51
  # Time::DATE_FORMATS[:month_and_year] = '%B %Y'
52
52
  # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
53
- def to_formatted_s(format = :default)
53
+ def to_fs(format = :default)
54
54
  if formatter = DATE_FORMATS[format]
55
55
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
56
56
  else
@@ -58,7 +58,7 @@ class Time
58
58
  to_default_s
59
59
  end
60
60
  end
61
- alias_method :to_fs, :to_formatted_s
61
+ alias_method :to_formatted_s, :to_fs
62
62
  alias_method :to_default_s, :to_s
63
63
 
64
64
  # Returns a formatted string of the offset from UTC, or an alternative
@@ -7,14 +7,14 @@ class Time
7
7
  def to_s(format = NOT_SET) # :nodoc:
8
8
  if formatter = DATE_FORMATS[format]
9
9
  ActiveSupport::Deprecation.warn(
10
- "Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_formatted_s(#{format.inspect}) instead."
10
+ "Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
11
11
  )
12
12
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
13
13
  elsif format == NOT_SET
14
14
  to_default_s
15
15
  else
16
16
  ActiveSupport::Deprecation.warn(
17
- "Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_formatted_s(#{format.inspect}) instead."
17
+ "Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
18
18
  )
19
19
  to_default_s
20
20
  end
@@ -40,7 +40,7 @@ module ActiveSupport
40
40
  end
41
41
 
42
42
  def []=(object, _present)
43
- @map[object_id] = object
43
+ @map[object.object_id] = object
44
44
  end
45
45
  end
46
46
  WeakSet.new
@@ -51,7 +51,6 @@ module ActiveSupport
51
51
  unless @clear_disabled
52
52
  @clear_disabled = true
53
53
  remove_method(:subclasses)
54
- remove_method(:descendants)
55
54
  @@excluded_descendants = nil
56
55
  end
57
56
  end
@@ -87,9 +86,7 @@ module ActiveSupport
87
86
  end
88
87
 
89
88
  def descendants
90
- descendants = super
91
- descendants.reject! { |d| @@excluded_descendants[d] }
92
- descendants
89
+ subclasses.concat(subclasses.flat_map(&:descendants))
93
90
  end
94
91
 
95
92
  def direct_descendants
@@ -191,13 +191,14 @@ module ActiveSupport
191
191
  end
192
192
 
193
193
  parts = {}
194
- remainder = value.round(9)
194
+ remainder_sign = value <=> 0
195
+ remainder = value.round(9).abs
195
196
  variable = false
196
197
 
197
198
  PARTS.each do |part|
198
199
  unless part == :seconds
199
200
  part_in_seconds = PARTS_IN_SECONDS[part]
200
- parts[part] = remainder.div(part_in_seconds)
201
+ parts[part] = remainder.div(part_in_seconds) * remainder_sign
201
202
  remainder %= part_in_seconds
202
203
 
203
204
  unless parts[part].zero?
@@ -206,7 +207,7 @@ module ActiveSupport
206
207
  end
207
208
  end unless value == 0
208
209
 
209
- parts[:seconds] = remainder
210
+ parts[:seconds] = remainder * remainder_sign
210
211
 
211
212
  new(value, parts, variable)
212
213
  end
@@ -49,7 +49,8 @@ module ActiveSupport
49
49
  end
50
50
 
51
51
  def deserialize(config)
52
- YAML.load(config).presence || {}
52
+ doc = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(config) : YAML.load(config)
53
+ doc.presence || {}
53
54
  end
54
55
  end
55
56
  end
@@ -64,18 +64,21 @@ module ActiveSupport
64
64
  # after the work has been performed.
65
65
  #
66
66
  # Where possible, prefer +wrap+.
67
- def self.run!
68
- if active?
69
- Null
67
+ def self.run!(reset: false)
68
+ if reset
69
+ lost_instance = IsolatedExecutionState.delete(active_key)
70
+ lost_instance&.complete!
70
71
  else
71
- new.tap do |instance|
72
- success = nil
73
- begin
74
- instance.run!
75
- success = true
76
- ensure
77
- instance.complete! unless success
78
- end
72
+ return Null if active?
73
+ end
74
+
75
+ new.tap do |instance|
76
+ success = nil
77
+ begin
78
+ instance.run!
79
+ success = true
80
+ ensure
81
+ instance.complete! unless success
79
82
  end
80
83
  end
81
84
  end
@@ -105,27 +108,20 @@ module ActiveSupport
105
108
  end
106
109
  end
107
110
 
108
- class << self # :nodoc:
109
- attr_accessor :active
110
- end
111
-
112
111
  def self.error_reporter
113
112
  @error_reporter ||= ActiveSupport::ErrorReporter.new
114
113
  end
115
114
 
116
- def self.inherited(other) # :nodoc:
117
- super
118
- other.active = Concurrent::Hash.new
115
+ def self.active_key # :nodoc:
116
+ @active_key ||= :"active_execution_wrapper_#{object_id}"
119
117
  end
120
118
 
121
- self.active = Concurrent::Hash.new
122
-
123
119
  def self.active? # :nodoc:
124
- @active[IsolatedExecutionState.unique_id]
120
+ IsolatedExecutionState.key?(active_key)
125
121
  end
126
122
 
127
123
  def run! # :nodoc:
128
- self.class.active[IsolatedExecutionState.unique_id] = true
124
+ IsolatedExecutionState[self.class.active_key] = self
129
125
  run
130
126
  end
131
127
 
@@ -140,7 +136,7 @@ module ActiveSupport
140
136
  def complete!
141
137
  complete
142
138
  ensure
143
- self.class.active.delete(IsolatedExecutionState.unique_id)
139
+ IsolatedExecutionState.delete(self.class.active_key)
144
140
  end
145
141
 
146
142
  def complete # :nodoc:
@@ -9,8 +9,8 @@ module ActiveSupport
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 0
12
- TINY = 0
13
- PRE = "rc3"
12
+ TINY = 2
13
+ PRE = "1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -37,6 +37,14 @@ module ActiveSupport
37
37
  current[key] = value
38
38
  end
39
39
 
40
+ def key?(key)
41
+ state.key?(key)
42
+ end
43
+
44
+ def delete(key)
45
+ state.delete(key)
46
+ end
47
+
40
48
  def clear
41
49
  current.clear
42
50
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "openssl"
3
4
  require "base64"
4
5
  require "active_support/core_ext/object/blank"
5
6
  require "active_support/security_utils"
@@ -103,10 +104,13 @@ module ActiveSupport
103
104
 
104
105
  class InvalidSignature < StandardError; end
105
106
 
107
+ SEPARATOR = "--" # :nodoc:
108
+ SEPARATOR_LENGTH = SEPARATOR.length # :nodoc:
109
+
106
110
  def initialize(secret, digest: nil, serializer: nil)
107
111
  raise ArgumentError, "Secret should not be nil." unless secret
108
112
  @secret = secret
109
- @digest = digest || "SHA1"
113
+ @digest = digest&.to_s || "SHA1"
110
114
  @serializer = serializer || Marshal
111
115
  end
112
116
 
@@ -120,10 +124,8 @@ module ActiveSupport
120
124
  # tampered_message = signed_message.chop # editing the message invalidates the signature
121
125
  # verifier.valid_message?(tampered_message) # => false
122
126
  def valid_message?(signed_message)
123
- return if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank?
124
-
125
- data, digest = signed_message.split("--")
126
- data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data))
127
+ data, digest = get_data_and_digest_from(signed_message)
128
+ digest_matches_data?(digest, data)
127
129
  end
128
130
 
129
131
  # Decodes the signed message using the +MessageVerifier+'s secret.
@@ -148,9 +150,9 @@ module ActiveSupport
148
150
  # incompatible_message = "test--dad7b06c94abba8d46a15fafaef56c327665d5ff"
149
151
  # verifier.verified(incompatible_message) # => TypeError: incompatible marshal file format
150
152
  def verified(signed_message, purpose: nil, **)
151
- if valid_message?(signed_message)
153
+ data, digest = get_data_and_digest_from(signed_message)
154
+ if digest_matches_data?(digest, data)
152
155
  begin
153
- data = signed_message.split("--")[0]
154
156
  message = Messages::Metadata.verify(decode(data), purpose)
155
157
  @serializer.load(message) if message
156
158
  rescue ArgumentError => argument_error
@@ -185,7 +187,7 @@ module ActiveSupport
185
187
  # verifier.generate 'a private message' # => "BAhJIhRwcml2YXRlLW1lc3NhZ2UGOgZFVA==--e2d724331ebdee96a10fb99b089508d1c72bd772"
186
188
  def generate(value, expires_at: nil, expires_in: nil, purpose: nil)
187
189
  data = encode(Messages::Metadata.wrap(@serializer.dump(value), expires_at: expires_at, expires_in: expires_in, purpose: purpose))
188
- "#{data}--#{generate_digest(data)}"
190
+ "#{data}#{SEPARATOR}#{generate_digest(data)}"
189
191
  end
190
192
 
191
193
  private
@@ -198,8 +200,38 @@ module ActiveSupport
198
200
  end
199
201
 
200
202
  def generate_digest(data)
201
- require "openssl" unless defined?(OpenSSL)
202
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
203
+ OpenSSL::HMAC.hexdigest(@digest, @secret, data)
204
+ end
205
+
206
+ def digest_length_in_hex
207
+ # In hexadecimal (AKA base16) it takes 4 bits to represent a character,
208
+ # hence we multiply the digest's length (in bytes) by 8 to get it in
209
+ # bits and divide by 4 to get its number of characters it hex. Well, 8
210
+ # divided by 4 is 2.
211
+ @digest_length_in_hex ||= OpenSSL::Digest.new(@digest).digest_length * 2
212
+ end
213
+
214
+ def separator_index_for(signed_message)
215
+ index = signed_message.length - digest_length_in_hex - SEPARATOR_LENGTH
216
+ return if index.negative? || signed_message[index, SEPARATOR_LENGTH] != SEPARATOR
217
+
218
+ index
219
+ end
220
+
221
+ def get_data_and_digest_from(signed_message)
222
+ return if signed_message.nil? || !signed_message.valid_encoding? || signed_message.empty?
223
+
224
+ separator_index = separator_index_for(signed_message)
225
+ return if separator_index.nil?
226
+
227
+ data = signed_message[0...separator_index]
228
+ digest = signed_message[separator_index + SEPARATOR_LENGTH..-1]
229
+
230
+ [data, digest]
231
+ end
232
+
233
+ def digest_matches_data?(digest, data)
234
+ data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data))
203
235
  end
204
236
  end
205
237
  end
@@ -33,7 +33,7 @@ module ActiveSupport
33
33
  # t.dst? # => true
34
34
  # t.utc_offset # => -14400
35
35
  # t.zone # => "EDT"
36
- # t.to_formatted_s(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
36
+ # t.to_fs(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
37
37
  # t + 1.day # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00
38
38
  # t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00.000000000 EST -05:00
39
39
  # t > Time.utc(1999) # => true
@@ -202,7 +202,7 @@ module ActiveSupport
202
202
  #
203
203
  # Time.zone.now.rfc2822 # => "Tue, 01 Jan 2013 04:51:39 +0000"
204
204
  def rfc2822
205
- to_formatted_s(:rfc822)
205
+ to_fs(:rfc822)
206
206
  end
207
207
  alias_method :rfc822, :rfc2822
208
208
 
@@ -212,19 +212,19 @@ module ActiveSupport
212
212
  def to_s(format = NOT_SET)
213
213
  if format == :db
214
214
  ActiveSupport::Deprecation.warn(
215
- "TimeWithZone#to_s(:db) is deprecated. Please use TimeWithZone#to_formatted_s(:db) instead."
215
+ "TimeWithZone#to_s(:db) is deprecated. Please use TimeWithZone#to_fs(:db) instead."
216
216
  )
217
- utc.to_formatted_s(format)
217
+ utc.to_fs(format)
218
218
  elsif formatter = ::Time::DATE_FORMATS[format]
219
219
  ActiveSupport::Deprecation.warn(
220
- "TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_formatted_s(#{format.inspect}) instead."
220
+ "TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_fs(#{format.inspect}) instead."
221
221
  )
222
222
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
223
223
  elsif format == NOT_SET
224
224
  "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
225
225
  else
226
226
  ActiveSupport::Deprecation.warn(
227
- "TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_formatted_s(#{format.inspect}) instead."
227
+ "TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_fs(#{format.inspect}) instead."
228
228
  )
229
229
  "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
230
230
  end
@@ -232,15 +232,15 @@ module ActiveSupport
232
232
 
233
233
  # Returns a string of the object's date and time.
234
234
  #
235
- # This method is aliased to <tt>to_fs</tt>.
235
+ # This method is aliased to <tt>to_formatted_s</tt>.
236
236
  #
237
237
  # Accepts an optional <tt>format</tt>:
238
238
  # * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
239
- # * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_formatted_s(:db).
239
+ # * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_fs(:db).
240
240
  # * Any key in <tt>Time::DATE_FORMATS</tt> can be used. See active_support/core_ext/time/conversions.rb.
241
- def to_formatted_s(format = :default)
241
+ def to_fs(format = :default)
242
242
  if format == :db
243
- utc.to_formatted_s(format)
243
+ utc.to_fs(format)
244
244
  elsif formatter = ::Time::DATE_FORMATS[format]
245
245
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
246
246
  else
@@ -248,7 +248,7 @@ module ActiveSupport
248
248
  "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}"
249
249
  end
250
250
  end
251
- alias_method :to_fs, :to_formatted_s
251
+ alias_method :to_formatted_s, :to_fs
252
252
 
253
253
  # Replaces <tt>%Z</tt> directive with +zone before passing to Time#strftime,
254
254
  # so that zone information is correct.
@@ -54,7 +54,7 @@ module ActiveSupport
54
54
 
55
55
  FORMATTING = {
56
56
  "symbol" => Proc.new { |symbol| symbol.to_s },
57
- "date" => Proc.new { |date| date.to_formatted_s(:db) },
57
+ "date" => Proc.new { |date| date.to_fs(:db) },
58
58
  "dateTime" => Proc.new { |time| time.xmlschema },
59
59
  "binary" => Proc.new { |binary| ::Base64.encode64(binary) },
60
60
  "yaml" => Proc.new { |yaml| yaml.to_yaml }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2005-2021 David Heinemeier Hansson
4
+ # Copyright (c) 2005-2022 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesupport
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.0.rc3
4
+ version: 7.0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-14 00:00:00.000000000 Z
11
+ date: 2022-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -359,10 +359,10 @@ licenses:
359
359
  - MIT
360
360
  metadata:
361
361
  bug_tracker_uri: https://github.com/rails/rails/issues
362
- changelog_uri: https://github.com/rails/rails/blob/v7.0.0.rc3/activesupport/CHANGELOG.md
363
- documentation_uri: https://api.rubyonrails.org/v7.0.0.rc3/
362
+ changelog_uri: https://github.com/rails/rails/blob/v7.0.2.1/activesupport/CHANGELOG.md
363
+ documentation_uri: https://api.rubyonrails.org/v7.0.2.1/
364
364
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
365
- source_code_uri: https://github.com/rails/rails/tree/v7.0.0.rc3/activesupport
365
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.2.1/activesupport
366
366
  rubygems_mfa_required: 'true'
367
367
  post_install_message:
368
368
  rdoc_options:
@@ -377,11 +377,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
377
377
  version: 2.7.0
378
378
  required_rubygems_version: !ruby/object:Gem::Requirement
379
379
  requirements:
380
- - - ">"
380
+ - - ">="
381
381
  - !ruby/object:Gem::Version
382
- version: 1.3.1
382
+ version: '0'
383
383
  requirements: []
384
- rubygems_version: 3.2.15
384
+ rubygems_version: 3.2.22
385
385
  signing_key:
386
386
  specification_version: 4
387
387
  summary: A toolkit of support libraries and Ruby core extensions extracted from the