Skip to content

Handle escape gem with YAMLSerializer#9399

Merged
hsbt merged 1 commit intomasterfrom
load-old-gem
Mar 17, 2026
Merged

Handle escape gem with YAMLSerializer#9399
hsbt merged 1 commit intomasterfrom
load-old-gem

Conversation

@hsbt
Copy link
Member

@hsbt hsbt commented Mar 16, 2026

What was the end-user or developer problem that led to this PR?

Old gems such as escape use the legacy !ruby/object:Gem::Version::Requirement YAML tag which is an alias for Gem::Requirement. This caused Psych::DisallowedClass errors when installing these gems with the pure Ruby YAML parser.

What is your fix for the problem, implemented in this PR?

Add Gem::Version::Requirement to the Builder's case statement so it is handled by build_requirement

Make sure the following tasks are checked

Copilot AI review requested due to automatic review settings March 16, 2026 07:57
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates RubyGems’ YAML safe-loading behavior/tests to align error types with Psych and to ensure Gem::Version::Requirement tags can be loaded when embedded in gemspec YAML.

Changes:

  • Switch unknown-tag handling from ArgumentError to Psych::DisallowedClass (and refactor into raise_disallowed_class!).
  • Adjust tag validation/permitted-classes handling in Gem::YAMLSerializer::Builder.
  • Add a regression test ensuring Gem::Version::Requirement is accepted in Gem::Specification#required_ruby_version.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
test/rubygems/test_gem_safe_yaml.rb Updates/extends SafeYAML tests for unknown tags and version-requirement tag handling.
lib/rubygems/yaml_serializer.rb Refactors Builder tag validation and error raising behavior for disallowed classes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

else
raise Psych::DisallowedClass, "Tried to load unspecified class: #{tag}"
end
return if @permitted_classes.empty?
Comment on lines +426 to 427
@permitted_classes = permitted_classes.map {|c| "!ruby/object:#{c}" }
@permitted_symbols = permitted_symbols
yaml = "!ruby/object:MyCustomClass\nfoo: bar\n"
assert_raise(ArgumentError) do
assert_raise(Psych::DisallowedClass) do
yaml_load(yaml, permitted_classes: ["MyCustomClass"])
… Psych

Align YAMLSerializer's `permitted_classes` validation with Psych's whitelist
semantics: an empty `permitted_classes` list denies all tagged classes, matching
`Psych::ClassLoader::Restricted` behavior.

- Rename `@permitted_tags` to `@permitted_classes` and simplify initialization
- Extract `raise_disallowed_class!` from `validate_tag!` for clarity
- Move `check_anchor!` before `validate_tag!` in `build_mapping`
- Add test for `Gem::Version::Requirement` tag used by old gems like `escape`

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hsbt hsbt merged commit 99607ea into master Mar 17, 2026
93 checks passed
@hsbt hsbt deleted the load-old-gem branch March 17, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants