升级到 Ruby 3.1 会在使用 YAML.load_file 时导致 Psych::DisallowedClass 异常

问题描述 投票:0回答:6

升级到 ruby 3.1 时,我在使用时看到以下排序错误消息

YAML.load_file some_file_name

 Psych::DisallowedClass:
   Tried to load unspecified class: Matrix

其他加载语句会导致类似的错误,但会引用不同的未指定类,例如开放结构。最新版本的 YAML 似乎只从允许的白名单中加载类,因此有必要使用 permitted_class 关键字来允许其他类。我试过了

hsh = YAML.load_file some_file_name, permitted_classes: [Matrix, OpenStruct]

但这给出了错误

 Psych::DisallowedClass:
   Tried to load unspecified class: Symbol

我该如何解决这个问题?

ruby yaml activesupport
6个回答
36
投票

工作解决方案是将此行添加到 config/application.rb

config.active_record.yaml_column_permitted_classes = [ActiveSupport::HashWithIndifferentAccess]

你可以对任何类名做同样的事情,比如

config.active_record.yaml_column_permitted_classes = [Symbol, Hash, Array, ActiveSupport::HashWithIndifferentAccess]

32
投票
默认情况下也不允许使用

Symbol
。因此,加载文件时,您也需要将
Symbol
添加到
permitted_classes
中:

hash = YAML.load_file(
  some_file_name, 
  permitted_classes: [Matrix, OpenStruct, Symbol]
)

查看 Psych. 中的默认列表

permitted_classes

或者,当在 Ruby on Rails 中使用时,您可以配置 Rails 在您的

config/application.rb
中使用 YAML 文件时应该全局允许哪些类:

config.active_record.yaml_column_permitted_classes += [Matrix, OpenStruct, Symbol]

请注意,对于 Ruby on Rails 中的内部 YAML 解析,

Symbol
已经是
active_record.yaml_column_permitted_classes
的默认值。


16
投票

在 rails 6.1 升级中进行了此操作。如果你别无选择,也许这个解决方法会给你带来一些时间(application.rb):

config.active_record.use_yaml_unsafe_load = true

0
投票

直接使用

YAML.load_file
时,不使用
config.yaml_column_permitted_classes
。这仅在 Rails 加载 YAML(配置文件、序列化 YAML)时使用。

你可以:

  • a.) 或者,像@spickermann 写的那样,将允许的类列表传递给
    YAML.load_file(path, permitted_classes: [..])
    ,或者:
  • b.) 您可以切换到
    YAML.unsafe_load_file
    (例如对于测试用例)。

0
投票

“safe YAML”加载方式默认不允许所有类反序列化。此选项允许您指定在您的应用程序中被视为“安全”的类。例如,如果您的应用程序在序列化数据中使用 Symbol 和 Time,您可以将 Symbol 和 Time 添加到允许列表中。

通过将此添加到 application.rb 来修复:

config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]

0
投票

您可以更改 Rails 配置以使用 YAML/Psych 的 unsafe_load(参见 Mohamed 和 crazywulf 的回答)。我需要在不重新启动 Rails 应用程序的情况下更改此配置,所以我这样做了:

ActiveRecord.use_yaml_unsafe_load = true

请注意,这只是对当前流程的临时修复。一旦你重新启动服务器,它就会消失。

© www.soinside.com 2019 - 2024. All rights reserved.