Posted 11 days ago. Visible to the public.

Ruby: The YAML safe_load method hides some pitfalls

The Ruby standard lib ships with a YAML Parser called Psych. But serializing and deserializing data seems not as obvious as if you are using JSON.

To safely write and read YAML files you should use Psych#dump (String#to_yaml) and Psych.safe_load (YAML.safe_load):

Copy
data = {'key' => 'value'}.to_yaml => "---\nkey: value\n" YAML.safe_load(data) => {"key"=>"value"}

Unfortunately you might encounter a few pitfalls which are not obvious in the first place. All of them are a side effect that you can not configure Psych#dump to write save data.

Pitfall 1: Psych::DisallowedClass

Psych#safe_load only whitelists the following classes: TrueClass, FalseClass, NilClass, Numeric, String, Array and Hash. All other classes will raise an exception unless you whitelist them. Maybe it is a good idea to add Symbol, Date and Time to that list, but other classes could also make sense.

Copy
data = {foo: 'bar'}.to_yaml ::YAML.safe_load(data) Psych::DisallowedClass: Tried to load unspecified class: Symbol ::YAML.safe_load(data, [Symbol]) => {:foo=>"bar"}

Pitfall 2: Psych::BadAlias

Psych#dump will create aliases if you reference the same object more than one time. By default this is disabled by Psych#safe_load. If you use the default whitelist you will not encounter the issue, but for "more complex" classes (e.g. Time) Psych#dump will optimize the result.

Copy
time = Time.now data = {foo: time, bar: time}.to_yaml => => "---\n:foo: &1 2019-11-08 11:28:34.834180510 +01:00\n:bar: *1\n" ::YAML.safe_load(data, [Symbol, Time]) Psych::BadAlias: Unknown alias: 1 ::YAML.safe_load(data, [Symbol, Time], [], true) # This sym => {:foo=>2019-11-08 11:28:34 +0100, :bar=>2019-11-08 11:28:34 +0100}

makandra has been working exclusively with Ruby on Rails since 2007. Our laser focus on a single technology has made us a leader in this space.

Owner of this card:

Avatar
Emanuel De
Last edit:
11 days ago
by Emanuel De
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Emanuel De to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more