[前][次][番号順一覧][スレッド一覧]

ruby-changes:21025

From: drbrain <ko1@a...>
Date: Fri, 26 Aug 2011 10:11:03 +0900 (JST)
Subject: [ruby-changes:21025] drbrain:r33074 (trunk): * lib/rubygems: Update to RubyGems 1.8.10. Fixes security issue in

drbrain	2011-08-26 10:10:50 +0900 (Fri, 26 Aug 2011)

  New Revision: 33074

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33074

  Log:
    * lib/rubygems:  Update to RubyGems 1.8.10.  Fixes security issue in
      creating ruby-format gemspecs.  Fixes Gem.dir not being at the front
      of Gem.path to fix uninstall and cleanup commands.  Fixes gem
      uninstall stopping on the first missing gem.

  Modified files:
    trunk/ChangeLog
    trunk/lib/rubygems/commands/uninstall_command.rb
    trunk/lib/rubygems/path_support.rb
    trunk/lib/rubygems/requirement.rb
    trunk/lib/rubygems/specification.rb
    trunk/lib/rubygems.rb
    trunk/test/rubygems/test_gem.rb
    trunk/test/rubygems/test_gem_commands_specification_command.rb
    trunk/test/rubygems/test_gem_commands_uninstall_command.rb
    trunk/test/rubygems/test_gem_gem_runner.rb
    trunk/test/rubygems/test_gem_path_support.rb
    trunk/test/rubygems/test_gem_specification.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33073)
+++ ChangeLog	(revision 33074)
@@ -1,3 +1,10 @@
+Fri Aug 26 10:10:37 2011  Eric Hodel  <drbrain@s...>
+
+	* lib/rubygems:  Update to RubyGems 1.8.10.  Fixes security issue in
+	  creating ruby-format gemspecs.  Fixes Gem.dir not being at the front
+	  of Gem.path to fix uninstall and cleanup commands.  Fixes gem
+	  uninstall stopping on the first missing gem.
+
 Fri Aug 26 08:21:10 2011  Aaron Patterson <aaron@t...>
 
 	* time.c (strftimev): Make Time#to_s default to US-ASCII encoding but
Index: lib/rubygems/path_support.rb
===================================================================
--- lib/rubygems/path_support.rb	(revision 33073)
+++ lib/rubygems/path_support.rb	(revision 33074)
@@ -1,5 +1,4 @@
 ##
-#
 # Gem::PathSupport facilitates the GEM_HOME and GEM_PATH environment settings
 # to the rest of RubyGems.
 #
@@ -43,18 +42,16 @@
   # Set the Gem search path (as reported by Gem.path).
 
   def path=(gpaths)
-    # FIX: it should be [home, *path], not [*path, home]
+    gem_path = [@home]
 
-    gem_path = []
-
     # FIX: I can't tell wtf this is doing.
     gpaths ||= (ENV['GEM_PATH'] || "").empty? ? nil : ENV["GEM_PATH"]
 
-    if gpaths
-      if gpaths.kind_of?(Array)
-        gem_path = gpaths.dup
+    if gpaths then
+      if gpaths.kind_of?(Array) then
+        gem_path.push(*gpaths)
       else
-        gem_path = gpaths.split(File::PATH_SEPARATOR)
+        gem_path.push(*gpaths.split(File::PATH_SEPARATOR))
       end
 
       if File::ALT_SEPARATOR then
@@ -62,14 +59,10 @@
           this_path.gsub File::ALT_SEPARATOR, File::SEPARATOR
         end
       end
-
-      gem_path << @home
     else
-      gem_path = Gem.default_path + [@home]
+      gem_path.push(*Gem.default_path)
 
-      if defined?(APPLE_GEM_HOME)
-        gem_path << APPLE_GEM_HOME
-      end
+      gem_path << APPLE_GEM_HOME if defined?(APPLE_GEM_HOME)
     end
 
     @path = gem_path.uniq
Index: lib/rubygems/specification.rb
===================================================================
--- lib/rubygems/specification.rb	(revision 33073)
+++ lib/rubygems/specification.rb	(revision 33074)
@@ -1459,7 +1459,7 @@
     # TODO: do we need these?? Kill it
     glob = File.join(self.lib_dirs_glob, glob)
 
-    Dir[glob].map { |f| f.untaint } # FIX our tests are brokey, run w/ SAFE=1
+    Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1
   end
 
   ##
@@ -1690,11 +1690,11 @@
 
   def ruby_code(obj)
     case obj
-    when String            then '%q{' + obj + '}'
+    when String            then obj.dump
     when Array             then '[' + obj.map { |x| ruby_code x }.join(", ") + ']'
-    when Gem::Version      then obj.to_s.inspect
-    when Date              then '%q{' + obj.strftime('%Y-%m-%d') + '}'
-    when Time              then '%q{' + obj.strftime('%Y-%m-%d') + '}'
+    when Gem::Version      then obj.to_s.dump
+    when Date              then obj.strftime('%Y-%m-%d').dump
+    when Time              then obj.strftime('%Y-%m-%d').dump
     when Numeric           then obj.inspect
     when true, false, nil  then obj.inspect
     when Gem::Platform     then "Gem::Platform.new(#{obj.to_a.inspect})"
Index: lib/rubygems/commands/uninstall_command.rb
===================================================================
--- lib/rubygems/commands/uninstall_command.rb	(revision 33073)
+++ lib/rubygems/commands/uninstall_command.rb	(revision 33074)
@@ -78,6 +78,8 @@
     get_all_gem_names.each do |gem_name|
       begin
         Gem::Uninstaller.new(gem_name, options).uninstall
+      rescue Gem::InstallError => e
+        alert e.message
       rescue Gem::GemNotInHomeException => e
         spec = e.spec
         alert("In order to remove #{spec.name}, please execute:\n" \
Index: lib/rubygems/requirement.rb
===================================================================
--- lib/rubygems/requirement.rb	(revision 33073)
+++ lib/rubygems/requirement.rb	(revision 33074)
@@ -16,6 +16,9 @@
   if !defined? Syck
     module Syck
       class DefaultKey
+        def to_s
+          '='
+        end
       end
     end
   end
Index: lib/rubygems.rb
===================================================================
--- lib/rubygems.rb	(revision 33073)
+++ lib/rubygems.rb	(revision 33074)
@@ -118,7 +118,7 @@
 # -The RubyGems Team
 
 module Gem
-  VERSION = '1.8.9'
+  VERSION = '1.8.10'
 
   ##
   # Raised when RubyGems is unable to load or activate a gem.  Contains the
@@ -644,7 +644,15 @@
 
   def self.load_yaml
     begin
-      require 'psych'
+      gem 'psych', '~> 1.2', '>= 1.2.1' unless ENV['TEST_SYCK']
+    rescue Gem::LoadError
+      # It's OK if the user does not have the psych gem installed.  We will
+      # attempt to require the stdlib version
+    end
+
+    begin
+      # Try requiring the gem version *or* stdlib version of psych.
+      require 'psych' unless ENV['TEST_SYCK']
     rescue ::LoadError
     ensure
       require 'yaml'
Index: test/rubygems/test_gem_path_support.rb
===================================================================
--- test/rubygems/test_gem_path_support.rb	(revision 33073)
+++ test/rubygems/test_gem_path_support.rb	(revision 33074)
@@ -22,10 +22,10 @@
   def test_initialize_home
     ps = Gem::PathSupport.new "GEM_HOME" => "#{@tempdir}/foo"
 
-    assert_equal File.join(@tempdir, "foo"), ps.home
+    expected = File.join(@tempdir, "foo")
+    assert_equal expected, ps.home
 
-    expected = util_path + [File.join(@tempdir, 'foo')]
-    assert_equal expected, ps.path
+    assert_equal [expected, *util_path], ps.path
   end
 
   if defined?(File::ALT_SEPARATOR) and File::ALT_SEPARATOR
@@ -43,9 +43,9 @@
     assert_equal ENV["GEM_HOME"], ps.home
 
     expected = [
+                ENV["GEM_HOME"],
                 File.join(@tempdir, 'foo'),
                 File.join(@tempdir, 'bar'),
-                ENV["GEM_HOME"],
                ]
 
     assert_equal expected, ps.path
@@ -61,6 +61,32 @@
     assert_equal expected, ps.path
   end
 
+  def test_path_equals
+    ps = Gem::PathSupport.new
+
+    ps.send :path=, ['a', 'b']
+
+    assert_equal [@tempdir, 'a', 'b'], ps.path
+  end
+
+  def test_path_equals_empty
+    ps = Gem::PathSupport.new
+
+    ps.send :path=, nil
+
+    assert_equal [@tempdir, 'something'], ps.path
+  end
+
+  def test_path_equals_empty_no_GEM_PATH
+    ENV.delete 'GEM_PATH'
+
+    ps = Gem::PathSupport.new
+
+    ps.send :path=, nil
+
+    assert_equal [@tempdir, *Gem.default_path], ps.path
+  end
+
   def util_path
     ENV["GEM_PATH"].split(File::PATH_SEPARATOR)
   end
Index: test/rubygems/test_gem_commands_uninstall_command.rb
===================================================================
--- test/rubygems/test_gem_commands_uninstall_command.rb	(revision 33073)
+++ test/rubygems/test_gem_commands_uninstall_command.rb	(revision 33074)
@@ -45,6 +45,19 @@
     assert_includes output, "Successfully uninstalled #{@other.full_name}"
   end
 
+  def test_execute_mulitple_nonexistent
+    @cmd.options[:args] = %w[x y]
+
+    use_ui @ui do
+      @cmd.execute
+    end
+
+    output = @ui.output.split "\n"
+
+    assert_includes output, 'INFO:  gem "x" is not installed'
+    assert_includes output, 'INFO:  gem "y" is not installed'
+  end
+
   def test_execute_removes_executable
     ui = Gem::MockGemUi.new
     util_setup_gem ui
Index: test/rubygems/test_gem_gem_runner.rb
===================================================================
--- test/rubygems/test_gem_gem_runner.rb	(revision 33073)
+++ test/rubygems/test_gem_gem_runner.rb	(revision 33074)
@@ -25,7 +25,7 @@
     gr = Gem::GemRunner.new
     gr.send :do_configuration, %W[--config-file #{temp_conf}]
 
-    assert_equal [other_gem_path, other_gem_home], Gem.path
+    assert_equal [other_gem_home, other_gem_path], Gem.path
     assert_equal %w[--commands], Gem::Command.extra_args
     assert_equal %w[--all], Gem::DocManager.configured_args
   end
Index: test/rubygems/test_gem.rb
===================================================================
--- test/rubygems/test_gem.rb	(revision 33073)
+++ test/rubygems/test_gem.rb	(revision 33074)
@@ -733,7 +733,7 @@
 
     Gem.instance_variable_set :@paths, nil
 
-    assert_equal [Gem.default_path, Gem.dir].flatten.uniq, Gem.path
+    assert_equal [Gem.dir, *Gem.default_path].uniq, Gem.path
   ensure
     Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME if orig_APPLE_GEM_HOME
   end
@@ -772,11 +772,10 @@
 
     ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR)
 
-    assert_equal @additional, Gem.path[0,2]
+    assert_equal [Gem.dir, *@additional], Gem.path
 
     assert_equal path_count + @additional.size, Gem.path.size,
                  "extra path components: #{Gem.path[2..-1].inspect}"
-    assert_equal Gem.dir, Gem.path.last
   end
 
   def test_self_path_duplicate
@@ -789,8 +788,7 @@
 
     assert_equal @gemhome, Gem.dir
 
-    paths = [Gem.dir]
-    assert_equal @additional + paths, Gem.path
+    assert_equal [Gem.dir, *@additional], Gem.path
   end
 
   def test_self_path_overlap
@@ -802,8 +800,7 @@
 
     assert_equal @gemhome, Gem.dir
 
-    paths = [Gem.dir]
-    assert_equal @additional + paths, Gem.path
+    assert_equal [Gem.dir, *@additional], Gem.path
   end
 
   def test_self_platforms
@@ -923,7 +920,7 @@
     ENV["GEM_HOME"] = @gemhome
     Gem.paths = { "GEM_PATH" => path }
 
-    assert_equal [@userhome, other, @gemhome], Gem.path
+    assert_equal [@gemhome, @userhome, other], Gem.path
   end
 
   def test_self_paths_eq_nonexistent_home
@@ -936,7 +933,7 @@
 
     Gem.paths = { "GEM_PATH" => other }
 
-    assert_equal [other, @gemhome], Gem.path
+    assert_equal [@gemhome, other], Gem.path
   end
 
   def test_self_source_index
@@ -983,7 +980,7 @@
     Gem.use_paths @gemhome, @additional
 
     assert_equal @gemhome, Gem.dir
-    assert_equal @additional + [Gem.dir], Gem.path
+    assert_equal [Gem.dir, *@additional], Gem.path
   end
 
   def test_self_user_dir
Index: test/rubygems/test_gem_commands_specification_command.rb
===================================================================
--- test/rubygems/test_gem_commands_specification_command.rb	(revision 33073)
+++ test/rubygems/test_gem_commands_specification_command.rb	(revision 33074)
@@ -135,7 +135,7 @@
     end
 
     assert_match %r|Gem::Specification.new|, @ui.output
-    assert_match %r|s.name = %q\{foo\}|, @ui.output
+    assert_match %r|s.name = "foo"|, @ui.output
     assert_equal '', @ui.error
   end
 
Index: test/rubygems/test_gem_specification.rb
===================================================================
--- test/rubygems/test_gem_specification.rb	(revision 33073)
+++ test/rubygems/test_gem_specification.rb	(revision 33074)
@@ -114,7 +114,7 @@
     assert_equal @current_version, new_spec.specification_version
   end
 
-  def test_self_from_yaml_syck_bug
+  def test_self_from_yaml_syck_date_bug
     # This is equivalent to (and totally valid) psych 1.0 output and
     # causes parse errors on syck.
     yaml = @a1.to_yaml
@@ -128,6 +128,41 @@
     assert_kind_of Time, new_spec.date
   end
 
+  def test_self_from_yaml_syck_default_key_bug
+    skip 'syck default_key bug is only for ruby 1.8' unless RUBY_VERSION < '1.9'
+    # This is equivalent to (and totally valid) psych 1.0 output and
+    # causes parse errors on syck.
+    yaml = <<-YAML
+--- !ruby/object:Gem::Specification
+name: posix-spawn
+version: !ruby/object:Gem::Version
+  version: 0.3.6
+  prerelease: 
+dependencies:
+- !ruby/object:Gem::Dependency
+  name: rake-compiler
+  requirement: &70243867725240 !ruby/object:Gem::Requirement
+    none: false
+    requirements:
+    - - =
+      - !ruby/object:Gem::Version
+        version: 0.7.6
+  type: :development
+  prerelease: false
+  version_requirements: *70243867725240
+platform: ruby
+files: []
+test_files: []
+bindir:
+    YAML
+
+    new_spec = with_syck do
+      Gem::Specification.from_yaml yaml
+    end
+
+    refute_match %r%DefaultKey%, new_spec.to_ruby
+  end
+
   def test_self_load
     full_path = @a2.spec_file
     write_file full_path do |io|
@@ -141,6 +176,51 @@
     assert_equal @a2, spec
   end
 
+  def test_self_load_escape_curly
+    @a2.name = 'a};raise "improper escaping";%q{'
+
+    full_path = @a2.spec_file
+    write_file full_path do |io|
+      io.write @a2.to_ruby_for_cache
+    end
+
+    spec = Gem::Specification.load full_path
+
+    @a2.files.clear
+
+    assert_equal @a2, spec
+  end
+
+  def test_self_load_escape_interpolation
+    @a2.name = 'a#{raise %<improper escaping>}'
+
+    full_path = @a2.spec_file
+    write_file full_path do |io|
+      io.write @a2.to_ruby_for_cache
+    end
+
+    spec = Gem::Specification.load full_path
+
+    @a2.files.clear
+
+    assert_equal @a2, spec
+  end
+
+  def test_self_load_escape_quote
+    @a2.name = 'a";raise "improper escaping";"'
+
+    full_path = @a2.spec_file
+    write_file full_path do |io|
+      io.write @a2.to_ruby_for_cache
+    end
+
+    spec = Gem::Specification.load full_path
+
+    @a2.files.clear
+
+    assert_equal @a2, spec
+  end
+
   def test_self_load_legacy_ruby
     spec = Deprecate.skip_during do
       eval LEGACY_RUBY_SPEC
@@ -754,19 +834,19 @@
 # -*- encoding: utf-8 -*-
 
 Gem::Specification.new do |s|
-  s.name = %q{a}
-  s.version = \"2\"
+  s.name = "a"
+  s.version = "2"
 
   s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version=
-  s.authors = [%q{A User}]
-  s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
-  s.description = %q{This is a test description}
-  s.email = %q{example@e...}
-  s.files = [%q{lib/code.rb}]
-  s.homepage = %q{http://example.com}
-  s.require_paths = [%q{lib}]
-  s.rubygems_version = %q{#{Gem::VERSION}}
-  s.summary = %q{this is a summary}
+  s.authors = ["A User"]
+  s.date = "#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}"
+  s.description = "This is a test description"
+  s.email = "example@e..."
+  s.files = ["lib/code.rb"]
+  s.homepage = "http://example.com"
+  s.require_paths = ["lib"]
+  s.rubygems_version = "#{Gem::VERSION}"
+  s.summary = "this is a summary"
 
   if s.respond_to? :specification_version then
     s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
@@ -801,18 +881,18 @@
 # -*- encoding: utf-8 -*-
 
 Gem::Specification.new do |s|
-  s.name = %q{a}
-  s.version = \"2\"
+  s.name = "a"
+  s.version = "2"
 
   s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version=
-  s.authors = [%q{A User}]
-  s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
-  s.description = %q{This is a test description}
-  s.email = %q{example@e...}
-  s.homepage = %q{http://example.com}
-  s.require_paths = [%q{lib}]
-  s.rubygems_version = %q{#{Gem::VERSION}}
-  s.summary = %q{this is a summary}
+  s.authors = ["A User"]
+  s.date = "#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}"
+  s.description = "This is a test description"
+  s.email = "example@e..."
+  s.homepage = "http://example.com"
+  s.require_paths = ["lib"]
+  s.rubygems_version = "#{Gem::VERSION}"
+  s.summary = "this is a summary"
 
   if s.respond_to? :specification_version then
     s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
@@ -848,26 +928,26 @@
 # -*- encoding: utf-8 -*-
 
 Gem::Specification.new do |s|
-  s.name = %q{a}
-  s.version = \"1\"
+  s.name = "a"
+  s.version = "1"
   s.platform = Gem::Platform.new(#{expected_platform})
 
   s.required_rubygems_version = Gem::Requirement.new(\">= 0\") if s.respond_to? :required_rubygems_version=
-  s.authors = [%q{A User}]
-  s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
-  s.description = %q{This is a test description}
-  s.email = %q{example@e...}
-  s.executables = [%q{exec}]
-  s.extensions = [%q{ext/a/extconf.rb}]
-  s.files = [%q{lib/code.rb}, %q{test/suite.rb}, %q{bin/exec}, %q{ext/a/extconf.rb}]
-  s.homepage = %q{http://example.com}
-  s.licenses = [%q{MIT}]
-  s.require_paths = [%q{lib}]
-  s.requirements = [%q{A working computer}]
-  s.rubyforge_project = %q{example}
-  s.rubygems_version = %q{#{Gem::VERSION}}
-  s.summary = %q{this is a summary}
-  s.test_files = [%q{test/suite.rb}]
+  s.authors = ["A User"]
+  s.date = "#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}"
+  s.description = "This is a test description"
+  s.email = "example@e..."
+  s.executables = ["exec"]
+  s.extensions = ["ext/a/extconf.rb"]
+  s.files = ["lib/code.rb", "test/suite.rb", "bin/exec", "ext/a/extconf.rb"]
+  s.homepage = "http://example.com"
+  s.licenses = ["MIT"]
+  s.require_paths = ["lib"]
+  s.requirements = ["A working computer"]
+  s.rubyforge_project = "example"
+  s.rubygems_version = "#{Gem::VERSION}"
+  s.summary = "this is a summary"
+  s.test_files = ["test/suite.rb"]
 
   if s.respond_to? :specification_version then
     s.specification_version = 3

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]