Module: SafeYAML

Defined in:
lib/safe_yaml.rb,
lib/safe_yaml.rb,
lib/safe_yaml/deep.rb,
lib/safe_yaml/version.rb,
lib/safe_yaml/resolver.rb,
lib/safe_yaml/transform.rb,
lib/safe_yaml/parse/date.rb,
lib/safe_yaml/psych_handler.rb,
lib/safe_yaml/syck_resolver.rb,
lib/safe_yaml/psych_resolver.rb,
lib/safe_yaml/transform/to_nil.rb,
lib/safe_yaml/parse/hexadecimal.rb,
lib/safe_yaml/parse/sexagesimal.rb,
lib/safe_yaml/transform/to_date.rb,
lib/safe_yaml/transform/to_float.rb,
lib/safe_yaml/transform/to_symbol.rb,
lib/safe_yaml/safe_to_ruby_visitor.rb,
lib/safe_yaml/transform/to_boolean.rb,
lib/safe_yaml/transform/to_integer.rb,
lib/safe_yaml/transform/transformation_map.rb

Overview

This needs to be defined up front in case any internal classes need to base their behavior off of this.

Defined Under Namespace

Classes: Deep, Parse, PsychHandler, PsychResolver, Resolver, SafeToRubyVisitor, SyckResolver, Transform

Constant Summary collapse

YAML_ENGINE =
defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : "syck"
MULTI_ARGUMENT_YAML_LOAD =
YAML.method(:load).arity != 1
DEFAULT_OPTIONS =
Deep.freeze({
  :default_mode         => nil,
  :suppress_warnings    => false,
  :deserialize_symbols  => false,
  :whitelisted_tags     => [],
  :custom_initializers  => {},
  :raise_on_unknown_tag => false
})
OPTIONS =
Deep.copy(DEFAULT_OPTIONS)
TRUSTED_TAGS =
Set.new([
  "tag:yaml.org,2002:binary",
  "tag:yaml.org,2002:bool#no",
  "tag:yaml.org,2002:bool#yes",
  "tag:yaml.org,2002:float",
  "tag:yaml.org,2002:float#fix",
  "tag:yaml.org,2002:int",
  "tag:yaml.org,2002:map",
  "tag:yaml.org,2002:null",
  "tag:yaml.org,2002:seq",
  "tag:yaml.org,2002:str",
  "tag:yaml.org,2002:timestamp",
  "tag:yaml.org,2002:timestamp#ymd"
]).freeze
VERSION =
"0.9.7"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.predefined_tagsObject


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/safe_yaml.rb', line 81

def predefined_tags
  if @predefined_tags.nil?
    @predefined_tags = {}

    if YAML_ENGINE == "syck"
      YAML.tagged_classes.each do |tag, klass|
        @predefined_tags[klass] = tag
      end

    else
      # Special tags appear to be hard-coded in Psych:
      # https://github.com/tenderlove/psych/blob/v1.3.4/lib/psych/visitors/to_ruby.rb
      # Fortunately, there aren't many that SafeYAML doesn't already support.
      @predefined_tags.merge!({
        Exception => "!ruby/exception",
        Range     => "!ruby/range",
        Regexp    => "!ruby/regexp",
      })
    end
  end

  @predefined_tags
end

.restore_defaults!Object


40
41
42
# File 'lib/safe_yaml.rb', line 40

def restore_defaults!
  OPTIONS.clear.merge!(Deep.copy(DEFAULT_OPTIONS))
end

.tag_safety_check!(tag, options) ⇒ Object


44
45
46
47
48
49
# File 'lib/safe_yaml.rb', line 44

def tag_safety_check!(tag, options)
  return if tag.nil? || tag == "!"
  if options[:raise_on_unknown_tag] && !options[:whitelisted_tags].include?(tag) && !tag_is_explicitly_trusted?(tag)
    raise "Unknown YAML tag '#{tag}'"
  end
end

.whitelist!(*classes) ⇒ Object


51
52
53
54
55
# File 'lib/safe_yaml.rb', line 51

def whitelist!(*classes)
  classes.each do |klass|
    whitelist_class!(klass)
  end
end

.whitelist_class!(klass) ⇒ Object


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/safe_yaml.rb', line 57

def whitelist_class!(klass)
  raise "#{klass} not a Class" unless klass.is_a?(::Class)

  klass_name = klass.name
  raise "#{klass} cannot be anonymous" if klass_name.nil? || klass_name.empty?

  # Whitelist any built-in YAML tags supplied by Syck or Psych.
  predefined_tag = predefined_tags[klass]
  if predefined_tag
    OPTIONS[:whitelisted_tags] << predefined_tag
    return
  end

  # Exception is exceptional (har har).
  tag_class  = klass < Exception ? "exception" : "object"

  tag_prefix = case YAML_ENGINE
               when "psych" then "!ruby/#{tag_class}"
               when "syck"  then "tag:ruby.yaml.org,2002:#{tag_class}"
               else raise "unknown YAML_ENGINE #{YAML_ENGINE}"
               end
  OPTIONS[:whitelisted_tags] << "#{tag_prefix}:#{klass_name}"
end

Instance Method Details

#tag_is_explicitly_trusted?(tag) ⇒ Boolean

Returns:

  • (Boolean)

106
107
108
# File 'lib/safe_yaml.rb', line 106

def tag_is_explicitly_trusted?(tag)
  false
end