Подтвердить что ты не робот

Есть ли способ в Ruby/Rails для выполнения кода, который находится в строке?

Итак, у меня есть база данных различных образцов кода (чтение фрагментов). Образцы кода создаются пользователями. Есть ли способ в Rails выполнить его?

Итак, например, у меня есть следующий код в моей базе данных (с id = 123):

return @var.reverse

Есть ли способ для меня выполнить его? Что-то вроде:

@var = 'Hello'
@result = exec(CodeSample.find(123))

Таким образом, результатом будет "olleH"

4b9b3361

Ответ 1

Вы можете использовать eval:

code = '@var.reverse'
@var = 'Hello'
@result = eval(code)  # => "olleH"

Но будьте очень осторожны в этом; вы даете этому коду полный доступ к вашей системе. Попробуйте eval('exit()') и посмотрите, что произойдет.

Ответ 2

В ответ eval (который является правильным) я бы добавил: получите копию Копии книги Киккаса (Programming Ruby или Программирование Ruby 1.9 в зависимости от вашей версии Ruby) и прочитайте главу "Блокировка Ruby в Safe". Эта глава посвящена безопасным уровням Ruby и искаженным объектам, и глава открывается именно вашим прецедентом и почему вам нужно быть параноидальным.

Ответ 3

Существует и другой подход, который вы можете использовать, если у вас очень ограниченный вариант использования или ограничение использования.

Мне пришлось использовать этот подход, чтобы позволить пользователям динамически определять относительные времена, например 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

Вы можете расширить регулярное выражение, чтобы разрешить from_now, или создать массив регулярных выражений для разрешенных операций и выполнить цикл над ним.

Приветствуем любые комментарии к этому подходу.