Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions lib/rubygems/yaml_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,7 @@ class Builder
MAX_ALIAS_RESOLUTIONS = 1_000

def initialize(permitted_classes: [], permitted_symbols: [], aliases: true)
@permitted_tags = Array(permitted_classes).map do |c|
"!ruby/object:#{c.is_a?(Module) ? c.name : c}"
end
@permitted_classes = permitted_classes.map {|c| "!ruby/object:#{c}" }
@permitted_symbols = permitted_symbols
Comment on lines +426 to 427
@aliases = aliases
@anchor_values = {}
Expand Down Expand Up @@ -474,8 +472,8 @@ def store_anchor(name, value)
end

def build_mapping(node)
validate_tag!(node.tag) if node.tag
check_anchor!(node)
validate_tag!(node.tag) if node.tag

result = case node.tag
when "!ruby/object:Gem::Version"
Expand Down Expand Up @@ -605,12 +603,15 @@ def pairs_to_hash(node)
end

def validate_tag!(tag)
unless @permitted_tags.include?(tag)
if defined?(Psych::VERSION)
raise Psych::DisallowedClass.new("load", tag)
else
raise Psych::DisallowedClass, "Tried to load unspecified class: #{tag}"
end
return if @permitted_classes.include?(tag)
raise_disallowed_class!(tag)
end

def raise_disallowed_class!(tag)
if defined?(Psych::VERSION)
raise Psych::DisallowedClass.new("load", tag)
else
raise Psych::DisallowedClass, "Tried to load unspecified class: #{tag}"
end
end

Expand Down
20 changes: 20 additions & 0 deletions test/rubygems/test_gem_safe_yaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1196,4 +1196,24 @@ def test_binary_tag_decoded_in_sequence_item_inline
result = yaml_load(yaml)
assert_equal ["SHA1"], result
end

def test_version_requirement_tag_always_permitted
yaml = <<~YAML
--- !ruby/object:Gem::Specification
name: escape
version: !ruby/object:Gem::Version
version: 0.0.4
required_ruby_version: !ruby/object:Gem::Version::Requirement
requirements:
- - ">"
- !ruby/object:Gem::Version
version: 0.0.0
version:
YAML

result = yaml_load(yaml)
assert_kind_of Gem::Specification, result
assert_equal "escape", result.name
assert_kind_of Gem::Requirement, result.required_ruby_version
end
end
Loading