class Gem::YAMLSerializer::Builder
Constants
- ARRAY_FIELDS
- VALID_OPS
Public Class Methods
Source
# File lib/rubygems/yaml_serializer.rb, line 385 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_symbols = permitted_symbols @aliases = aliases @anchor_values = {} end
Public Instance Methods
Source
# File lib/rubygems/yaml_serializer.rb, line 394 def build(node) return {} if node.nil? result = build_node(node) if result.is_a?(Hash) && (result[:tag] == "!ruby/object:Gem::Specification" || result["tag"] == "!ruby/object:Gem::Specification") build_specification(result) else result end end
Private Instance Methods
Source
# File lib/rubygems/yaml_serializer.rb, line 514 def build_dependency(node) hash = pairs_to_hash(node) d = Gem::Dependency.allocate d.instance_variable_set(:@name, hash["name"]) requirement = build_safe_requirement(hash["requirement"]) d.instance_variable_set(:@requirement, requirement) type = hash["type"] type = type ? type.to_s.sub(/^:/, "").to_sym : :runtime validate_symbol!(type) d.instance_variable_set(:@type, type) d.instance_variable_set(:@prerelease, ["true", true].include?(hash["prerelease"])) d.instance_variable_set(:@version_requirements, d.instance_variable_get(:@requirement)) d end
Source
# File lib/rubygems/yaml_serializer.rb, line 455 def build_hash(node) result = {} node.pairs.each do |key_node, value_node| key = key_node.is_a?(Scalar) ? key_node.value.to_s : build_node(key_node).to_s value = build_node(value_node) if ARRAY_FIELDS.include?(key) value = normalize_array_field(value) end result[key] = value end result end
Source
# File lib/rubygems/yaml_serializer.rb, line 431 def build_mapping(node) validate_tag!(node.tag) if node.tag check_anchor!(node) result = case node.tag when "!ruby/object:Gem::Version" build_version(node) when "!ruby/object:Gem::Platform" build_platform(node) when "!ruby/object:Gem::Requirement", "!ruby/object:Gem::Version::Requirement" build_requirement(node) when "!ruby/object:Gem::Dependency" build_dependency(node) when nil build_hash(node) else hash = build_hash(node) hash[:tag] = node.tag hash end store_anchor(node.anchor, result) end
Source
# File lib/rubygems/yaml_serializer.rb, line 410 def build_node(node) case node when nil then nil when AliasRef then resolve_alias(node) when Scalar then store_anchor(node.anchor, node.value) when Mapping then build_mapping(node) when Sequence then store_anchor(node.anchor, node.items.map {|item| build_node(item) }) else node # already a Ruby object end end
Source
# File lib/rubygems/yaml_serializer.rb, line 475 def build_platform(node) hash = pairs_to_hash(node) if hash["value"] Gem::Platform.new(hash["value"]) else Gem::Platform.new([hash["cpu"], hash["os"], hash["version"]]) end end
Source
# File lib/rubygems/yaml_serializer.rb, line 484 def build_requirement(node) r = Gem::Requirement.allocate hash = pairs_to_hash(node) reqs = hash["requirements"] || hash["value"] reqs = [] unless reqs.is_a?(Array) if reqs.is_a?(Array) && !reqs.empty? safe_reqs = [] reqs.each do |item| if item.is_a?(Array) && item.size == 2 op = item[0].to_s ver = item[1] if VALID_OPS.include?(op) version_obj = ver.is_a?(Gem::Version) ? ver : Gem::Version.new(ver.to_s) safe_reqs << [op, version_obj] end elsif item.is_a?(String) parsed = Gem::Requirement.parse(item) safe_reqs << parsed end rescue Gem::Requirement::BadRequirementError, Gem::Version::BadVersionError # Skip malformed items silently end reqs = safe_reqs unless safe_reqs.empty? end r.instance_variable_set(:@requirements, reqs) r end
Source
# File lib/rubygems/yaml_serializer.rb, line 552 def build_safe_requirement(req_value) return Gem::Requirement.default unless req_value converted = req_value return Gem::Requirement.default unless converted.is_a?(Gem::Requirement) reqs = converted.instance_variable_get(:@requirements) if reqs&.is_a?(Array) valid = reqs.all? do |item| next true if item == Gem::Requirement::DefaultRequirement item.is_a?(Array) && item.size >= 2 && VALID_OPS.include?(item[0].to_s) end valid ? converted : Gem::Requirement.default else converted end rescue StandardError Gem::Requirement.default end
Source
# File lib/rubygems/yaml_serializer.rb, line 532 def build_specification(hash) spec = Gem::Specification.allocate normalize_specification_version!(hash) normalize_rdoc_options!(hash) normalize_array_fields!(hash) spec.yaml_initialize("!ruby/object:Gem::Specification", hash) spec end
Source
# File lib/rubygems/yaml_serializer.rb, line 470 def build_version(node) hash = pairs_to_hash(node) Gem::Version.new((hash["version"] || hash["value"]).to_s) end
Source
# File lib/rubygems/yaml_serializer.rb, line 592 def check_anchor!(node) if node.anchor raise Psych::AliasesNotEnabled unless @aliases end end
Source
# File lib/rubygems/yaml_serializer.rb, line 628 def normalize_array_field(value) if value.is_a?(Hash) value.values.flatten.compact elsif !value.is_a?(Array) && value [value].flatten.compact else value end end
Source
# File lib/rubygems/yaml_serializer.rb, line 621 def normalize_array_fields!(hash) ARRAY_FIELDS.each do |field| next if field == "rdoc_options" # already handled hash[field] = normalize_array_field(hash[field]) if hash[field] end end
Source
# File lib/rubygems/yaml_serializer.rb, line 604 def normalize_rdoc_options!(hash) opts = hash["rdoc_options"] if opts.is_a?(Hash) hash["rdoc_options"] = opts.values.flatten.compact.map(&:to_s) elsif opts.is_a?(Array) hash["rdoc_options"] = opts.flat_map do |opt| if opt.is_a?(Hash) opt.flat_map {|k, v| [k.to_s, v.to_s] } elsif opt.is_a?(String) opt else opt.to_s end end end end
Source
# File lib/rubygems/yaml_serializer.rb, line 598 def normalize_specification_version!(hash) val = hash["specification_version"] return unless val && !val.is_a?(Integer) hash["specification_version"] = val.to_i if val.is_a?(String) && /\A\d+\z/.match?(val) end
Source
# File lib/rubygems/yaml_serializer.rb, line 543 def pairs_to_hash(node) result = {} node.pairs.each do |key_node, value_node| key = key_node.is_a?(Scalar) ? key_node.value.to_s : build_node(key_node).to_s result[key] = build_node(value_node) end result end
Source
# File lib/rubygems/yaml_serializer.rb, line 421 def resolve_alias(node) raise Psych::AliasesNotEnabled unless @aliases @anchor_values.fetch(node.name, nil) end
Source
# File lib/rubygems/yaml_serializer.rb, line 426 def store_anchor(name, value) @anchor_values[name] = value if name value end
Source
# File lib/rubygems/yaml_serializer.rb, line 582 def validate_symbol!(sym) if @permitted_symbols.any? && !@permitted_symbols.include?(sym.to_s) if defined?(Psych::VERSION) raise Psych::DisallowedClass.new("load", sym.inspect) else raise Psych::DisallowedClass, "Tried to load unspecified class: #{sym.inspect}" end end end
Source
# File lib/rubygems/yaml_serializer.rb, line 572 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 end end