【问题标题】:Ruby executable in YAMLYAML 中的 Ruby 可执行文件
【发布时间】:2015-06-02 06:02:33
【问题描述】:

我有一个样本yaml 文件(abc.yaml),如下所示:

entity1:
  condition: "created_at >= #{Date.today - 3.months}"

我想在 Ruby 中从 YAML 读取这个条件:

"created_at >= 2015-03-02"

但是当我这样做时

YAML.load_file('abc.yaml')["entity1"]["condition"]

我明白了:

"created_at >= \#{Date.today - 3.months}"

请告诉我如何解决这个问题。

【问题讨论】:

    标签: ruby-on-rails ruby yaml


    【解决方案1】:

    更安全的选择是仅从预先确定的格式转换已知数据。或者使用一些很酷的东西,比如 settingslogic https://github.com/settingslogic/settingslogic。它使用 ERB 样式的格式来加载设置,因此您可以获得一些内置的安全性。

    例如:

    defaults: &defaults
      cool:
        saweet: nested settings
      neat_setting: 24
      awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %>
    

    【讨论】:

      【解决方案2】:

      只有在您绝对确定没有人可以更改您的 yaml 文件以注入有害内容时才这样做:

      condition = YAML.load_file('abc.yaml')["entity1"]["condition"]
      condition = eval "\"#{condition}\""
      

      【讨论】:

      • OP:“只有当你绝对确定时”部分,我再怎么强调都不为过;这很可能是错误的做法。如果可能的话,重构为更具限制性的东西。
      • eval condition 将尝试运行 created_at &gt;= \#{Date.today - 3.months} 并因语法错误而失败。 condition = eval "\"#{condition}\"" 将运行 "created_at &gt;= #{Date.today - 3.months}" 并生成 "created_at &gt;= 2015-03-02" 字符串作为结果。
      • 哦,对了,对不起。忽略了插值。那么你可能需要用eval eval "\"#{condition}\""... 跟进它
      【解决方案3】:

      像这样使用它

      entity1:
        condition: "created_at >= <%= Date.today - 3.months %>"
      

      在阅读时加载它就像

      abc = YAML.load(ERB.new(File.read("file_path")).result)
      abc["entity1"]["condition"]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 2013-08-08
        • 1970-01-01
        • 2015-12-30
        • 2011-12-13
        • 1970-01-01
        相关资源
        最近更新 更多