web-dev-qa-db-fra.com

Existe-t-il un moyen dans Ruby / Rails d'exécuter du code qui est dans une chaîne?

J'ai donc une base de données de différents exemples de code (lire des extraits). Les exemples de code sont créés par les utilisateurs. Existe-t-il un moyen dans Rails pour l'exécuter?

Ainsi, par exemple, j'ai le code suivant dans ma base de données (avec id = 123):

return @var.reverse

Existe-t-il un moyen pour moi de l'exécuter? Quelque chose comme:

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

Le résultat serait donc "olleH"

49
Zepplock

Vous pouvez utiliser eval :

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

Mais soyez très prudent en le faisant; vous donnez à ce code un accès complet à votre système. Essayez eval('exit()') et voyez ce qui se passe.

81
Pesto

À la réponse eval (qui est la bonne), j'ajouterais: obtenir une copie du livre de pioche (soit Programmation Ruby ou Programmation Ruby 1.9 selon votre Ruby) et lisez le chapitre intitulé "Verrouillage Ruby dans le coffre-fort. " Ce chapitre est tout au sujet des niveaux sûrs de Ruby et des objets contaminés, et le chapitre s'ouvre avec exactement votre cas d'utilisation et pourquoi vous devez être paranoïaque à ce sujet.

14
SFEley

Il existe également une autre approche que vous pouvez utiliser si vous avez un cas d'utilisation très limité ou pour limiter les cas d'utilisation.

J'ai dû utiliser cette approche pour permettre aux utilisateurs de spécifier dynamiquement des heures relatives, par exemple .3.months.ago

J'ai utilisé une expression régulière pour désinfecter l'entrée des utilisateurs comme ça

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

Vous pouvez étendre l'expression régulière pour permettre from_now ou créez un tableau d'expressions régulières pour les opérations autorisées et bouclez-le.

Accueillerait volontiers tout commentaire sur cette approche.

2
Tyrone Wilson