Report abuse

Index: setup.rb
===================================================================
--- setup.rb	(revision 1423)
+++ setup.rb	(working copy)
@@ -7,6 +7,7 @@

 $:.unshift 'lib'
 require 'rubygems'
+require 'rubygems/source_info_cache'

 require 'fileutils'
 require 'rbconfig'
@@ -100,6 +101,20 @@
   end
 end

+# remove source_cache
+source_cache_path = File.join Gem.dir, 'source_cache'
+if File.writable? source_cache_path then
+  puts "Removing system-wide source cache"
+  rm source_cache_path
+end
+
+user_cache_path = Gem::SourceInfoCache.user_cache_file
+if File.writable? user_cache_path then
+  puts "Removing user source cache"
+  rm user_cache_path
+end
+
+#
 # install RDoc

 gem_doc_dir = File.join Gem.dir, 'doc'
Index: lib/rubygems/specification.rb
===================================================================
--- lib/rubygems/specification.rb	(revision 1423)
+++ lib/rubygems/specification.rb	(working copy)
@@ -58,6 +58,8 @@
         'Now forward-compatible with future versions',
       ],
     }
+    
+    MARSHAL_FIELDS = { 1 => 16, 2 => 16 }

     # ------------------------- Class variables.

@@ -215,10 +217,16 @@

     # Load custom marshal format, re-initializing defaults as needed
     def marshal_load(array)
+      unless array.is_a?(Array) then
+        raise TypeError, "Outdated Gem::Specification marshal format"
+      end
+
       spec_version = array[1]
       current_version = CURRENT_SPECIFICATION_VERSION
-      unless spec_version == current_version
-        raise TypeError, "Outdated Gem::Specification marshal format: #{spec_version} 
+      field_count = MARSHAL_FIELDS[current_version]
+      if field_count.nil? or array.size < field_count then
+        STDERR.puts "loading marshaled specification: #{array.inspect}"
+        raise TypeError, "Outdated Gem::Specification marshal format: #{spec_version} \
           instead of #{current_version}"
       end
       assign_defaults # Set defaults for anything we didn't dump
Index: lib/rubygems/version.rb
===================================================================
--- lib/rubygems/version.rb	(revision 1423)
+++ lib/rubygems/version.rb	(working copy)
@@ -9,6 +9,7 @@
 ##
 # The Version class processes string versions into comparable values
 class Gem::Version
+  MARSHAL_FIELDS = { 1 => 1, 2 => 1 }

   include Comparable

@@ -59,18 +60,22 @@

   # Dump only the raw version string, not the complete object
   def marshal_dump
-    [Gem::Specification::CURRENT_SPECIFICATION_VERSION, @version]
+    [@version]
   end

   # Load custom marshal format
   def marshal_load(array)
-    spec_version = array[0]
+    unless array.is_a?(Array) then
+      raise TypeError, "Outdated Gem::Version marshal format"
+    end
+
     current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
-    unless spec_version == current_version
-      raise TypeError, "Outdated Gem::Version marshal format: #{spec_version} 
-          instead of #{current_version}"
+    field_count = MARSHAL_FIELDS[current_version]
+    if field_count.nil? or array.size < field_count then
+      raise TypeError, "Outdated Gem::Version marshal format: expected
+          #{field_count} fields, got: #{array}"
     end
-    @version = array[1]
+    @version = array[0]
   end

   ##
Index: lib/rubygems/source_info_cache.rb
===================================================================
--- lib/rubygems/source_info_cache.rb	(revision 1423)
+++ lib/rubygems/source_info_cache.rb	(working copy)
@@ -74,24 +74,39 @@
       @cache_data = Marshal.load data

       @cache_data.each do |url, sice|
-        next unless Hash === sice
+        next unless sice.is_a?(Hash)
         @dirty = true
-        if sice.key? 'cache' and sice.key? 'size' and
-           Gem::SourceIndex === sice['cache'] and Numeric === sice['size'] then
-          new_sice = Gem::SourceInfoCacheEntry.new sice['cache'], sice['size']
+        cache = sice['cache']
+        size  = sice['size']
+        if cache.is_a?(Gem::SourceIndex) and size.is_a?(Numeric) then
+          new_sice = Gem::SourceInfoCacheEntry.new cache, size
           @cache_data[url] = new_sice
         else # irreperable, force refetch.
-          sice = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0
-          sice.refresh url # HACK may be unnecessary, see ::cache and #refresh
-          @cache_data[url] = sice
+          reset_cache_for(url)
         end
       end
       @cache_data
-    rescue
-      {}
+    rescue => ex
+      if Gem.configuration.really_verbose
+        say "Exception during cache_data handling: #{ex.class} - #{ex}"
+        say "Cache file was: #{cache_file}"
+        say ex.backtrace.join("\n")
+      end
+      reset_cache_data
     end
   end

+  def reset_cache_for(url)
+    sice = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0
+    sice.refresh url # HACK may be unnecessary, see ::cache and #refresh
+    @cache_data[url] = sice
+    @cache_data
+  end
+
+  def reset_cache_data
+    @cache_data = {}
+  end
+
   # The name of the cache file to be read
   def cache_file
     return @cache_file if @cache_file
Index: lib/rubygems/requirement.rb
===================================================================
--- lib/rubygems/requirement.rb	(revision 1423)
+++ lib/rubygems/requirement.rb	(working copy)
@@ -28,6 +28,8 @@

   OP_RE = /#{OPS.keys.map{ |k| Regexp.quote k }.join '|'}/o

+  MARSHAL_FIELDS = { 1 => 2, 2 => 2 }
+
   ##
   # Factory method to create a Gem::Requirement object.  Input may be a
   # Version, a String, or nil.  Intended to simplify client code.
@@ -82,9 +84,13 @@

   # Load custom marshal format
   def marshal_load(array)
+    unless array.is_a?(Array) then
+      raise TypeError, "Outdated Gem::Requirement marshal format"
+    end
     spec_version = array[0]
     current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
-    unless spec_version == current_version
+    field_count = MARSHAL_FIELDS[current_version]
+    if field_count.nil? or array.size < field_count then
       raise TypeError, "Outdated Gem::Requirement marshal format: #{spec_version} 
           instead of #{current_version}"
     end