1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/rubygems: Update to RubyGems 2.1.0. Fixes CVE-2013-4287.

See http://rubygems.rubyforge.org/rubygems-update/CVE-2013-4287_txt.html
  for CVE information.

  See http://rubygems.rubyforge.org/rubygems-update/History_txt.html#label-2.1.0+%2F+2013-09-09
  for release notes.

* test/rubygems:  Tests for the above.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42898 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2013-09-10 00:52:14 +00:00
parent 888e5cbbe7
commit f06f903231
23 changed files with 313 additions and 39 deletions

View file

@ -1,3 +1,15 @@
Tue Sep 10 09:51:22 2013 Eric Hodel <drbrain@segment7.net>
* lib/rubygems: Update to RubyGems 2.1.0. Fixes CVE-2013-4287.
See http://rubygems.rubyforge.org/rubygems-update/CVE-2013-4287_txt.html
for CVE information.
See http://rubygems.rubyforge.org/rubygems-update/History_txt.html#label-2.1.0+%2F+2013-09-09
for release notes.
* test/rubygems: Tests for the above.
Mon Sep 9 21:31:45 2013 Tanaka Akira <akr@fsij.org>
* process.c: Remove spaces between SI prefix and unit to follow

View file

@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
VERSION = '2.1.0.rc.2'
VERSION = '2.1.0'
end
# Must be first since it unloads the prelude from 1.9.2
@ -315,7 +315,7 @@ module Gem
@paths = nil
@user_home = nil
Gem::Specification.reset
Gem::Security.reset if const_defined? :Security
Gem::Security.reset if defined?(Gem::Security)
end
##

View file

@ -79,7 +79,9 @@ class Gem::DependencyResolver
needed = nil
@needed.reverse_each do |n|
needed = Gem::List.new(Gem::DependencyResolver::DependencyRequest.new(n, nil), needed)
request = Gem::DependencyResolver::DependencyRequest.new n, nil
needed = Gem::List.new request, needed
end
res = resolve_for needed, nil
@ -162,7 +164,9 @@ class Gem::DependencyResolver
# Sort them so that we try the highest versions
# first.
possible = possible.sort_by { |s| [s.source, s.version] }
possible = possible.sort_by do |s|
[s.source, s.version, s.platform == Gem::Platform::RUBY ? -1 : 1]
end
# We track the conflicts seen so that we can report them
# to help the user figure out how to fix the situation.

View file

@ -8,6 +8,7 @@ class Gem::DependencyResolver::APISpecification
attr_reader :dependencies
attr_reader :name
attr_reader :platform
attr_reader :set # :nodoc:
attr_reader :version
@ -15,6 +16,7 @@ class Gem::DependencyResolver::APISpecification
@set = set
@name = api_data[:name]
@version = Gem::Version.new api_data[:number]
@platform = api_data[:platform]
@dependencies = api_data[:dependencies].map do |name, ver|
Gem::Dependency.new name, ver.split(/\s*,\s*/)
end
@ -25,6 +27,7 @@ class Gem::DependencyResolver::APISpecification
@set == other.set and
@name == other.name and
@version == other.version and
@platform == other.platform and
@dependencies == other.dependencies
end

View file

@ -43,9 +43,14 @@ class Gem::DependencyResolver::IndexSet
# Called from IndexSpecification to get a true Specification
# object.
def load_spec name, ver, source
key = "#{name}-#{ver}"
@specs[key] ||= source.fetch_spec(Gem::NameTuple.new(name, ver))
def load_spec name, ver, platform, source
key = "#{name}-#{ver}-#{platform}"
@specs.fetch key do
tuple = Gem::NameTuple.new name, ver, platform
@specs[key] = source.fetch_spec tuple
end
end
##

View file

@ -8,6 +8,8 @@ class Gem::DependencyResolver::IndexSpecification
attr_reader :name
attr_reader :platform
attr_reader :source
attr_reader :version
@ -39,14 +41,19 @@ class Gem::DependencyResolver::IndexSpecification
q.breakable
q.text full_name
unless Gem::Platform::RUBY == @platform then
q.breakable
q.text @platform
end
q.breakable
q.text ' source '
q.text 'source '
q.pp @source
end
end
def spec
@spec ||= @set.load_spec(@name, @version, @source)
@spec ||= @set.load_spec(@name, @version, @platform, @source)
end
end

View file

@ -26,6 +26,10 @@ class Gem::DependencyResolver::InstalledSpecification
@spec.name
end
def platform
@spec.platform
end
def source
@source ||= Gem::Source::Installed.new
end

View file

@ -115,9 +115,14 @@ class Gem::DependencyResolver::InstallerSet
# Called from IndexSpecification to get a true Specification
# object.
def load_spec name, ver, source
key = "#{name}-#{ver}"
@specs[key] ||= source.fetch_spec Gem::NameTuple.new name, ver
def load_spec name, ver, platform, source
key = "#{name}-#{ver}-#{platform}"
@specs.fetch key do
tuple = Gem::NameTuple.new name, ver, platform
@specs[key] = source.fetch_spec tuple
end
end
##

View file

@ -77,7 +77,8 @@ module Gem::GemcutterUtilities
# Signs in with the RubyGems API at +sign_in_host+ and sets the rubygems API
# key.
def sign_in sign_in_host = self.host
def sign_in sign_in_host = nil
sign_in_host ||= self.host
return if Gem.configuration.rubygems_api_key
pretty_host = if Gem::DEFAULT_HOST == sign_in_host then

View file

@ -28,7 +28,10 @@ class Gem::RequestSet
@always_install = []
@development = false
@requests = []
@soft_missing = false
@sorted = nil
@specs = nil
yield self if block_given?
end

View file

@ -200,8 +200,11 @@ class Gem::SpecFetcher
when :released
tuples_for source, :released
when :complete
tuples_for(source, :prerelease, true) +
names =
tuples_for(source, :prerelease, true) +
tuples_for(source, :released)
names.sort
when :prerelease
tuples_for(source, :prerelease)
else

View file

@ -34,7 +34,7 @@ class Date; end
# s.homepage = 'https://rubygems.org/gems/example'
# end
#
# Starting in RubyGems 1.9.0, a Specification can hold arbitrary
# Starting in RubyGems 2.0, a Specification can hold arbitrary
# metadata. This metadata is accessed via Specification#metadata
# and has the following restrictions:
#
@ -2097,7 +2097,6 @@ class Gem::Specification < Gem::BasicSpecification
# Returns an object you can use to sort specifications in #sort_by.
def sort_obj
# TODO: this is horrible. Deprecate it.
[@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1]
end

View file

@ -1097,7 +1097,11 @@ Also, a list:
class StaticSet
def initialize(specs)
@specs = specs.sort_by { |s| s.full_name }
@specs = specs
end
def add spec
@specs << spec
end
def find_spec(dep)
@ -1110,6 +1114,15 @@ Also, a list:
@specs.find_all { |s| dep.matches_spec? s }
end
def load_spec name, ver, platform, source
dep = Gem::Dependency.new name, ver
spec = find_spec dep
Gem::Specification.new spec.name, spec.version do |s|
s.platform = spec.platform
end
end
def prefetch(reqs)
end
end

View file

@ -147,7 +147,7 @@ class Gem::Version
# FIX: These are only used once, in .correct?. Do they deserve to be
# constants?
VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})*\s*\z/ # :nodoc:
##

View file

@ -1183,23 +1183,28 @@ class TestGem < Gem::TestCase
def test_default_gems_use_full_paths
begin
engine = RUBY_ENGINE
Object.send :remove_const, :RUBY_ENGINE
if defined?(RUBY_ENGINE) then
engine = RUBY_ENGINE
Object.send :remove_const, :RUBY_ENGINE
end
Object.const_set :RUBY_ENGINE, 'ruby'
refute Gem.default_gems_use_full_paths?
ensure
Object.send :remove_const, :RUBY_ENGINE
Object.const_set :RUBY_ENGINE, engine
Object.const_set :RUBY_ENGINE, engine if engine
end
begin
engine = RUBY_ENGINE
Object.send :remove_const, :RUBY_ENGINE
if defined?(RUBY_ENGINE) then
engine = RUBY_ENGINE
Object.send :remove_const, :RUBY_ENGINE
end
Object.const_set :RUBY_ENGINE, 'jruby'
assert Gem.default_gems_use_full_paths?
ensure
Object.send :remove_const, :RUBY_ENGINE
Object.const_set :RUBY_ENGINE, engine
Object.const_set :RUBY_ENGINE, engine if engine
end
end

View file

@ -66,6 +66,27 @@ class TestGemDependencyResolver < Gem::TestCase
assert_set [a2], res.resolve
end
def test_picks_best_platform
is = Gem::DependencyResolver::IndexSpecification
a2_p = quick_spec 'a' do |s| s.platform = Gem::Platform.local end
version = Gem::Version.new 2
source = Gem::Source.new @gem_repo
s = set
a2 = is.new s, 'a', version, source, Gem::Platform::RUBY
a2_p = is.new s, 'a', version, source, Gem::Platform.local.to_s
s.add a2_p
s.add a2
ad = make_dep "a"
res = Gem::DependencyResolver.new([ad], s)
assert_set [a2_p], res.resolve
end
def test_only_returns_spec_once
a1 = util_spec "a", "1", "c" => "= 1"
b1 = util_spec "b", "1", "c" => "= 1"

View file

@ -0,0 +1,33 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverAPISpecification < Gem::TestCase
def test_initialize
set = Gem::DependencyResolver::APISet.new
data = {
:name => 'rails',
:number => '3.0.3',
:platform => 'ruby',
:dependencies => [
['bundler', '~> 1.0'],
['railties', '= 3.0.3'],
],
}
spec = Gem::DependencyResolver::APISpecification.new set, data
assert_equal 'rails', spec.name
assert_equal Gem::Version.new('3.0.3'), spec.version
assert_equal Gem::Platform::RUBY, spec.platform
expected = [
Gem::Dependency.new('bundler', '~> 1.0'),
Gem::Dependency.new('railties', '= 3.0.3'),
]
assert_equal expected, spec.dependencies
end
end

View file

@ -0,0 +1,53 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverIndexSet < Gem::TestCase
def test_load_spec
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
a_2 = quick_spec 'a', 2
a_2_p = quick_spec 'a', 2 do |s| s.platform = Gem::Platform.local end
Gem::Specification.add_specs a_2, a_2_p
util_setup_spec_fetcher a_2, a_2_p
source = Gem::Source.new @gem_repo
version = v 2
set = Gem::DependencyResolver::IndexSet.new
spec = set.load_spec 'a', version, Gem::Platform.local, source
assert_equal a_2_p.full_name, spec.full_name
end
def test_load_spec_cached
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
a_2 = quick_spec 'a', 2
a_2_p = quick_spec 'a', 2 do |s| s.platform = Gem::Platform.local end
Gem::Specification.add_specs a_2, a_2_p
util_setup_spec_fetcher a_2, a_2_p
source = Gem::Source.new @gem_repo
version = v 2
set = Gem::DependencyResolver::IndexSet.new
first = set.load_spec 'a', version, Gem::Platform.local, source
util_setup_spec_fetcher # clear
second = set.load_spec 'a', version, Gem::Platform.local, source
assert_same first, second
end
end

View file

@ -0,0 +1,46 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverIndexSpecification < Gem::TestCase
def test_initialize
set = Gem::DependencyResolver::IndexSet.new
source = Gem::Source.new @gem_repo
version = Gem::Version.new '3.0.3'
spec = Gem::DependencyResolver::IndexSpecification.new(
set, 'rails', version, source, Gem::Platform::RUBY)
assert_equal 'rails', spec.name
assert_equal version, spec.version
assert_equal Gem::Platform::RUBY, spec.platform
assert_equal source, spec.source
end
def test_spec
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
a_2 = quick_spec 'a', 2
a_2_p = quick_spec 'a', 2 do |s| s.platform = Gem::Platform.local end
Gem::Specification.add_specs a_2, a_2_p
util_setup_spec_fetcher a_2, a_2_p
source = Gem::Source.new @gem_repo
version = v 2
set = Gem::DependencyResolver::IndexSet.new
i_spec = Gem::DependencyResolver::IndexSpecification.new \
set, 'a', version, source, Gem::Platform.local
spec = i_spec.spec
assert_equal a_2_p.full_name, spec.full_name
end
end

View file

@ -0,0 +1,19 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverInstalledSpecification < Gem::TestCase
def test_initialize
set = Gem::DependencyResolver::CurrentSet.new
source_spec = quick_spec 'a'
spec = Gem::DependencyResolver::InstalledSpecification.new set, source_spec
assert_equal 'a', spec.name
assert_equal Gem::Version.new(2), spec.version
assert_equal Gem::Platform::RUBY, spec.platform
end
end

View file

@ -0,0 +1,28 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverInstallerSet < Gem::TestCase
def test_load_spec
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
a_2 = quick_spec 'a', 2
a_2_p = quick_spec 'a', 2 do |s| s.platform = Gem::Platform.local end
Gem::Specification.add_specs a_2, a_2_p
util_setup_spec_fetcher a_2, a_2_p
source = Gem::Source.new @gem_repo
version = v 2
set = Gem::DependencyResolver::InstallerSet.new :remote
spec = set.load_spec 'a', version, Gem::Platform.local, source
assert_equal a_2_p.full_name, spec.full_name
end
end

View file

@ -101,7 +101,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
def test_sign_in_with_host
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
util_sign_in [api_key, 200, 'OK'], 'http://example.com', :param
util_sign_in [api_key, 200, 'OK'], 'http://example.com', ['http://example.com']
assert_match "Enter your http://example.com credentials.",
@sign_in_ui.output
@ -112,6 +112,20 @@ class TestGemGemcutterUtilities < Gem::TestCase
assert_equal api_key, credentials[:rubygems_api_key]
end
def test_sign_in_with_host_nil
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
util_sign_in [api_key, 200, 'OK'], nil, [nil]
assert_match "Enter your RubyGems.org credentials.",
@sign_in_ui.output
assert @fetcher.last_request["authorization"]
assert_match %r{Signed in.}, @sign_in_ui.output
credentials = YAML.load_file Gem.configuration.credentials_path
assert_equal api_key, credentials[:rubygems_api_key]
end
def test_sign_in_with_host_ENV
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
util_sign_in [api_key, 200, 'OK'], 'http://example.com'
@ -163,14 +177,14 @@ class TestGemGemcutterUtilities < Gem::TestCase
assert_match %r{Access Denied.}, @sign_in_ui.output
end
def util_sign_in response, host = nil, style = :ENV
def util_sign_in response, host = nil, args = []
skip 'Always uses $stdin on windows' if Gem.win_platform?
email = 'you@example.com'
password = 'secret'
if host
ENV['RUBYGEMS_HOST'] = host if style == :ENV
ENV['RUBYGEMS_HOST'] = host
else
host = Gem.host
end
@ -182,8 +196,8 @@ class TestGemGemcutterUtilities < Gem::TestCase
@sign_in_ui = Gem::MockGemUi.new "#{email}\n#{password}\n"
use_ui @sign_in_ui do
if style == :param then
@cmd.sign_in host
if args.length > 0 then
@cmd.sign_in(*args)
else
@cmd.sign_in
end
@ -209,4 +223,3 @@ class TestGemGemcutterUtilities < Gem::TestCase
end
end

View file

@ -168,7 +168,7 @@ class TestGemSpecFetcher < Gem::TestCase
specs, _ = @sf.available_specs(:latest)
assert_equal [@source], specs.keys
assert_equal @latest_specs, specs[@source].sort
assert_equal @latest_specs, specs[@source]
end
def test_available_specs_released
@ -176,7 +176,7 @@ class TestGemSpecFetcher < Gem::TestCase
assert_equal [@source], specs.keys
assert_equal @released, specs[@source].sort
assert_equal @released, specs[@source]
end
def test_available_specs_complete
@ -184,9 +184,9 @@ class TestGemSpecFetcher < Gem::TestCase
assert_equal [@source], specs.keys
comp = @prerelease_specs + @released
expected = (@prerelease_specs + @released).sort
assert_equal comp.sort, specs[@source].sort
assert_equal expected, specs[@source]
end
def test_available_specs_complete_handles_no_prerelease
@ -197,12 +197,9 @@ class TestGemSpecFetcher < Gem::TestCase
assert_equal [@source], specs.keys
comp = @released
assert_equal comp.sort, specs[@source].sort
assert_equal @released, specs[@source]
end
def test_available_specs_cache
specs, _ = @sf.available_specs(:latest)
@ -230,7 +227,7 @@ class TestGemSpecFetcher < Gem::TestCase
def test_available_specs_prerelease
specs, _ = @sf.available_specs(:prerelease)
assert_equal @prerelease_specs, specs[@source].sort
assert_equal @prerelease_specs, specs[@source]
end
def test_available_specs_with_bad_source