Ruby/Rails中有没有办法执行字符串中的代码?

Zep*_*ock 51 ruby scripting ruby-on-rails

所以我有一个不同代码示例的数据库(读取片段).代码示例由用户创建.Rails有没有办法执行它?

例如,我在我的数据库中有以下代码(id = 123):

return @var.reverse
Run Code Online (Sandbox Code Playgroud)

有没有办法让我执行它?就像是:

@var = 'Hello'
@result = exec(CodeSample.find(123))
Run Code Online (Sandbox Code Playgroud)

所以结果就是'olleH'

Pes*_*sto 83

你可以使用eval:

code = '@var.reverse'
@var = 'Hello'
@result = eval(code)  # => "olleH"
Run Code Online (Sandbox Code Playgroud)

但要这样做要非常小心; 您正在为该代码提供对系统的完全访问权限.试试看eval('exit()')看会发生什么.


SFE*_*ley 15

对于eval答案(这是正确的答案),我想补充一下:给你一份Pickaxe Book(编程Ruby编程Ruby 1.9,取决于你的Ruby版本)并阅读一章名为"Locking Ruby in the Safe". 这一章是关于Ruby的安全水平和污染对象,并与章开恰好你的使用情况,以及为什么你需要疑神疑鬼.

  • http://www.ruby-doc.org/docs/ProgrammingRuby/html/taint.html这里是他正在谈论的"锁定安全中的红宝石"! (3认同)

Tyr*_*son 5

如果您的用例非常有限或需要限制用例,您还可以使用另一种方法。

我必须使用这种方法来允许用户动态指定相对时间,例如3.months.ago

我使用正则表达式来清理用户的输入,如下所示

PERMITTED_OPERATIONS = /^\{\%([1-9]\.(day|year|month|hour|minute)(s\.|\.)ago|Time\.now)\%\}$/
def permit?(operation)
  return !PERMITTED_OPERATIONS.match(operation.to_s).nil?
end
Run Code Online (Sandbox Code Playgroud)

您可以扩展正则表达式以允许from_now也可以,或者为允许的操作创建一个正则表达式数组并对其进行循环。

欢迎对此方法提出任何意见。