ruby/psych

Release of 4.0.0 breaks yaml files with dates

poloka opened this issue ยท 15 comments

With the release of 4.0.0, receiving the following error for yaml files with dates

Tried to load unspecified class: Date (Psych::DisallowedClass)

Yaml file that I am attempting to load is

---
date: 2013-10-16

I was able to reproduce locally between two project by simply running the following code

#!/usr/bin/env ruby
# frozen_string_literal: true

require 'yaml'

path = File.join(__dir__, 'file.yml')
data = YAML.load_file(path)
puts data

The version with a 3.3.2 loads as expected

> ./test.rb 
{"date"=>#<Date: 2013-10-16 ((2456582j,0s,0n),+0s,2299161j)>}

4.0 introduces a set of new methods, #unsafe_load_file is among them.
#488

@olleolleolle sure it may have new methods but the underlying changes are breaking to existing Yaml.load_file. This seems really really bad. I looked for release notes on the v4.0.0 tag and in the readme and there is none so my assumption existing logic should continue to work. I'm currently investigating a lot of other similar breaking changes that I will be commenting shortly like

Tried to load unspecified class: Libv8::Location::System (Psych::DisallowedClass)

@poloka #487 is the only change in 4.0.0. If you need to load a file from a trusted source, use unsafe_load_file. If the data is from an untrusted source, then specify the classes you allow via the permitted_classes option here.

@tenderlove I do not believe that is acceptable. I have taken my project entirely out of the picture by running the following:

> rails new psych_rails_3

In updating the Gemfile to lock psych to 3.x, place the following file in the config/ folder

---
development:
  date: 2013-10-16

And execute the following

> rails c
2.6.6 :001 > ::Rails.application.config_for(:file)
 => {"date"=>Wed, 16 Oct 2013} 

Lock in psych-4.x and perform the same execution, I get

> rails c
Traceback (most recent call last):
        70: from bin/rails:4:in `<main>'
        69: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
        68: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
        67: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
        66: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
        65: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
        64: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands.rb:18:in `<main>'
        63: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/command.rb:46:in `invoke'
        62: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/command/base.rb:69:in `perform'
        61: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
        60: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
        59: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
        58: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:96:in `perform'
        57: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:19:in `start'
        56: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:19:in `new'
        55: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:29:in `initialize'
        54: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/engine.rb:444:in `load_console'
        53: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/application.rb:535:in `run_console_blocks'
        52: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/engine/railties.rb:15:in `each'
        51: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/engine/railties.rb:15:in `each'
        50: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/application.rb:535:in `block in run_console_blocks'
        49: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:233:in `run_console_blocks'
        48: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:255:in `each_registered_block'
        47: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:255:in `each'
        46: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:233:in `block in run_console_blocks'
        45: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/railtie.rb:57:in `block in <class:Railtie>'
        44: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/dependencies.rb:291:in `require'
        43: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/dependencies.rb:257:in `load_dependency'
        42: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/dependencies.rb:291:in `block in require'
        41: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
        40: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
        39: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
        38: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
        37: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
        36: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/base.rb:27:in `<main>'
        35: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/base.rb:328:in `<module:ActiveRecord>'
        34: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
        33: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:51:in `each'
        32: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
        31: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'
        30: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'
        29: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:71:in `block in execute_hook'
        28: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:71:in `instance_eval'
        27: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/railtie.rb:133:in `block (2 levels) in <class:Railtie>'
        26: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/application/configuration.rb:172:in `database_configuration'
        25: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych.rb:369:in `load'
        24: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych.rb:334:in `safe_load'
        23: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
        22: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
        21: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
        20: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:318:in `visit_Psych_Nodes_Document'
        19: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
        18: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
        17: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
        16: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
        15: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `revive_hash'
        14: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each_slice'
        13: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each'
        12: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
        11: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
        10: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
         9: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
         8: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
         7: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `revive_hash'
         6: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each_slice'
         5: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each'
         4: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
         3: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
         2: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
         1: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
/Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:430:in `visit_Psych_Nodes_Alias': Unknown alias: default (Psych::BadAlias)
        70: from bin/rails:4:in `<main>'
        69: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
        68: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
        67: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
        66: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
        65: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
        64: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands.rb:18:in `<main>'
        63: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/command.rb:46:in `invoke'
        62: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/command/base.rb:69:in `perform'
        61: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
        60: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
        59: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
        58: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:96:in `perform'
        57: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:19:in `start'
        56: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:19:in `new'
        55: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/commands/console/console_command.rb:29:in `initialize'
        54: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/engine.rb:444:in `load_console'
        53: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/application.rb:535:in `run_console_blocks'
        52: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/engine/railties.rb:15:in `each'
        51: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/engine/railties.rb:15:in `each'
        50: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/application.rb:535:in `block in run_console_blocks'
        49: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:233:in `run_console_blocks'
        48: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:255:in `each_registered_block'
        47: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:255:in `each'
        46: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/railtie.rb:233:in `block in run_console_blocks'
        45: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/railtie.rb:57:in `block in <class:Railtie>'
        44: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/dependencies.rb:291:in `require'
        43: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/dependencies.rb:257:in `load_dependency'
        42: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/dependencies.rb:291:in `block in require'
        41: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
        40: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
        39: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
        38: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
        37: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/bootsnap-1.7.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
        36: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/base.rb:27:in `<main>'
        35: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/base.rb:328:in `<module:ActiveRecord>'
        34: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
        33: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:51:in `each'
        32: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
        31: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'
        30: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'
        29: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:71:in `block in execute_hook'
        28: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activesupport-5.2.6/lib/active_support/lazy_load_hooks.rb:71:in `instance_eval'
        27: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/activerecord-5.2.6/lib/active_record/railtie.rb:133:in `block (2 levels) in <class:Railtie>'
        26: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/railties-5.2.6/lib/rails/application/configuration.rb:172:in `database_configuration'
        25: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych.rb:369:in `load'
        24: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych.rb:334:in `safe_load'
        23: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
        22: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
        21: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
        20: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:318:in `visit_Psych_Nodes_Document'
        19: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
        18: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
        17: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
        16: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
        15: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `revive_hash'
        14: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each_slice'
        13: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each'
        12: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
        11: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
        10: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
         9: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
         8: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:167:in `visit_Psych_Nodes_Mapping'
         7: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `revive_hash'
         6: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each_slice'
         5: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:343:in `each'
         4: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:345:in `block in revive_hash'
         3: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:35:in `accept'
         2: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:6:in `accept'
         1: from /Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/visitor.rb:30:in `visit'
/Users/gh7199/.rvm/gems/ruby-2.6.6@psych_rails_3/gems/psych-4.0.0/lib/psych/visitors/to_ruby.rb:430:in `visit_Psych_Nodes_Alias': Cannot load database configuration: (Psych::BadAlias)
Unknown alias: default

Something is terribly wrong with your rubygem and the 4.0 version should be pulled from rubygems.

@tenderlove if such a change was deemed necessary, deprecation notices should have been provided directing consumers that 'hey, a change is coming you may be concerned about' and not just breaking people on an upgrade. If you wish to continue with the existing logic, you should provide fallback to original if an exception occurs and provide a deprecation notice to again indicate to your consumers that they will need to change their way of loading yaml files.

@poloka It's a major version change. You can choose whether or not to upgrade, and if you'd like to add those kind of warnings to the 3.x series, I'm happy to merge your pull requests! ๐Ÿ˜„

@poloka

Semantic versioning dictates that a major version change happens when breaking changes are introduced:

Semantic Versioning 2.0.0

Summary

Given a version number MAJOR.MINOR.PATCH, increment the:

  1. MAJOR version when you make incompatible API changes

3.x.y to 4.x.y is a MAJOR version change, and you should expect breaking changes.

As Aaron points out, you can limit your project to ~> 3.0 via your Gemfile if this causes you problems.

@JonRowe I am very aware of semantic versioning practices but I also understand the responsibility of a developer to provide warnings of such breaking changes and documentation of said changes when they do occur. Neither has happened in regards to this breaking change. And yes, I will lock in the version to a 3.x until I have determined a way to remove psych from my tech stack.

@poloka I'm sure the maintainers would be happy to refund all of the money you gave them to use this gem

Maybe I should phrase it more like this, it is a 'courtesy' to warn our consumers and if we know there is a breaking change that we provide migration guides to assist in the pains of pulling the rug out from under them. I'm just trying to follow best practices to my/our consumers in order to keep them productive and keep disruptions to a minimum. Just trying to give my $0.02 on the topic.

I am very aware of semantic versioning practices but I also understand the responsibility of a developer to provide warnings of such breaking changes and documentation of said changes when they do occur.

That is to say, none, a major version change is the warning. Please lock your major versions if you are unable to cope with breaking changes. :)

@poloka Did you mean that "our consumers" are your project or product's consumers using psych as one of the dependencies? I am sorry about your situation. However a breaking change can happen for every gem as a possibility. So, I think the best practice you can learn for your project or product from this situation is to pin the dependency gem versions as much as possible such as with Gemfile or/and Gemfile.lock.

@JonRowe we ran into psych being a transitive dependency from another project so we didn't have knowledge of its version or had initial control over the version being taken. So we were blissfully unaware of the open-ended accepted versions.

Thanks @junaruga , yeah we utilize the lock in our Rails applications but not in our rubygems but luckily the issue we've run into is a development concern so we are able to direct our consumers to update the Gemfile to lock in and keep on working.

BTW, thanks for making it a MVB. I've run into other gems where breaking changes were in minor versions. Talk about a pain. Thanks guys for the direction!

ric2b commented

I ran into this while upgrading to Ruby 3.1 and I do feel that the messaging on this breaking change could be improved.

The Ruby 3.1.0 release notes list the breaking change as basically a footnote in the "Other changes" section and don't provide a direct migration recommendation, they just link to an issue with discussion on whether Psych 4 should be included in Ruby 3.1 or not.

When going to the official documentation or to this repo I can't find any official changelog or guide on what exactly changed. The releases tab on this repo also doesn't have a changelog for 4.0.0.

It seems to me like Pull Request 487 is the most official looking warning/guide/documentation on what changed but it's not prominently linked from the obvious places, so I think a lot of people will waste some time trying to find the relevant information about this change, like I did.

To be clear: I agree with the change and I'm thankful for the work done here, I'm just giving some (hopefully constructive) feedback on how the change was communicated.

UPDATE: Leaving this here in case anyone else has this issue. It turns out there is a goldilocks version of psych if you're having these issues. Anything before v3.1.0 won't let you pass permitted_classes as a method argument or a config argument in rails. Anything greater than ~v4 causes a Psych::AliasesNotEnabled errors. I explicitly add psych to my Gemfile like this and the permitted_classes whitelist works great: gem 'psych', '~> 3.3.4'.

I followed the advice for rails users (rails 5.2.8.1 in our case), and set config.active_record.yaml_column_permitted_classes = [BigDecimal], however it does nothing.

Currently the only thing that works is config.active_record.use_yaml_unsafe_load = true, and I really don't want to do that.

Doesn't matter if I call Psych directly passing in the permitted classes:

pry(main)> Psych.safe_load("---\n- - 7043\n  - !ruby/object:BigDecimal 18:0.5658e2\n", permitted_classes: [BigDecimal])
Psych::DisallowedClass: Tried to load unspecified class: BigDecimal
from /usr/share/rvm/rubies/ruby-2.4.9/lib/ruby/2.4.0/psych/class_loader.rb:97:in `find'

What do we do in this situation then. Shouldn't psych be reading our config change and allowing BigDecimals?

EDIT: After digging into the gem (says version 2.2.2 inside versions.rb), I think there could be something wrong. When I run this with permitted classes, the @classes variable is not set correctly:

[1] pry(main)> Psych.safe_load("---\n- - 7043\n  - !ruby/object:BigDecimal 18:0.5658e2\n", permitted_classes: [BigDecimal])

From: /usr/share/rvm/rubies/ruby-2.4.9/lib/ruby/2.4.0/psych/class_loader.rb:96 Psych::ClassLoader::Restricted#find:

     94: def find klassname
     95:   binding.pry
 =>  96:   if @classes.include? klassname
     97:     super
     98:   else
     99:     raise DisallowedClass, klassname
    100:   end
    101: end

[1] pry(#<Psych::ClassLoader::Restricted>)> @classes
=> ["[:permitted_classes, [BigDecimal]]"]
[2] pry(#<Psych::ClassLoader::Restricted>)> klassname
=> "BigDecimal"
[3] pry(#<Psych::ClassLoader::Restricted>)> @classes.include? klassname
=> false