Introduced ActiveSupport::Digest that allows to specify hash function implementation

and defaults to `Digest::MD5`.

Replaced calls to `::Digest::MD5.hexdigest` with calls to `ActiveSupport::Digest.hexdigest`.
This commit is contained in:
Dmitri Dolguikh 2017-11-29 16:27:27 -08:00
parent d2aca50bbd
commit 82822a3421
13 changed files with 81 additions and 12 deletions

@ -133,7 +133,7 @@ def generate_weak_etag(validators)
end
def generate_strong_etag(validators)
%("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(validators))}")
%("#{ActiveSupport::Digest.hexdigest(ActiveSupport::Cache.expand_cache_key(validators))}")
end
def cache_control_segments

@ -464,7 +464,7 @@ def test_stale_without_etag
end
def test_stale_with_etag
@request.if_none_match = %(W/"#{Digest::MD5.hexdigest('123')}")
@request.if_none_match = %(W/"#{ActiveSupport::Digest.hexdigest('123')}")
get :with_stale
assert_equal 304, response.status.to_i
end

@ -592,7 +592,7 @@ def weak_etag(record)
end
def strong_etag(record)
%("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(record))}")
%("#{ActiveSupport::Digest.hexdigest(ActiveSupport::Cache.expand_cache_key(record))}")
end
end

@ -89,7 +89,7 @@ def initialize(name, logical_name, template, children = [])
end
def digest(finder, stack = [])
Digest::MD5.hexdigest("#{template.source}-#{dependency_digest(finder, stack)}")
ActiveSupport::Digest.hexdigest("#{template.source}-#{dependency_digest(finder, stack)}")
end
def dependency_digest(finder, stack)

@ -3,7 +3,7 @@
module ActiveRecord
module CollectionCacheKey
def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
query_signature = Digest::MD5.hexdigest(collection.to_sql)
query_signature = ActiveSupport::Digest.hexdigest(collection.to_sql)
key = "#{collection.model_name.cache_key}/query-#{query_signature}"
if collection.loaded?

@ -24,7 +24,7 @@ class CollectionCacheKeyTest < ActiveRecord::TestCase
/\Adevelopers\/query-(\h+)-(\d+)-(\d+)\z/ =~ developers.cache_key
assert_equal Digest::MD5.hexdigest(developers.to_sql), $1
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
end
@ -37,7 +37,7 @@ class CollectionCacheKeyTest < ActiveRecord::TestCase
/\Adevelopers\/query-(\h+)-(\d+)-(\d+)\z/ =~ developers.cache_key
assert_equal Digest::MD5.hexdigest(developers.to_sql), $1
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
end
@ -50,7 +50,7 @@ class CollectionCacheKeyTest < ActiveRecord::TestCase
/\Adevelopers\/query-(\h+)-(\d+)-(\d+)\z/ =~ developers.cache_key
assert_equal Digest::MD5.hexdigest(developers.to_sql), $1
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
end
@ -68,7 +68,7 @@ class CollectionCacheKeyTest < ActiveRecord::TestCase
/\Adevelopers\/query-(\h+)-(\d+)-(\d+)\z/ =~ developers.cache_key
assert_equal Digest::MD5.hexdigest(developers.to_sql), $1
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
end

@ -1,3 +1,10 @@
* Introduced `ActiveSupport::Digest` that allows to specify hash function implementation
and defaults to `Digest::MD5`.
Replaced calls to `::Digest::MD5.hexdigest` with calls to `ActiveSupport::Digest.hexdigest`.
*Dmitri Dolguikh*
## Rails 5.2.0.beta2 (November 28, 2017) ##
* No changes.

@ -53,6 +53,7 @@ module ActiveSupport
autoload :Callbacks
autoload :Configurable
autoload :Deprecation
autoload :Digest
autoload :Gzip
autoload :Inflector
autoload :JSON

@ -121,7 +121,7 @@ def normalize_key(key, options)
fname = URI.encode_www_form_component(key)
if fname.size > FILEPATH_MAX_SIZE
fname = Digest::MD5.hexdigest(key)
fname = ActiveSupport::Digest.hexdigest(key)
end
hash = Zlib.adler32(fname)

@ -7,7 +7,6 @@
raise e
end
require "digest/md5"
require "active_support/core_ext/marshal"
require "active_support/core_ext/array/extract_options"
@ -183,7 +182,7 @@ def normalize_key(key, options)
key = super.dup
key = key.force_encoding(Encoding::ASCII_8BIT)
key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
key = "#{key[0, 213]}:md5:#{ActiveSupport::Digest.hexdigest(key)}" if key.size > 250
key
end

@ -0,0 +1,28 @@
# frozen_string_literal: true
module ActiveSupport
class Digest #:nodoc:
class <<self
def hash_digest_class
@hash_digest_class || ::Digest::MD5
end
def hash_digest_class=(klass)
raise ArgumentError, "#{klass} is expected to implement hexdigest class method" unless klass.respond_to?(:hexdigest)
@hash_digest_class = klass
end
def hexdigest(arg)
new.hexdigest(arg)
end
end
def initialize(digest_class: nil)
@digest_class = digest_class || self.class.hash_digest_class
end
def hexdigest(arg)
@digest_class.hexdigest(arg).truncate(32)
end
end
end

@ -66,5 +66,12 @@ class Railtie < Rails::Railtie # :nodoc:
ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
end
end
initializer "active_support.set_hash_digest_class" do |app|
if app.config.active_support.respond_to?(:use_hash_digest_class) && app.config.active_support.use_hash_digest_class
ActiveSupport::Digest.hash_digest_class =
app.config.active_support.use_hash_digest_class
end
end
end
end

@ -0,0 +1,27 @@
# frozen_string_literal: true
require "abstract_unit"
require "openssl"
class DigestTest < ActiveSupport::TestCase
class InvalidDigest; end
def test_with_default_hash_digest_class
assert_equal ::Digest::MD5.hexdigest("hello friend"), ActiveSupport::Digest.hexdigest("hello friend")
end
def test_with_custom_hash_digest_class
original_hash_digest_class = ActiveSupport::Digest.hash_digest_class
ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
digest = ActiveSupport::Digest.hexdigest("hello friend")
assert_equal 32, digest.length
assert_equal ::Digest::SHA1.hexdigest("hello friend").truncate(32), digest
ensure
ActiveSupport::Digest.hash_digest_class = original_hash_digest_class
end
def test_should_raise_argument_error_if_custom_digest_is_missing_hexdigest_method
assert_raises(ArgumentError) { ActiveSupport::Digest.hash_digest_class = InvalidDigest }
end
end