module SafeYAML

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

Constants

DEFAULT_OPTIONS
MULTI_ARGUMENT_YAML_LOAD
OPTIONS
PREDEFINED_TAGS
TRUSTED_TAGS
VERSION
YAML_ENGINE

Public Class Methods

load(yaml, filename=nil, options={}) click to toggle source
# File lib/safe_yaml/load.rb, line 134
def self.load(yaml, filename=nil, options={})
  # If the user hasn't whitelisted any tags, we can go with this implementation which is
  # significantly faster.
  if (options && options[:whitelisted_tags] || SafeYAML::OPTIONS[:whitelisted_tags]).empty?
    safe_handler = SafeYAML::PsychHandler.new(options) do |result|
      return result
    end
    arguments_for_parse = [yaml]
    arguments_for_parse << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
    Psych::Parser.new(safe_handler).parse(*arguments_for_parse)
    return safe_handler.result

  else
    safe_resolver = SafeYAML::PsychResolver.new(options)
    tree = SafeYAML::MULTI_ARGUMENT_YAML_LOAD ?
      Psych.parse(yaml, filename) :
      Psych.parse(yaml)
    return safe_resolver.resolve_node(tree)
  end
end
load_file(filename, options={}) click to toggle source
# File lib/safe_yaml/load.rb, line 155
def self.load_file(filename, options={})
  if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
    File.open(filename, 'r:bom|utf-8') { |f| self.load(f, filename, options) }

  else
    # Ruby pukes on 1.9.2 if we try to open an empty file w/ 'r:bom|utf-8';
    # so we'll not specify those flags here. This mirrors the behavior for
    # unsafe_load_file so it's probably preferable anyway.
    self.load File.open(filename), nil, options
  end
end

Public Instance Methods

restore_defaults!() click to toggle source
# File lib/safe_yaml/load.rb, line 62
def restore_defaults!
  OPTIONS.clear.merge!(Deep.copy(DEFAULT_OPTIONS))
end
tag_is_explicitly_trusted?(tag) click to toggle source
# File lib/safe_yaml/load.rb, line 104
def tag_is_explicitly_trusted?(tag)
  false
end
tag_safety_check!(tag, options) click to toggle source
# File lib/safe_yaml/load.rb, line 66
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) click to toggle source
# File lib/safe_yaml/load.rb, line 73
def whitelist!(*classes)
  classes.each do |klass|
    whitelist_class!(klass)
  end
end
whitelist_class!(klass) click to toggle source
# File lib/safe_yaml/load.rb, line 79
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