ActiveSupport日期解析的“eval”替代方案

时间:2016-01-29 01:19:18

标签: ruby metaprogramming activesupport

我的脚本当前接受ActiveSupport日期字符串作为命令行参数:

attribute = 1

在我的脚本中,我使用eval将其存储到我的配置

function onclick(e) {
     window.open(e.target.feature.properties.link);
}


function onEachFeature(feature, layer) {
    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight,
        click: onclick
    });
}

我明白这是非常狡猾和不安全的,因为任何东西都可以传递给eval,但我的替代方案是什么?

2 个答案:

答案 0 :(得分:2)

你想要持续时间吗?我想你可以使用chronic_duration

 my_script --mindate "1 day"
 MyScript.configuration.min_date = ChronicDuration.parse(min_date_string)

但是,由于它是自然语言的启发式方法,它并没有完全明确地定义它将识别出什么样的字符串。但它会做一些奇特的事情,例如" 1天和4小时"。

或者您可以为参数编写自己非常简单的解析器/解释器。只需分隔一个空格(用于" 1天和#34;输入类型)或句点(用于" 1.day")输入类型。在第二个位置识别几个单词("小时","分钟""日","月","年&# 34;),将它们转换为秒,将数字乘以转换为秒的单词。大概有十几条红宝石。

或者您甚至可以利用ActiveSupport功能支持" 1.day"使它更容易。

  str = "11 hours"
  number, unit = str.split(' ')
  number.to_i.send(unit)

这会让命令行用户将他们想要的任何方法发送到一个数字。我不确定这是否重要。就此而言,我不确定原始的eval是否真的重要 - 但我同意你的不好做法。就此而言,用户输入可能是send,尽管不是那么糟糕。

或者您可以让它们以原始秒数发送并自行计算。

my_script --mindate 86400

您意识到1.day最终会被转换为标准日的秒数,对吧?我不确定你为什么要打电话几秒钟"请注意",但那是你的事!

修改或者另一种选择,让他们这样做:

my_script --mindays 2 --minhours 4 --minminutes 3

或者其他什么。

答案 1 :(得分:0)

你的脚本是如何被调用的?是否总是由具有帐户的用户在运行它的任何计算机上调用?这是不是以某种方式被Web服务调用,或者以某种方式无法访问该机器的人能够使用自己的参数远程调用它?

如果它仅由用户调用,并且这些用户已经可以访问ruby命令或irb,那么您无法让他们执行任何操作他们不能通过调用eval来做。

如果远程调用,您可能不应该使用eval。或者,快速而肮脏的解决方案可能是匹配您将使用正则表达式进行评估的模式。像/^[0-9]+(\.[a-z_0-9]+){,2}$/这样的东西可以确保它在评估之前在Fixnum文字的2个方法调用中。