mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/rubygems.rb, lib/rubygems/*, test/rubygems/*: Update
rubygems to 2.6.8.
Release note of 2.6.8: 9fb8880976
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56525 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f4b623f780
commit
9a21c28426
18 changed files with 304 additions and 22 deletions
|
@ -1,3 +1,9 @@
|
|||
Sun Oct 30 15:32:43 2016 SHIBATA Hiroshi <hsbt@ruby-lang.org>
|
||||
|
||||
* lib/rubygems.rb, lib/rubygems/*, test/rubygems/*: Update
|
||||
rubygems to 2.6.8.
|
||||
Release note of 2.6.8: https://github.com/rubygems/rubygems/commit/9fb8880976f5ab998912898b091d88aa10eb1d4a
|
||||
|
||||
Sun Oct 30 06:39:37 2016 Martin Duerst <duerst@it.aoyama.ac.jp>
|
||||
|
||||
* enc/windows_1254.c: Fix typo. Reported by k-takata at
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'rbconfig'
|
|||
require 'thread'
|
||||
|
||||
module Gem
|
||||
VERSION = '2.6.7'
|
||||
VERSION = '2.6.8'
|
||||
end
|
||||
|
||||
# Must be first since it unloads the prelude from 1.9.2
|
||||
|
|
|
@ -317,13 +317,16 @@ class Gem::Dependency
|
|||
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
|
||||
|
|
|
@ -6,6 +6,7 @@ require 'rubygems/user_interaction'
|
|||
|
||||
class Gem::Request
|
||||
|
||||
extend Gem::UserInteraction
|
||||
include Gem::UserInteraction
|
||||
|
||||
###
|
||||
|
@ -69,6 +70,13 @@ class Gem::Request
|
|||
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') ||
|
||||
|
@ -78,6 +86,44 @@ class Gem::Request
|
|||
'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.
|
||||
|
|
|
@ -182,6 +182,13 @@ module Gem::Resolver::Molinillo
|
|||
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
|
||||
|
|
|
@ -7,7 +7,7 @@ module Gem::Resolver::Molinillo
|
|||
# rubocop:disable Lint/UnusedMethodArgument
|
||||
|
||||
# @return [Symbol] The name of the action.
|
||||
def self.name
|
||||
def self.action_name
|
||||
raise 'Abstract'
|
||||
end
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ module Gem::Resolver::Molinillo
|
|||
class AddEdgeNoCircular < Action
|
||||
# @!group Action
|
||||
|
||||
# (see Action.name)
|
||||
def self.name
|
||||
# (see Action.action_name)
|
||||
def self.action_name
|
||||
:add_vertex
|
||||
end
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ module Gem::Resolver::Molinillo
|
|||
class AddVertex < Action # :nodoc:
|
||||
# @!group Action
|
||||
|
||||
# (see Action.name)
|
||||
def self.name
|
||||
# (see Action.action_name)
|
||||
def self.action_name
|
||||
:add_vertex
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# frozen_string_literal: true
|
||||
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
|
||||
module Gem::Resolver::Molinillo
|
||||
class DependencyGraph
|
||||
# @!visibility private
|
||||
# (see DependencyGraph#delete_edge)
|
||||
class DeleteEdge < Action
|
||||
# @!group Action
|
||||
|
||||
# (see Action.action_name)
|
||||
def self.action_name
|
||||
:delete_edge
|
||||
end
|
||||
|
||||
# (see Action#up)
|
||||
def up(graph)
|
||||
edge = make_edge(graph)
|
||||
edge.origin.outgoing_edges.delete(edge)
|
||||
edge.destination.incoming_edges.delete(edge)
|
||||
end
|
||||
|
||||
# (see Action#down)
|
||||
def down(graph)
|
||||
edge = make_edge(graph)
|
||||
edge.origin.outgoing_edges << edge
|
||||
edge.destination.incoming_edges << edge
|
||||
edge
|
||||
end
|
||||
|
||||
# @!group DeleteEdge
|
||||
|
||||
# @return [String] the name of the origin of the edge
|
||||
attr_reader :origin_name
|
||||
|
||||
# @return [String] the name of the destination of the edge
|
||||
attr_reader :destination_name
|
||||
|
||||
# @return [Object] the requirement that the edge represents
|
||||
attr_reader :requirement
|
||||
|
||||
# @param [DependencyGraph] graph the graph to find vertices from
|
||||
# @return [Edge] The edge this action adds
|
||||
def make_edge(graph)
|
||||
Edge.new(
|
||||
graph.vertex_named(origin_name),
|
||||
graph.vertex_named(destination_name),
|
||||
requirement
|
||||
)
|
||||
end
|
||||
|
||||
# Initialize an action to add an edge to a dependency graph
|
||||
# @param [String] origin_name the name of the origin of the edge
|
||||
# @param [String] destination_name the name of the destination of the edge
|
||||
# @param [Object] requirement the requirement that the edge represents
|
||||
def initialize(origin_name, destination_name, requirement)
|
||||
@origin_name = origin_name
|
||||
@destination_name = destination_name
|
||||
@requirement = requirement
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,7 +8,7 @@ module Gem::Resolver::Molinillo
|
|||
# @!group Action
|
||||
|
||||
# (see Action#name)
|
||||
def self.name
|
||||
def self.action_name
|
||||
:add_vertex
|
||||
end
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
@ -40,6 +41,16 @@ module Gem::Resolver::Molinillo
|
|||
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))
|
||||
|
@ -92,7 +103,7 @@ module Gem::Resolver::Molinillo
|
|||
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
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ module Gem::Resolver::Molinillo
|
|||
class SetPayload < Action # :nodoc:
|
||||
# @!group Action
|
||||
|
||||
# (see Action.name)
|
||||
def self.name
|
||||
# (see Action.action_name)
|
||||
def self.action_name
|
||||
:set_payload
|
||||
end
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ module Gem::Resolver::Molinillo
|
|||
class Tag < Action
|
||||
# @!group Action
|
||||
|
||||
# (see Action.name)
|
||||
def self.name
|
||||
# (see Action.action_name)
|
||||
def self.action_name
|
||||
:tag
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
module Gem::Resolver::Molinillo
|
||||
# The version of Gem::Resolver::Molinillo.
|
||||
VERSION = '0.5.1'.freeze
|
||||
VERSION = '0.5.3'.freeze
|
||||
end
|
||||
|
|
|
@ -356,10 +356,14 @@ module Gem::Resolver::Molinillo
|
|||
# @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)
|
||||
|
@ -368,7 +372,11 @@ module Gem::Resolver::Molinillo
|
|||
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
|
||||
|
||||
|
|
|
@ -2698,7 +2698,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
|
||||
unless specification_version.is_a?(Integer)
|
||||
raise Gem::InvalidSpecificationException,
|
||||
'specification_version must be an Integer (did you mean version?)'
|
||||
'specification_version must be a Integer (did you mean version?)'
|
||||
end
|
||||
|
||||
case platform
|
||||
|
|
|
@ -8,6 +8,7 @@ class TestGemRequest < Gem::TestCase
|
|||
|
||||
CA_CERT_FILE = cert_path 'ca'
|
||||
CHILD_CERT = load_cert 'child'
|
||||
EXPIRED_CERT = load_cert 'expired'
|
||||
PUBLIC_CERT = load_cert 'public'
|
||||
PUBLIC_CERT_FILE = cert_path 'public'
|
||||
SSL_CERT = load_cert 'ssl'
|
||||
|
@ -311,6 +312,136 @@ class TestGemRequest < Gem::TestCase
|
|||
util_restore_version
|
||||
end
|
||||
|
||||
def test_verify_certificate
|
||||
store = OpenSSL::X509::Store.new
|
||||
context = OpenSSL::X509::StoreContext.new store
|
||||
context.error = OpenSSL::X509::V_ERR_OUT_OF_MEM
|
||||
|
||||
use_ui @ui do
|
||||
Gem::Request.verify_certificate context
|
||||
end
|
||||
|
||||
assert_equal "ERROR: SSL verification error at depth 0: out of memory (17)\n",
|
||||
@ui.error
|
||||
end
|
||||
|
||||
def test_verify_certificate_extra_message
|
||||
store = OpenSSL::X509::Store.new
|
||||
context = OpenSSL::X509::StoreContext.new store
|
||||
context.error = OpenSSL::X509::V_ERR_INVALID_CA
|
||||
|
||||
use_ui @ui do
|
||||
Gem::Request.verify_certificate context
|
||||
end
|
||||
|
||||
expected = <<-ERROR
|
||||
ERROR: SSL verification error at depth 0: invalid CA certificate (24)
|
||||
ERROR: Certificate is an invalid CA certificate
|
||||
ERROR
|
||||
|
||||
assert_equal expected, @ui.error
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_CERT_HAS_EXPIRED
|
||||
error_number = OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, EXPIRED_CERT
|
||||
|
||||
assert_equal "Certificate #{EXPIRED_CERT.subject} expired at #{EXPIRED_CERT.not_before.iso8601}",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_CERT_NOT_YET_VALID
|
||||
error_number = OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, EXPIRED_CERT
|
||||
|
||||
assert_equal "Certificate #{EXPIRED_CERT.subject} not valid until #{EXPIRED_CERT.not_before.iso8601}",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_CERT_REJECTED
|
||||
error_number = OpenSSL::X509::V_ERR_CERT_REJECTED
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, CHILD_CERT
|
||||
|
||||
assert_equal "Certificate #{CHILD_CERT.subject} is rejected",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_CERT_UNTRUSTED
|
||||
error_number = OpenSSL::X509::V_ERR_CERT_UNTRUSTED
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, CHILD_CERT
|
||||
|
||||
assert_equal "Certificate #{CHILD_CERT.subject} is not trusted",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_DEPTH_ZERO_SELF_SIGNED_CERT
|
||||
error_number = OpenSSL::X509::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, CHILD_CERT
|
||||
|
||||
assert_equal "Certificate #{CHILD_CERT.issuer} is not trusted",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_INVALID_CA
|
||||
error_number = OpenSSL::X509::V_ERR_INVALID_CA
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, CHILD_CERT
|
||||
|
||||
assert_equal "Certificate #{CHILD_CERT.subject} is an invalid CA certificate",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_INVALID_PURPOSE
|
||||
error_number = OpenSSL::X509::V_ERR_INVALID_PURPOSE
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, CHILD_CERT
|
||||
|
||||
assert_equal "Certificate #{CHILD_CERT.subject} has an invalid purpose",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_SELF_SIGNED_CERT_IN_CHAIN
|
||||
error_number = OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, EXPIRED_CERT
|
||||
|
||||
assert_equal "Root certificate is not trusted (#{EXPIRED_CERT.subject})",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
|
||||
error_number = OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, EXPIRED_CERT
|
||||
|
||||
assert_equal "You must add #{EXPIRED_CERT.issuer} to your local trusted store",
|
||||
message
|
||||
end
|
||||
|
||||
def test_verify_certificate_message_UNABLE_TO_VERIFY_LEAF_SIGNATURE
|
||||
error_number = OpenSSL::X509::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
|
||||
|
||||
message =
|
||||
Gem::Request.verify_certificate_message error_number, EXPIRED_CERT
|
||||
|
||||
assert_equal "You must add #{EXPIRED_CERT.issuer} to your local trusted store",
|
||||
message
|
||||
end
|
||||
|
||||
def util_restore_version
|
||||
Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE)
|
||||
Object.send :const_set, :RUBY_ENGINE, @orig_RUBY_ENGINE if
|
||||
|
@ -344,6 +475,7 @@ class TestGemRequest < Gem::TestCase
|
|||
|
||||
def new *args; self; end
|
||||
def use_ssl=(bool); end
|
||||
def verify_callback=(setting); end
|
||||
def verify_mode=(setting); end
|
||||
def cert_store=(setting); end
|
||||
def start; end
|
||||
|
|
|
@ -3080,7 +3080,7 @@ Did you mean 'Ruby'?
|
|||
end
|
||||
end
|
||||
|
||||
err = 'specification_version must be an Integer (did you mean version?)'
|
||||
err = 'specification_version must be a Integer (did you mean version?)'
|
||||
assert_equal err, e.message
|
||||
end
|
||||
end
|
||||
|
@ -3389,6 +3389,13 @@ end
|
|||
end
|
||||
end
|
||||
|
||||
def test_find_by_name_with_only_prereleases
|
||||
q = util_spec "q", "2.a"
|
||||
install_specs q
|
||||
|
||||
assert Gem::Specification.find_by_name "q"
|
||||
end
|
||||
|
||||
def test_find_by_name_prerelease
|
||||
b = util_spec "b", "2.a"
|
||||
|
||||
|
|
Loading…
Reference in a new issue