Is there a way in Ruby/Rails to execute code that is in a string?

Ruby on-RailsRubyScripting

Ruby on-Rails Problem Overview

So I have a database of different code samples (read snippets). The code samples are created by users. Is there a way in Rails to execute it?

So for example I have the following code in my database (with id=123):

return @var.reverse

Is there a way for me to execute it? Something like:

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

So the result would be 'olleH'

Ruby on-Rails Solutions

Solution 1 - Ruby on-Rails

You can use eval:

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

But be very careful in doing so; you're giving that code full access to your system. Try out eval('exit()') and see what happens.

Solution 2 - Ruby on-Rails

To the eval answer (which is the right one) I would add: get thee a copy of the Pickaxe Book (either Programming Ruby or Programming Ruby 1.9 depending on your Ruby version) and read the chapter called "Locking Ruby in the Safe." That chapter is all about Ruby's safe levels and tainted objects, and the chapter opens with exactly your use case and why you need to be paranoid about it.

Solution 3 - Ruby on-Rails

There is also another approach which you can use if you have a very limited use case or to limit the use cases.

I had to use this approach to allow users to dynamically specify relative times e.g.3.months.ago

I used a regex to sanitize the input from the users like so

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

You could extend the regex to allow for from_now as well or create an array of regexes for permitted operations and loop over it.

Would welcome any comments on this approach.


All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZepplockView Question on Stackoverflow
Solution 1 - Ruby on-RailsPestoView Answer on Stackoverflow
Solution 2 - Ruby on-RailsSFEleyView Answer on Stackoverflow
Solution 3 - Ruby on-RailsTyrone WilsonView Answer on Stackoverflow