summaryrefslogtreecommitdiff
path: root/lib/bundler/errors.rb
diff options
context:
space:
mode:
authorMartin Emde <martin.emde@gmail.com>2023-09-01 15:15:49 -0700
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2023-10-23 13:59:01 +0900
commitc667de72ff9de195e1cab4b1937973e841ff89ae (patch)
tree6dc6a88dbf8c44109593352055c8e798d562a83f /lib/bundler/errors.rb
parent6362bfdc337c1929a381734ded417b796f9767bf (diff)
[rubygems/rubygems] Improve errors and register checksums reliably
Improve error reporting for checksums, raises a new error class. Solve for multi-source checksum errors. Add CHECKSUMS to tool/bundler/(dev|standard|rubocop)26_gems.rb https://github.com/rubygems/rubygems/commit/26ceee0e76 Co-authored-by: Samuel Giddins <segiddins@segiddins.me>
Diffstat (limited to 'lib/bundler/errors.rb')
-rw-r--r--lib/bundler/errors.rb43
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb
index 5839fc6a73..c6b3cec4dc 100644
--- a/lib/bundler/errors.rb
+++ b/lib/bundler/errors.rb
@@ -52,6 +52,49 @@ module Bundler
class GemfileEvalError < GemfileError; end
class MarshalError < StandardError; end
+ class ChecksumMismatchError < SecurityError
+ def initialize(name_tuple, existing, checksum)
+ @name_tuple = name_tuple
+ @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}
+ from #{@existing.sources.join("\n and ")}
+ #{@name_tuple.lock_name} #{@checksum.to_lock}
+ from #{@checksum.sources.join("\n and ")}
+
+ #{mismatch_resolution_instructions}
+ To ignore checksum security warnings, disable checksum validation with
+ `bundle config set --local disable_checksum_validation true`
+ MESSAGE
+ end
+
+ def mismatch_resolution_instructions
+ removable, remote = [@existing, @checksum].partition(&:removable?)
+ case removable.size
+ when 0
+ msg = +"Mismatched checksums each have an authoritative source:\n"
+ msg << " 1. #{@existing.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
+ msg << " 2. #{@checksum.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
+ msg << "You may need to alter your Gemfile sources to resolve this issue.\n"
+ when 1
+ msg = +"If you trust #{remote.first.sources.first}, to resolve this issue you can:\n"
+ msg << removable.first.removal_instructions
+ when 2
+ msg = +"To resolve this issue you can either:\n"
+ msg << @checksum.removal_instructions
+ msg << "or if you are sure that the new checksum from #{@checksum.sources.first} is correct:\n"
+ msg << @existing.removal_instructions
+ end
+ end
+
+ status_code(37)
+ end
+
class PermissionError < BundlerError
def initialize(path, permission_type = :write)
@path = path