Skip to content

Commit e5bcde3

Browse files
committed
Handle malformed/unknown YAML Platform fields
1 parent 6b0aa2a commit e5bcde3

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/rubygems/yaml_serializer.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,22 @@ def build_version(node)
482482
Gem::Version.new((hash["version"] || hash["value"]).to_s)
483483
end
484484

485+
PLATFORM_FIELDS = %w[cpu os version].freeze
486+
485487
def build_platform(node)
486488
hash = pairs_to_hash(node)
487-
Gem::Platform.new([hash["cpu"], hash["os"], hash["version"]])
489+
if (hash.keys & PLATFORM_FIELDS).any?
490+
Gem::Platform.new([hash["cpu"], hash["os"], hash["version"]])
491+
elsif hash["value"].is_a?(Array)
492+
# Malformed platform (e.g. sequence instead of mapping).
493+
# Return the raw value so yaml_initialize handles it like Psych does.
494+
hash["value"]
495+
else
496+
# Unknown fields: set as instance variables like Psych's init_with
497+
plat = Gem::Platform.allocate
498+
hash.each {|k, v| plat.instance_variable_set(:"@#{k}", v) }
499+
plat
500+
end
488501
end
489502

490503
def build_requirement(node)

test/rubygems/test_gem_safe_yaml.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,14 @@ def test_load_platform_from_cpu_os_version_fields
923923
assert_equal "darwin", plat.os
924924
end
925925

926+
def test_load_platform_malicious_sequence
927+
928+
yaml = "!ruby/object:Gem::Platform\n- \"x86-mswin32\\n system('id')#\"\n"
929+
result = yaml_load(yaml, permitted_classes: Gem::SafeYAML::PERMITTED_CLASSES)
930+
refute_kind_of Gem::Platform, result
931+
assert_kind_of Array, result
932+
end
933+
926934
def test_load_dependency_missing_requirement_uses_default
927935

928936
yaml = <<~YAML

0 commit comments

Comments
 (0)