在这种情况下我怎样才能避免eval

时间:2015-08-12 10:02:24

标签: ruby-on-rails ruby

编写title_tag帮助器,我想拥有以下yml文件结构

index: Hello {{@game.name}}
edit: Edit {{@game.name}} - {{@game.classification}}

到那时我接受I18n翻译字符串,需要用实际上下文替换{{var}}。

title = I18n.t "title_tags.#{namespace}.#{controller_name}.#{action_name}", default: ""

title.scan(/\{\{.*?\}\}/).each do |replace|
  # transform {{@game.name}} => @game.name
  var = replace.gsub(/\{|\}/, "")
  title.gsub! replace, eval(var)
end      
这是非常好的工作。另一方面,用户可能会上传一些名为“system(rm -rf / *)”的游戏,这可能对我们造成一些真正的危险?

有没有可能以更安全的方式运行?

修改

感谢Axel,我可以用这个很酷的东西结束

 title.scan(/\{\{.*?\}\}/).each do |replace|
    var = replace.gsub(/\{|\}/, "")                        

    # catch "resource" (like resource-controller)
    if var.starts_with? "resource"
      @tempresource = resource
      var.gsub!("resource", "@tempresource")
    end

    # @game or @game.name
    if var.starts_with?("@")          
      content = var.split('.').inject(nil){|clazz, method| clazz.nil? ? instance_variable_get(method) : clazz.send(method)}
      title.gsub! replace, content
    end
  end
工作辉煌!

1 个答案:

答案 0 :(得分:2)

您可以使用send而不是eval:

content = var.split('.').inject(nil){|clazz, method| clazz.nil? ? instance_variable_get(method) : clazz.send(method)}
title.gsub! replace, content