Class: Gem::YAMLSerializer::Builder
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | lib/rubygems/yaml_serializer.rb |
Constant Summary
-
ARRAY_FIELDS =
# File 'lib/rubygems/yaml_serializer.rb', line 422%w[files test_files executables extra_rdoc_files].freeze
-
MAX_ALIAS_RESOLUTIONS =
# File 'lib/rubygems/yaml_serializer.rb', line 4231_000 -
PLATFORM_ALLOWED_IVARS =
# File 'lib/rubygems/yaml_serializer.rb', line 521%w[cpu os version value].freeze
-
PLATFORM_FIELDS =
# File 'lib/rubygems/yaml_serializer.rb', line 520%w[cpu os version].freeze
-
VALID_OPS =
# File 'lib/rubygems/yaml_serializer.rb', line 421%w[= != > < >= <= ~>].freeze
Class Method Summary
Instance Method Summary
- #build(node)
- #build_dependency(node) private
- #build_hash(node) private
- #build_mapping(node) private
- #build_node(node) private
- #build_platform(node) private
- #build_requirement(node) private
- #build_specification(hash) private
- #build_version(node) private
- #check_anchor!(node) private
- #normalize_array_field(value) private
- #normalize_array_fields!(hash) private
- #normalize_specification_version!(hash) private
- #pairs_to_hash(node) private
- #raise_disallowed_class!(tag) private
- #resolve_alias(node) private
- #store_anchor(name, value) private
- #validate_symbol!(sym) private
- #validate_tag!(tag) private
Constructor Details
.new(permitted_classes: [], permitted_symbols: [], aliases: true) ⇒ Builder
# File 'lib/rubygems/yaml_serializer.rb', line 425
def initialize(permitted_classes: [], permitted_symbols: [], aliases: true) @permitted_classes = permitted_classes.map {|c| "!ruby/object:#{c}" } @permitted_symbols = permitted_symbols @aliases = aliases @anchor_values = {} @alias_count = 0 end
Instance Method Details
#build(node)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 433
def build(node) return nil 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
#build_dependency(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 569
def build_dependency(node) hash = pairs_to_hash(node) d = Gem::Dependency.allocate d.instance_variable_set(:@name, hash["name"]) d.instance_variable_set(:@requirement, hash["requirement"] || hash["version_requirements"]) 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
#build_hash(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 500
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
#build_mapping(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 474
def build_mapping(node) check_anchor!(node) validate_tag!(node.tag) if node.tag 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) when "!ruby/object:Gem::Specification" hash = build_hash(node) hash[:tag] = node.tag hash else raise ArgumentError, "undefined class/module #{node.tag.sub("!ruby/object:", "")}" end store_anchor(node.anchor, result) end
#build_node(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 449
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
#build_platform(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 523
def build_platform(node) hash = pairs_to_hash(node) if (hash.keys & PLATFORM_FIELDS).any? Gem::Platform.new([hash["cpu"], hash["os"], hash["version"]]) elsif hash["value"].is_a?(Array) # Malformed platform (e.g. sequence instead of mapping). # Return the raw value so yaml_initialize handles it like Psych does. hash["value"] else plat = Gem::Platform.allocate hash.each do |k, v| plat.instance_variable_set(:"@#{k}", v) if PLATFORM_ALLOWED_IVARS.include?(k) end plat end end
#build_requirement(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 540
def build_requirement(node) r = Gem::Requirement.allocate hash = pairs_to_hash(node) reqs = hash["requirements"] || hash["value"] 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
#build_specification(hash) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 586
def build_specification(hash) spec = Gem::Specification.allocate normalize_specification_version!(hash) normalize_array_fields!(hash) spec.yaml_initialize("!ruby/object:Gem::Specification", hash) spec end
#build_version(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 515
def build_version(node) hash = pairs_to_hash(node) Gem::Version.new((hash["version"] || hash["value"]).to_s) end
#check_anchor!(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 628
def check_anchor!(node) if node.anchor raise Psych::AliasesNotEnabled unless @aliases end end
#normalize_array_field(value) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 646
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
#normalize_array_fields!(hash) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 640
def normalize_array_fields!(hash) ARRAY_FIELDS.each do |field| hash[field] = normalize_array_field(hash[field]) if hash[field] end end
#normalize_specification_version!(hash) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 634
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
#pairs_to_hash(node) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 596
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
#raise_disallowed_class!(tag) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 610
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
#resolve_alias(node) (private)
# File 'lib/rubygems/yaml_serializer.rb', line 460
def resolve_alias(node) raise Psych::AliasesNotEnabled unless @aliases @alias_count += 1 if @alias_count > MAX_ALIAS_RESOLUTIONS raise Psych::BadAlias, "exceeded maximum alias resolutions (#{MAX_ALIAS_RESOLUTIONS})" end @anchor_values.fetch(node.name, nil) end
#store_anchor(name, value) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 469
def store_anchor(name, value) @anchor_values[name] = value if name value end
#validate_symbol!(sym) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 618
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
#validate_tag!(tag) (private)
[ GitHub ]# File 'lib/rubygems/yaml_serializer.rb', line 605
def validate_tag!(tag) return if @permitted_classes.include?(tag) raise_disallowed_class!(tag) end