ruby/psych

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

azeemh opened this issue · 2 comments

ruby 3.2
rails 7.04
ubuntu 22.10 (shouldn't matter but i hate when people give mac specific solutions)

even with gem 'psych', '~> 5.0.1' in my gemfile

none of the following lines in my ror application.rb will work (i tried them one at a time but including all for completeness.)


    config.active_record.yaml_column_permitted_classes = [Time]
    config.active_record.yaml_column_permitted_classes = [ActiveSupport::HashWithIndifferentAccess]
    config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]

please advise because now I have to pin to gem 'psych', '~> 3.3.0' in my gemfile which bundle gives me 3.3.4 and everything works.

why did you guys forget to add support for dates and times? that's like the most basic thing and it broke everything.

please add symbols dates and times as default permitted classes in the gem, or please inform the relevant area (file and line in the codebase) so I or anyone else with the same issue can make a pull release that fixes if nobody else will?

thank you.

hsbt commented

I can allow Date, DateTime and Time into Psych.load by default. But your issue seems Rails configuration, not Psych.

see

prolog: not sure why this is a closed issue, so this is just an observation (and a kind of band-aid to those who do not get the suggested fixes to work, or will not downgrade Psych

I'm currently on Rails 8.0.0.alpha with ruby 3.2.2 [amd64-darwin22] - and with the "baked-in psych at 5.1.2, I experience the subject on this issue in full force when (trying to) serializing IceCube::Schedule objects like:

now = Time.current
=> Tue, 09 Jul 2024 17:36:03.280022000 UTC +00:00
mortimer(dev)> schedule = IceCube::Schedule.new(now, duration: 3600)
mortimer(dev)> schedule.add_recurrence_rule IceCube::Rule.daily
mortimer(dev)> schedule.occurring_at? Time.current
=> true
mortimer(dev)> sy = schedule.to_yaml
=> "---\n:start_time:\n  :time: 2024-07-09 17:36:03.280022000 Z\n  :zone: UTC\n:end_time:\n  :time: 2024-07-09 18:36:03.280022000 Z\n  :zone: UTC\n:rrules:\n- :validations: {}\n  :rule_type: IceCube::DailyRule\n  :interval: 1\n- :validations:\n    :day:\n    - 1\n  :rule_type: IceCube::We...
mortimer(dev)> schedule = IceCube::Schedule.from_yaml sy, permitted_classes: [ Time, Symbol ]
(mortimer):92:in `<main>': Tried to load unspecified class: Time (Psych::DisallowedClass)
mortimer(dev)> schedule = IceCube::Schedule.from_yaml sy, unsafe_load: true
(mortimer):93:in `<main>': Tried to load unspecified class: Time (Psych::DisallowedClass)

Like @azeemh I'm perfectly able to "downgrade" Psych to 3.3.4 -- not sure if I loose something important though
🤔

mortimer(dev)> schedule = IceCube::Schedule.from_yaml sy
=> 
#<IceCube::Schedule:0x000000011185efc8
...

How can I have my 🍰 and eat it too?

Well, at least with IceCube::Schedule you seem to be able to do the following (building upon the defined schedule from above)

mortimer(dev)> json = schedule.to_json
=> "{\"start_time\":{\"time\":\"2024-07-09T18:25:18.588Z\",\"zone\":\"UTC\"},\"end_time\":{\"time\":\"2024-07-09T19:25:18.588Z\",\"zone\":\"UTC\"},\"rrules\":[{\"validations\":{},\"rule_type\":\"IceCube::DailyRule\",\"interval\":1}],\"rtimes\":[],\"extimes\":[]}"
mortimer(dev)> yaml = YAML.unsafe_load json
=> {"start_time"=>{"time"=>"2024-07-09T18:25:18.588Z", "zone"=>"UTC"}, "end_time"=>{"time"=>"2024-07-09T19:25:18.588Z", "zone"=>"UTC"}, "rrules"=>[{"validations"=>{}, "rule_type"=>"IceCube::DailyRule", "interval"=>1}], "rtimes"=>[], "extimes"=>[]}
mortimer(dev)> schedule = IceCube::Schedule.from_hash yaml
=> 
#<IceCube::Schedule:0x000000010e3fd400
...
mortimer(dev)> schedule.occurring_at? Time.current
=> true
mortimer(dev)> schedule.occurring_at? Time.current + 3.hours
=> false

epilog: I know - I'm using the unsafe_load but if IceCube::Schedule spat out the JSON, I guess I'm in the clear (otherwise the good folks at IceCube might watch their '6')
😎