diff --git a/lib/rubygems/yaml_serializer.rb b/lib/rubygems/yaml_serializer.rb index 46e665196b2b..a1d5c94fc5b4 100644 --- a/lib/rubygems/yaml_serializer.rb +++ b/lib/rubygems/yaml_serializer.rb @@ -95,6 +95,25 @@ def parse_node(base_indent) if stripped.start_with?("- ") || stripped == "-" parse_sequence(indent, anchor) + elsif stripped.start_with?("\"") && stripped.end_with?("\"") + # We don't need to care about the following case here: + # 1. "value with comment" # ... + # 2. "key": "value" + # + # 1. must not happen because YAMLSerializer doesn't emit any + # comment. YAMLSerializer parses only YAML that is generated + # by YAMLSerializer. + # + # 2. must not happen because #parse_node isn't used non + # top-level mapping. Non top-level mapping always uses + # #parse_mapping. Top-level mapping never use the '"key": + # "value"' form because all top-level keys + # ("!ruby/object:Gem::Specification"'s keys) are known and + # #emit_specification doesn't quote anything. + parse_plain_scalar(indent, anchor) + elsif stripped.start_with?("'") && stripped.end_with?("'") + # See also the above note for double quotation. + parse_plain_scalar(indent, anchor) elsif stripped =~ MAPPING_KEY_RE && !stripped.start_with?("!ruby/object:") parse_mapping(indent, anchor) elsif stripped.start_with?("!ruby/object:") diff --git a/test/rubygems/test_gem_safe_yaml.rb b/test/rubygems/test_gem_safe_yaml.rb index fbf19776405c..d6fef1d7de9f 100644 --- a/test/rubygems/test_gem_safe_yaml.rb +++ b/test/rubygems/test_gem_safe_yaml.rb @@ -318,6 +318,20 @@ def test_requirements_hash_converted_to_array assert_kind_of Hash, reqs end + def test_requirement_quote + yaml = <<~YAML + requirements: + - "system: arrow-glib>=25.0.0: amazon_linux: arrow-glib-devel" + - 'system: arrow-glib>=25.0.0: fedora: libarrow-glib-devel' + YAML + + expected = [ + "system: arrow-glib>=25.0.0: amazon_linux: arrow-glib-devel", + "system: arrow-glib>=25.0.0: fedora: libarrow-glib-devel", + ] + assert_equal expected, yaml_load(yaml)["requirements"] + end + def test_rdoc_options_hash_converted_to_array # Some gemspecs incorrectly have rdoc_options: {} instead of rdoc_options: [] yaml = <<~YAML