Gem::YAMLSerializer may not roundtrip metadata
RubyGems
### Describe the problem as clearly as you can
We can specify any valid UTF-8 128 bytes key and 1024 bytes value as metadata:
https://guides.rubygems.org/specification-reference/#metadata
For example, all of the following cases are valid:
* `spec.metadata["have space"] = "space value"`
* `spec.metadata["have:colon"] = "colon:value"`
* `spec.metadata["\"double_quoted\""] = "\"quoted_value\""`
* `spec.metadata["'single_quoted'"] = "'quoted_value'"`
These quoted patterns can't be roundtrip with The current `Gem::YAMLSerializer`:
```diff
diff --git a/test/rubygems/test_gem_safe_yaml.rb b/test/rubygems/test_gem_safe_yaml.rb
index d6fef1d7de..4aa5dbff72 100644
--- a/test/rubygems/test_gem_safe_yaml.rb
+++ b/test/rubygems/test_gem_safe_yaml.rb
@@ -648,6 +648,10 @@ def test_roundtrip_specification_with_metadata
"source_code_uri" => "https://github.com/example/metadata-test",
"bug_tracker_uri" => "https://github.com/example/metadata-test/issues",
"allowed_push_host" => "https://rubygems.org",
+ "\"double_quoted\"" => "\"quoted_value\"",
+ "'single_quoted'" => "'quoted_value'",
+ "have:colon" => "value:colon",
+ "have space" => "value space",
}
end
@@ -655,12 +659,17 @@ def test_roundtrip_specification_with_metadata
loaded = Gem::SafeYAML.safe_load(yaml)
assert_kind_of Gem::Specification, loaded
- assert_kind_of Hash, loaded.metadata
- assert_equal 4, loaded.metadata.size
- assert_equal "https://example.com/CHANGELOG.md", loaded.metadata["changelog_uri"]
- assert_equal "https://github.com/example/metadata-test", loaded.metadata["source_code_uri"]
- assert_equal "https://github.com/example/metadata-test/issues", loaded.metadata["bug_tracker_uri"]
- assert_equal "https://rubygems.org", loaded.metadata["allowed_push_host"]
+ expected_metadata = {
+ "changelog_uri" => "https://example.com/CHANGELOG.md",
+ "source_code_uri" => "https://github.com/example/metadata-test",
+ "bug_tracker_uri" => "https://github.com/example/metadata-test/issues",
+ "allowed_push_host" => "https://rubygems.org",
+ "\"double_quoted\"" => "\"quoted_value\"",
+ "'single_quoted'" => "'quoted_value'",
+ "have:colon" => "value:colon",
+ "have space" => "value space",
+ }
+ assert_equal expected_metadata, loaded.metadata
end
def test_roundtrip_version
```
```text
Failure: test_roundtrip_specification_with_metadata(TestGemSafeYAML)
test/rubygems/test_gem_safe_yaml.rb:673:in 'TestGemSafeYAML#test_roundtrip_specification_with_metadata'
<{"\"double_quoted\""=>"\"quoted_value\"",
"'single_quoted'"=>"'quoted_value'",
"allowed_push_host"=>"https://rubygems.org",
"bug_tracker_uri"=>"https://github.com/example/metadata-test/issues",
"changelog_uri"=>"https://example.com/CHANGELOG.md",
"have space"=>"value space",
"have:colon"=>"value:colon",
"source_code_uri"=>"https://github.com/example/metadata-test"}> expected but was
<{"\"double_quoted\""=>"quoted_value",
"'single_quoted'"=>"quoted_value",
"allowed_push_host"=>"https://rubygems.org",
"bug_tracker_uri"=>"https://github.com/example/metadata-test/issues",
"changelog_uri"=>"https://example.com/CHANGELOG.md",
"have space"=>"value space",
"have:colon"=>"value:colon",
"source_code_uri"=>"https://github.com/example/metadata-test"}>
diff:
? {"\"double_quoted\""=>"\"quoted_value\"",
? "'single_quoted'"=>"'quoted_value'",
"allowed_push_host"=>"https://rubygems.org",
"bug_tracker_uri"=>"https://github.com/example/metadata-test/issues",
"changelog_uri"=>"https://example.com/CHANGELOG.md",
"have space"=>"value space",
"have:colon"=>"value:colon",
"source_code_uri"=>"https://github.com/example/metadata-test"}
```
(Quotations (`"` and `'`) are missing for `quoted_value`.)
### Did you try upgrading RubyGems?
Yes.
### Post steps to reproduce the problem
Use the above diff.
### Which command did you run?
None.
### What were you expecting to happen?
Quoted values can be roundtrip.
### What actually happened?
Quotations in value are missing.
### Run `gem env` and paste the output below
```text
RubyGems Environment:
- RUBYGEMS VERSION: 4.1.0.dev
- RUBY VERSION: 4.1.0 (2026-05-02 patchlevel -1) [x86_64-linux]
- INSTALLATION DIRECTORY: /var/tmp/local/lib/ruby/gems/4.1.0+1
- USER INSTALLATION DIRECTORY: /home/kou/.gem/ruby/4.1.0+1
- CREDENTIALS FILE: /home/kou/.gem/credentials
- RUBYGEMS PREFIX: /home/kou/work/ruby/rubygems
- RUBY EXECUTABLE: /var/tmp/local/bin/ruby
- GIT EXECUTABLE: /bin/git
- EXECUTABLE DIRECTORY: /var/tmp/local/bin
- SPEC CACHE DIRECTORY: /home/kou/.cache/gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /var/tmp/local/etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux
- GEM PATHS:
- /var/tmp/local/lib/ruby/gems/4.1.0+1
- /home/kou/.gem/ruby/4.1.0+1
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => true
- :bulk_threshold => 1000
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /var/tmp/local/bin
- /bin
- /usr/local/bin
- /usr/bin
- /usr/games
```
0 条评论