diff options
| author | Samuel Giddins <segiddins@segiddins.me> | 2023-08-17 15:38:53 -0700 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2023-08-20 09:05:17 +0000 |
| commit | 1935433f5f6fecc786955dcf80e8f65ada6bcaeb (patch) | |
| tree | 89dbdd575507c83e6c0cb6803af1d60995424be5 /lib | |
| parent | f69f775f243ba2036b1b24a2beda1ca932040982 (diff) | |
[rubygems/rubygems] Ensure that loading multiple gemspecs with legacy YAML class references does not warn
Before this, you would get constant redefinition warnings on Psych::DefaultKey
Additionally, ensure the retries wont continue infinitely in the case of the ArgumentError not being caused by Marshal trying to load the undefined classes
https://github.com/rubygems/rubygems/commit/919e8c2de4
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/rubygems/specification.rb | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 3f132b6f2b..005d2ab797 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -1302,10 +1302,20 @@ class Gem::Specification < Gem::BasicSpecification Gem.load_yaml yaml_set = false + retry_count = 0 array = begin Marshal.load str rescue ArgumentError => e + # Avoid an infinite retry loop when the argument error has nothing to do + # with the classes not being defined. + # 1 retry each allowed in case all 3 of + # - YAML + # - YAML::Syck::DefaultKey + # - YAML::Private type + # need to be defined + raise if retry_count >= 3 + # # Some very old marshaled specs included references to `YAML::PrivateType` # and `YAML::Syck::DefaultKey` constants due to bugs in the old emitter @@ -1323,11 +1333,12 @@ class Gem::Specification < Gem::BasicSpecification 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::Syck.const_set "DefaultKey", Class.new if message.include?("YAML::Syck::DefaultKey") && !YAML::Syck.const_defined?(:DefaultKey) + elsif message.include?("YAML::PrivateType") && !YAML.const_defined?(:PrivateType) YAML.const_set "PrivateType", Class.new end + retry_count += 1 retry ensure Object.__send__(:remove_const, "YAML") if yaml_set |
