summaryrefslogtreecommitdiff
path: root/lib/rubygems/specification.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/specification.rb')
-rw-r--r--lib/rubygems/specification.rb22
1 files changed, 19 insertions, 3 deletions
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index d8a212a04a..56db0945eb 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -1272,10 +1272,26 @@ class Gem::Specification < Gem::BasicSpecification
array = begin
Marshal.load str
rescue ArgumentError => e
- raise unless e.message.include?("YAML")
+ #
+ # Some very old marshaled specs included references to `YAML::PrivateType`
+ # and `YAML::Syck::DefaultKey` constants due to bugs in the old emitter
+ # that generated them. Workaround the issue by defining the necessary
+ # constants and retrying.
+ #
+ message = e.message
+ raise unless message.include?("YAML::")
+
+ Object.const_set "YAML", Psych unless Object.const_defined?(:YAML)
+
+ if message.include?("YAML::Syck::")
+ YAML.const_set "Syck", YAML unless YAML.const_defined?(:Syck)
+
+ YAML::Syck.const_set "DefaultKey", Class.new if message.include?("YAML::Syck::DefaultKey")
+ elsif message.include?("YAML::PrivateType")
+ YAML.const_set "PrivateType", Class.new
+ end
- Object.const_set "YAML", Psych
- Marshal.load str
+ retry
end
spec = Gem::Specification.new