Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more
Validator performs various gem file and gem database validation
Checks the gem directory for the following potential inconsistencies/problems:
Checksum gem itself
For each file in each gem, check consistency of installed versions
Check for files that aren’t part of the gem but are in the gems directory
1 cache - 1 spec - 1 directory.
returns a hash of ErrorData objects, keyed on the problem gem’s name.
# File rubygems/validator.rb, line 84 def alien(gems=[]) errors = Hash.new { |h,k| h[k] = {} } Gem::SourceIndex.from_installed_gems.each do |gem_name, gem_spec| next unless gems.include? gem_spec.name unless gems.empty? install_dir = gem_spec.installation_path gem_path = Gem.cache_gem(gem_spec.file_name, install_dir) spec_path = File.join install_dir, "specifications", gem_spec.spec_name gem_directory = gem_spec.full_gem_path unless File.directory? gem_directory then errors[gem_name][gem_spec.full_name] = "Gem registered but doesn't exist at #{gem_directory}" next end unless File.exist? spec_path then errors[gem_name][spec_path] = "Spec file missing for installed gem" end begin verify_gem_file(gem_path) good, gone, unreadable = nil, nil, nil, nil open gem_path, Gem.binary_mode do |file| format = Gem::Format.from_file_by_path(gem_path) good, gone = format.file_entries.partition { |entry, _| File.exist? File.join(gem_directory, entry['path']) } gone.map! { |entry, _| entry['path'] } gone.sort.each do |path| errors[gem_name][path] = "Missing file" end good, unreadable = good.partition { |entry, _| File.readable? File.join(gem_directory, entry['path']) } unreadable.map! { |entry, _| entry['path'] } unreadable.sort.each do |path| errors[gem_name][path] = "Unreadable file" end good.each do |entry, data| begin next unless data # HACK `gem check -a mkrf` open File.join(gem_directory, entry['path']), Gem.binary_mode do |f| unless Digest::MD5.hexdigest(f.read).to_s == Digest::MD5.hexdigest(data).to_s then errors[gem_name][entry['path']] = "Modified from original" end end end end end installed_files = find_files_for_gem(gem_directory) good.map! { |entry, _| entry['path'] } extras = installed_files - good - unreadable extras.each do |extra| errors[gem_name][extra] = "Extra file" end rescue Gem::VerificationError => e errors[gem_name][gem_path] = e.message end end errors.each do |name, subhash| errors[name] = subhash.map { |path, msg| ErrorData.new(path, msg) } end errors end
# File rubygems/validator.rb, line 164 def remove_leading_dot_dir(path) path.sub(/^\.\//, "") end
Given a gem file’s contents, validates against its own MD5 checksum
Contents of the gem file
# File rubygems/validator.rb, line 26 def verify_gem(gem_data) raise Gem::VerificationError, 'empty gem file' if gem_data.size == 0 unless gem_data =~ /MD5SUM/ then return # Don't worry about it...this sucks. Need to fix MD5 stuff for # new format # FIXME end sum_data = gem_data.gsub(/MD5SUM = "([a-z0-9]+)"/, "MD5SUM = \"#{"F" * 32}\"") unless Digest::MD5.hexdigest(sum_data) == $1.to_s then raise Gem::VerificationError, 'invalid checksum for gem file' end end
Given the path to a gem file, validates against its own MD5 checksum
Path to gem file
# File rubygems/validator.rb, line 48 def verify_gem_file(gem_path) open gem_path, Gem.binary_mode do |file| gem_data = file.read verify_gem gem_data end rescue Errno::ENOENT, Errno::EINVAL raise Gem::VerificationError, "missing gem file #{gem_path}" end
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.