Skip to content

Commit

Permalink
[rubygems/rubygems] Store Checksum::Store indexed by spec.lock_name
Browse files Browse the repository at this point in the history
  • Loading branch information
martinemde authored and matzbot committed Dec 13, 2023
1 parent 14c7895 commit 7f4b271
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 20 deletions.
32 changes: 16 additions & 16 deletions lib/bundler/checksum.rb
Expand Up @@ -165,8 +165,8 @@ def initialize

def initialize_copy(other)
@store = {}
other.store.each do |name_tuple, checksums|
store[name_tuple] = checksums.dup
other.store.each do |lock_name, checksums|
store[lock_name] = checksums.dup
end
end

Expand All @@ -175,7 +175,7 @@ def inspect
end

def fetch(spec, algo = DEFAULT_ALGORITHM)
store[spec.name_tuple]&.fetch(algo, nil)
store[spec.name_tuple.lock_name]&.fetch(algo, nil)
end

# Replace when the new checksum is from the same source.
Expand All @@ -191,53 +191,53 @@ def fetch(spec, algo = DEFAULT_ALGORITHM)
def replace(spec, checksum)
return unless checksum

name_tuple = spec.name_tuple
checksums = (store[name_tuple] ||= {})
lock_name = spec.name_tuple.lock_name
checksums = (store[lock_name] ||= {})
existing = checksums[checksum.algo]

# we assume only one source because this is used while building the index
if !existing || existing.sources.first == checksum.sources.first
checksums[checksum.algo] = checksum
else
register_checksum(name_tuple, checksum)
register_checksum(lock_name, checksum)
end
end

def register(spec, checksum)
return unless checksum
register_checksum(spec.name_tuple, checksum)
register_checksum(spec.name_tuple.lock_name, checksum)
end

def merge!(other)
other.store.each do |name_tuple, checksums|
other.store.each do |lock_name, checksums|
checksums.each do |_algo, checksum|
register_checksum(name_tuple, checksum)
register_checksum(lock_name, checksum)
end
end
end

def to_lock(spec)
name_tuple = spec.name_tuple
if checksums = store[name_tuple]
"#{name_tuple.lock_name} #{checksums.values.map(&:to_lock).sort.join(",")}"
lock_name = spec.name_tuple.lock_name
if checksums = store[lock_name]
"#{lock_name} #{checksums.values.map(&:to_lock).sort.join(",")}"
else
name_tuple.lock_name
lock_name
end
end

private

def register_checksum(name_tuple, checksum)
def register_checksum(lock_name, checksum)
return unless checksum
checksums = (store[name_tuple] ||= {})
checksums = (store[lock_name] ||= {})
existing = checksums[checksum.algo]

if !existing
checksums[checksum.algo] = checksum
elsif existing.merge!(checksum)
checksum
else
raise ChecksumMismatchError.new(name_tuple, existing, checksum)
raise ChecksumMismatchError.new(lock_name, existing, checksum)
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions lib/bundler/errors.rb
Expand Up @@ -53,18 +53,18 @@ class GemfileEvalError < GemfileError; end
class MarshalError < StandardError; end

class ChecksumMismatchError < SecurityError
def initialize(name_tuple, existing, checksum)
@name_tuple = name_tuple
def initialize(lock_name, existing, checksum)
@lock_name = lock_name
@existing = existing
@checksum = checksum
end

def message
<<~MESSAGE
Bundler found mismatched checksums. This is a potential security risk.
#{@name_tuple.lock_name} #{@existing.to_lock}
#{@lock_name} #{@existing.to_lock}
from #{@existing.sources.join("\n and ")}
#{@name_tuple.lock_name} #{@checksum.to_lock}
#{@lock_name} #{@checksum.to_lock}
from #{@checksum.sources.join("\n and ")}
#{mismatch_resolution_instructions}
Expand Down

0 comments on commit 7f4b271

Please sign in to comment.