Skip to content

Commit

Permalink
Update RubyGems to 2.6.8. Fixes #4205.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Nov 8, 2016
1 parent 4e775c7 commit 9e8e14b
Show file tree
Hide file tree
Showing 17 changed files with 135 additions and 40 deletions.
5 changes: 3 additions & 2 deletions lib/ruby/stdlib/rubygems.rb
Expand Up @@ -10,7 +10,7 @@
require 'thread'

module Gem
VERSION = '2.6.6'
VERSION = '2.6.8'
end

# Must be first since it unloads the prelude from 1.9.2
Expand Down Expand Up @@ -971,7 +971,8 @@ def self.rubygems_version
# default_sources if the sources list is empty.

def self.sources
@sources ||= Gem::SourceList.from(default_sources)
source_list = configuration.sources || default_sources
@sources ||= Gem::SourceList.from(source_list)
end

##
Expand Down
27 changes: 14 additions & 13 deletions lib/ruby/stdlib/rubygems/commands/query_command.rb
Expand Up @@ -255,21 +255,22 @@ def entry_versions entry, name_tuples, platforms, specs
name_tuples.map { |n| n.version }.uniq
else
platforms.sort.reverse.map do |version, pls|
out = version.to_s

if options[:domain] == :local
default = specs.any? do |s|
!s.is_a?(Gem::Source) && s.version == version && s.default_gem?
if pls == [Gem::Platform::RUBY] then
if options[:domain] == :remote || specs.all? { |spec| spec.is_a? Gem::Source }
version
else
spec = specs.select { |s| s.version == version }
if spec.first.default_gem?
"default: #{version}"
else
version
end
end
out = "default: #{out}" if default
end

if pls != [Gem::Platform::RUBY] then
platform_list = [pls.delete(Gem::Platform::RUBY), *pls.sort].compact
out = platform_list.unshift(out).join(' ')
else
ruby = pls.delete Gem::Platform::RUBY
platform_list = [ruby, *pls.sort].compact
"#{version} #{platform_list.join ' '}"
end

out
end
end

Expand Down
6 changes: 5 additions & 1 deletion lib/ruby/stdlib/rubygems/config_file.rb
Expand Up @@ -143,6 +143,10 @@ class Gem::ConfigFile

attr_accessor :ssl_ca_cert

##
# sources to look for gems
attr_accessor :sources

##
# Path name of directory or file of openssl client certificate, used for remote https connection with client authentication

Expand Down Expand Up @@ -216,6 +220,7 @@ def initialize(args)
@update_sources = @hash[:update_sources] if @hash.key? :update_sources
@verbose = @hash[:verbose] if @hash.key? :verbose
@disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
@sources = @hash[:sources] if @hash.key? :sources

@ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
@ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
Expand All @@ -224,7 +229,6 @@ def initialize(args)
@api_keys = nil
@rubygems_api_key = nil

Gem.sources = @hash[:sources] if @hash.key? :sources
handle_arguments arg_list
end

Expand Down
11 changes: 7 additions & 4 deletions lib/ruby/stdlib/rubygems/dependency.rb
Expand Up @@ -317,13 +317,16 @@ def to_specs
end

def to_spec
matches = self.to_specs

active = matches.find { |spec| spec && spec.activated? }
matches = self.to_specs.compact

active = matches.find { |spec| spec.activated? }
return active if active

matches.delete_if { |spec| spec.nil? || spec.version.prerelease? } unless prerelease?
return matches.first if prerelease?

# Move prereleases to the end of the list for >= 0 requirements
pre, matches = matches.partition { |spec| spec.version.prerelease? }
matches += pre if requirement == Gem::Requirement.default

matches.first
end
Expand Down
11 changes: 8 additions & 3 deletions lib/ruby/stdlib/rubygems/installer.rb
Expand Up @@ -282,18 +282,23 @@ def install

run_pre_install_hooks

# Set loaded_from to ensure extension_dir is correct
if @options[:install_as_default] then
spec.loaded_from = default_spec_file
else
spec.loaded_from = spec_file
end

# Completely remove any previous gem files
FileUtils.rm_rf gem_dir
FileUtils.rm_rf spec.extension_dir

FileUtils.mkdir_p gem_dir

if @options[:install_as_default]
spec.loaded_from = default_spec_file
if @options[:install_as_default] then
extract_bin
write_default_spec
else
spec.loaded_from = spec_file
extract_files

build_extensions
Expand Down
3 changes: 3 additions & 0 deletions lib/ruby/stdlib/rubygems/remote_fetcher.rb
Expand Up @@ -260,6 +260,9 @@ def fetch_http uri, last_modified = nil, head = false, depth = 0
Net::HTTPTemporaryRedirect then
raise FetchError.new('too many redirects', uri) if depth > 10

unless location = response['Location']
raise FetchError.new("redirecting but no redirect location was given", uri)
end
location = URI.parse response['Location']

if https?(uri) && !https?(location)
Expand Down
46 changes: 46 additions & 0 deletions lib/ruby/stdlib/rubygems/request.rb
Expand Up @@ -6,6 +6,7 @@

class Gem::Request

extend Gem::UserInteraction
include Gem::UserInteraction

###
Expand Down Expand Up @@ -69,6 +70,13 @@ def self.configure_connection_for_https(connection, cert_files)
end
end
connection.cert_store = store

connection.verify_callback = proc do |preverify_ok, store_context|
verify_certificate store_context unless preverify_ok

preverify_ok
end

connection
rescue LoadError => e
raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
Expand All @@ -78,6 +86,44 @@ def self.configure_connection_for_https(connection, cert_files)
'Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources')
end

def self.verify_certificate store_context
depth = store_context.error_depth
error = store_context.error_string
number = store_context.error
cert = store_context.current_cert

ui.alert_error "SSL verification error at depth #{depth}: #{error} (#{number})"

extra_message = verify_certificate_message number, cert

ui.alert_error extra_message if extra_message
end

def self.verify_certificate_message error_number, cert
return unless cert
case error_number
when OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED then
"Certificate #{cert.subject} expired at #{cert.not_after.iso8601}"
when OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID then
"Certificate #{cert.subject} not valid until #{cert.not_before.iso8601}"
when OpenSSL::X509::V_ERR_CERT_REJECTED then
"Certificate #{cert.subject} is rejected"
when OpenSSL::X509::V_ERR_CERT_UNTRUSTED then
"Certificate #{cert.subject} is not trusted"
when OpenSSL::X509::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT then
"Certificate #{cert.issuer} is not trusted"
when OpenSSL::X509::V_ERR_INVALID_CA then
"Certificate #{cert.subject} is an invalid CA certificate"
when OpenSSL::X509::V_ERR_INVALID_PURPOSE then
"Certificate #{cert.subject} has an invalid purpose"
when OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN then
"Root certificate is not trusted (#{cert.subject})"
when OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
OpenSSL::X509::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE then
"You must add #{cert.issuer} to your local trusted store"
end
end

##
# Creates or an HTTP connection based on +uri+, or retrieves an existing
# connection, using a proxy if needed.
Expand Down
Expand Up @@ -182,6 +182,13 @@ def add_edge(origin, destination, requirement)
add_edge_no_circular(origin, destination, requirement)
end

# Deletes an {Edge} from the dependency graph
# @param [Edge] edge
# @return [Void]
def delete_edge(edge)
log.delete_edge(self, edge.origin.name, edge.destination.name, edge.requirement)
end

# Sets the payload of the vertex with the given name
# @param [String] name the name of the vertex
# @param [Object] payload the payload
Expand Down
Expand Up @@ -7,7 +7,7 @@ class Action
# rubocop:disable Lint/UnusedMethodArgument

# @return [Symbol] The name of the action.
def self.name
def self.action_name
raise 'Abstract'
end

Expand Down
Expand Up @@ -7,8 +7,8 @@ class DependencyGraph
class AddEdgeNoCircular < Action
# @!group Action

# (see Action.name)
def self.name
# (see Action.action_name)
def self.action_name
:add_vertex
end

Expand Down
Expand Up @@ -7,8 +7,8 @@ class DependencyGraph
class AddVertex < Action # :nodoc:
# @!group Action

# (see Action.name)
def self.name
# (see Action.action_name)
def self.action_name
:add_vertex
end

Expand Down
Expand Up @@ -8,7 +8,7 @@ class DetachVertexNamed < Action
# @!group Action

# (see Action#name)
def self.name
def self.action_name
:add_vertex
end

Expand Down
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular'
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex'
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge'
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named'
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload'
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag'
Expand Down Expand Up @@ -40,6 +41,16 @@ def add_edge_no_circular(graph, origin, destination, requirement)
push_action(graph, AddEdgeNoCircular.new(origin, destination, requirement))
end

# {include:DependencyGraph#delete_edge}
# @param [Graph] graph the graph to perform the action on
# @param [String] origin_name
# @param [String] destination_name
# @param [Object] requirement
# @return (see DependencyGraph#delete_edge)
def delete_edge(graph, origin_name, destination_name, requirement)
push_action(graph, DeleteEdge.new(origin_name, destination_name, requirement))
end

# @macro action
def set_payload(graph, name, payload)
push_action(graph, SetPayload.new(name, payload))
Expand Down Expand Up @@ -92,7 +103,7 @@ def rewind_to(graph, tag)
loop do
action = pop!(graph)
raise "No tag #{tag.inspect} found" unless action
break if action.class.name == :tag && action.tag == tag
break if action.class.action_name == :tag && action.tag == tag
end
end

Expand Down
Expand Up @@ -7,8 +7,8 @@ class DependencyGraph
class SetPayload < Action # :nodoc:
# @!group Action

# (see Action.name)
def self.name
# (see Action.action_name)
def self.action_name
:set_payload
end

Expand Down
Expand Up @@ -7,8 +7,8 @@ class DependencyGraph
class Tag < Action
# @!group Action

# (see Action.name)
def self.name
# (see Action.action_name)
def self.action_name
:tag
end

Expand Down
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# The version of Gem::Resolver::Molinillo.
VERSION = '0.5.0'.freeze
VERSION = '0.5.3'.freeze
end
Expand Up @@ -184,6 +184,8 @@ def unwind_for_conflict
raise VersionConflict.new(c) unless state
activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
state.conflicts = c
index = states.size - 1
@parent_of.reject! { |_, i| i >= index }
end
end

Expand All @@ -209,7 +211,10 @@ def state_index_for_unwind
# @return [Object] the requirement that led to `requirement` being added
# to the list of requirements.
def parent_of(requirement)
@parent_of[requirement]
return unless requirement
return unless index = @parent_of[requirement]
return unless parent_state = @states[index]
parent_state.requirement
end

# @return [Object] the requirement that led to a version of a possibility
Expand Down Expand Up @@ -351,10 +356,14 @@ def attempt_to_swap_possibility
# @return [void]
def fixup_swapped_children(vertex)
payload = vertex.payload
dep_names = dependencies_for(payload).map(&method(:name_for))
vertex.successors.each do |succ|
if !dep_names.include?(succ.name) && !succ.root? && succ.predecessors.to_a == [vertex]
deps = dependencies_for(payload).group_by(&method(:name_for))
vertex.outgoing_edges.each do |outgoing_edge|
@parent_of[outgoing_edge.requirement] = states.size - 1
succ = outgoing_edge.destination
matching_deps = Array(deps[succ.name])
if matching_deps.empty? && !succ.root? && succ.predecessors.to_a == [vertex]
debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
succ.requirements.each { |r| @parent_of.delete(r) }
activated.detach_vertex_named(succ.name)

all_successor_names = succ.recursive_successors.map(&:name)
Expand All @@ -363,7 +372,11 @@ def fixup_swapped_children(vertex)
requirement_name = name_for(requirement)
(requirement_name == succ.name) || all_successor_names.include?(requirement_name)
end
elsif !matching_deps.include?(outgoing_edge.requirement)
activated.delete_edge(outgoing_edge)
requirements.delete(outgoing_edge.requirement)
end
matching_deps.delete(outgoing_edge.requirement)
end
end

Expand Down Expand Up @@ -418,7 +431,8 @@ def require_nested_dependencies_for(activated_spec)
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
nested_dependencies.each do |d|
activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d)
@parent_of[d] = requirement
parent_index = states.size - 1
@parent_of[d] ||= parent_index
end

push_state_for_requirements(requirements + nested_dependencies, !nested_dependencies.empty?)
Expand Down

0 comments on commit 9e8e14b

Please sign in to comment.