Method: Psych.safe_load

Defined in:
lib/psych.rb

.safe_load(yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false) ⇒ Object

Safely load the yaml string in yaml. By default, only the following classes are allowed to be deserialized:

  • TrueClass

  • FalseClass

  • NilClass

  • Integer

  • Float

  • String

  • Array

  • Hash

Recursive data structures are not allowed by default. Arbitrary classes can be allowed by adding those classes to the permitted_classes keyword argument. They are additive. For example, to allow Date deserialization:

Psych.safe_load(yaml, permitted_classes: [Date])

Now the Date class can be loaded in addition to the classes listed above.

Aliases can be explicitly allowed by changing the aliases keyword argument. For example:

x = []
x << x
yaml = Psych.dump x
Psych.safe_load yaml               # => raises an exception
Psych.safe_load yaml, aliases: true # => loads the aliases

A Psych::DisallowedClass exception will be raised if the yaml contains a class that isn’t in the permitted_classes list.

A Psych::AliasesNotEnabled exception will be raised if the yaml contains aliases but the aliases keyword argument is set to false.

filename will be used in the exception message if any exception is raised while parsing.

When the optional symbolize_names keyword argument is set to a true value, returns symbols for keys in Hash objects (default: strings).

Psych.safe_load("---\n foo: bar")                         # => {"foo"=>"bar"}
Psych.safe_load("---\n foo: bar", symbolize_names: true)  # => {:foo=>"bar"}


324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/psych.rb', line 324

def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
  result = parse(yaml, filename: filename)
  return fallback unless result

  class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s),
                                             permitted_symbols.map(&:to_s))
  scanner      = ScalarScanner.new class_loader, strict_integer: strict_integer
  visitor = if aliases
              Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
            else
              Visitors::NoAliasRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
            end
  result = visitor.accept result
  result
end