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"
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.
À 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.
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.