ruby-changes:30819
From: drbrain <ko1@a...>
Date: Tue, 10 Sep 2013 09:52:26 +0900 (JST)
Subject: [ruby-changes:30819] drbrain:r42898 (trunk): * lib/rubygems: Update to RubyGems 2.1.0. Fixes CVE-2013-4287.
drbrain 2013-09-10 09:52:14 +0900 (Tue, 10 Sep 2013) New Revision: 42898 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42898 Log: * 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. Added files: trunk/test/rubygems/test_gem_dependency_resolver_api_specification.rb trunk/test/rubygems/test_gem_dependency_resolver_index_set.rb trunk/test/rubygems/test_gem_dependency_resolver_index_specification.rb trunk/test/rubygems/test_gem_dependency_resolver_installed_specification.rb trunk/test/rubygems/test_gem_dependency_resolver_installer_set.rb Modified files: trunk/ChangeLog trunk/lib/rubygems/dependency_resolver/api_specification.rb trunk/lib/rubygems/dependency_resolver/index_set.rb trunk/lib/rubygems/dependency_resolver/index_specification.rb trunk/lib/rubygems/dependency_resolver/installed_specification.rb trunk/lib/rubygems/dependency_resolver/installer_set.rb trunk/lib/rubygems/dependency_resolver.rb trunk/lib/rubygems/gemcutter_utilities.rb trunk/lib/rubygems/request_set.rb trunk/lib/rubygems/spec_fetcher.rb trunk/lib/rubygems/specification.rb trunk/lib/rubygems/test_case.rb trunk/lib/rubygems/version.rb trunk/lib/rubygems.rb trunk/test/rubygems/test_gem.rb trunk/test/rubygems/test_gem_dependency_resolver.rb trunk/test/rubygems/test_gem_gemcutter_utilities.rb trunk/test/rubygems/test_gem_spec_fetcher.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 42897) +++ ChangeLog (revision 42898) @@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Sep 10 09:51:22 2013 Eric Hodel <drbrain@s...> + + * 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@f...> * process.c: Remove spaces between SI prefix and unit to follow Index: lib/rubygems/gemcutter_utilities.rb =================================================================== --- lib/rubygems/gemcutter_utilities.rb (revision 42897) +++ lib/rubygems/gemcutter_utilities.rb (revision 42898) @@ -77,7 +77,8 @@ module Gem::GemcutterUtilities https://github.com/ruby/ruby/blob/trunk/lib/rubygems/gemcutter_utilities.rb#L77 # 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 Index: lib/rubygems/spec_fetcher.rb =================================================================== --- lib/rubygems/spec_fetcher.rb (revision 42897) +++ lib/rubygems/spec_fetcher.rb (revision 42898) @@ -200,8 +200,11 @@ class Gem::SpecFetcher https://github.com/ruby/ruby/blob/trunk/lib/rubygems/spec_fetcher.rb#L200 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 Index: lib/rubygems/dependency_resolver/installed_specification.rb =================================================================== --- lib/rubygems/dependency_resolver/installed_specification.rb (revision 42897) +++ lib/rubygems/dependency_resolver/installed_specification.rb (revision 42898) @@ -26,6 +26,10 @@ class Gem::DependencyResolver::Installed https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/installed_specification.rb#L26 @spec.name end + def platform + @spec.platform + end + def source @source ||= Gem::Source::Installed.new end Index: lib/rubygems/dependency_resolver/index_set.rb =================================================================== --- lib/rubygems/dependency_resolver/index_set.rb (revision 42897) +++ lib/rubygems/dependency_resolver/index_set.rb (revision 42898) @@ -43,9 +43,14 @@ class Gem::DependencyResolver::IndexSet https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/index_set.rb#L43 # 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 ## Index: lib/rubygems/dependency_resolver/index_specification.rb =================================================================== --- lib/rubygems/dependency_resolver/index_specification.rb (revision 42897) +++ lib/rubygems/dependency_resolver/index_specification.rb (revision 42898) @@ -8,6 +8,8 @@ class Gem::DependencyResolver::IndexSpec https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/index_specification.rb#L8 attr_reader :name + attr_reader :platform + attr_reader :source attr_reader :version @@ -39,14 +41,19 @@ class Gem::DependencyResolver::IndexSpec https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/index_specification.rb#L41 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 Index: lib/rubygems/dependency_resolver/installer_set.rb =================================================================== --- lib/rubygems/dependency_resolver/installer_set.rb (revision 42897) +++ lib/rubygems/dependency_resolver/installer_set.rb (revision 42898) @@ -115,9 +115,14 @@ class Gem::DependencyResolver::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/installer_set.rb#L115 # 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 ## Index: lib/rubygems/dependency_resolver/api_specification.rb =================================================================== --- lib/rubygems/dependency_resolver/api_specification.rb (revision 42897) +++ lib/rubygems/dependency_resolver/api_specification.rb (revision 42898) @@ -8,6 +8,7 @@ class Gem::DependencyResolver::APISpecif https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/api_specification.rb#L8 attr_reader :dependencies attr_reader :name + attr_reader :platform attr_reader :set # :nodoc: attr_reader :version @@ -15,6 +16,7 @@ class Gem::DependencyResolver::APISpecif https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/api_specification.rb#L16 @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::APISpecif https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver/api_specification.rb#L27 @set == other.set and @name == other.name and @version == other.version and + @platform == other.platform and @dependencies == other.dependencies end Index: lib/rubygems/request_set.rb =================================================================== --- lib/rubygems/request_set.rb (revision 42897) +++ lib/rubygems/request_set.rb (revision 42898) @@ -28,7 +28,10 @@ class Gem::RequestSet https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set.rb#L28 @always_install = [] @development = false + @requests = [] @soft_missing = false + @sorted = nil + @specs = nil yield self if block_given? end Index: lib/rubygems/specification.rb =================================================================== --- lib/rubygems/specification.rb (revision 42897) +++ lib/rubygems/specification.rb (revision 42898) @@ -34,7 +34,7 @@ class Date; end https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L34 # 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::BasicSpe https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L2097 # 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 Index: lib/rubygems/dependency_resolver.rb =================================================================== --- lib/rubygems/dependency_resolver.rb (revision 42897) +++ lib/rubygems/dependency_resolver.rb (revision 42898) @@ -79,7 +79,9 @@ class Gem::DependencyResolver https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver.rb#L79 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_resolver.rb#L164 # 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. Index: lib/rubygems/version.rb =================================================================== --- lib/rubygems/version.rb (revision 42897) +++ lib/rubygems/version.rb (revision 42898) @@ -147,7 +147,7 @@ class Gem::Version https://github.com/ruby/ruby/blob/trunk/lib/rubygems/version.rb#L147 # 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: ## Index: lib/rubygems/test_case.rb =================================================================== --- lib/rubygems/test_case.rb (revision 42897) +++ lib/rubygems/test_case.rb (revision 42898) @@ -1097,7 +1097,11 @@ Also, a list: https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L1097 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: https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L1114 @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 Index: lib/rubygems.rb =================================================================== --- lib/rubygems.rb (revision 42897) +++ lib/rubygems.rb (revision 42898) @@ -8,7 +8,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L8 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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L315 @paths = nil @user_home = nil Gem::Specification.reset - Gem::Security.reset if const_defined? :Security + Gem::Security.reset if defined?(Gem::Security) end ## Index: test/rubygems/test_gem_dependency_resolver_installer_set.rb =================================================================== --- test/rubygems/test_gem_dependency_resolver_installer_set.rb (revision 0) +++ test/rubygems/test_gem_dependency_resolver_installer_set.rb (revision 42898) @@ -0,0 +1,28 @@ https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_dependency_resolver_installer_set.rb#L1 +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 + Property changes on: test/rubygems/test_gem_dependency_resolver_installer_set.rb ___________________________________________________________________ Added: svn:eol-style + LF Index: test/rubygems/test_gem_spec_fetcher.rb =================================================================== --- test/rubygems/test_gem_spec_fetcher.rb (revision 42897) +++ test/rubygems/test_gem_spec_fetcher.rb (revision 42898) @@ -168,7 +168,7 @@ class TestGemSpecFetcher < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_spec_fetcher.rb#L168 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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_spec_fetcher.rb#L176 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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_spec_fetcher.rb#L184 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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_spec_fetcher.rb#L197 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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_spec_fetcher.rb#L227 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 Index: test/rubygems/test_gem_gemcutter_utilities.rb =================================================================== --- test/rubygems/test_gem_gemcutter_utilities.rb (revision 42897) +++ test/rubygems/test_gem_gemcutter_utilities.rb (revision 42898) @@ -101,7 +101,7 @@ class TestGemGemcutterUtilities < Gem::T https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_gemcutter_utilities.rb#L101 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::T https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_gemcutter_utilities.rb#L112 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::T https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_gemcutter_utilities.rb#L177 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@e...' 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::T https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_gemcutter_utilities.rb#L196 @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::T https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_gemcutter_utilities.rb#L223 end end - Index: test/rubygems/test_gem.rb =================================================================== --- test/rubygems/test_gem.rb (revision 42897) +++ test/rubygems/test_gem.rb (revision 42898) @@ -1183,23 +1183,28 @@ class TestGem < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem.rb#L1183 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 Index: test/rubygems/test_gem_dependency_resolver_api_specification.rb =================================================================== --- test/rubygems/test_gem_dependency_resolver_api_specification.rb (revision 0) +++ test/rubygems/test_gem_dependency_resolver_api_specification.rb (revision 42898) @@ -0,0 +1,33 @@ https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_dependency_resolver_api_specification.rb#L1 +require 'ru (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/