Bulding a crash-proof eval(), is it possible?

I’m building an app which must execute user-submitted bits of Ruby code.
Obviously, eval() does this. Illustration:

user_code = “‘hello’.upcase”
result = eval(user_code)
puts "the code evaluated to: " + result

But if the user’s code throws an uncaught exception, the whole app
crashes. This can be rectified by wrapping the eval() in
begin/rescue/end:

user_code = “0/0”
begin
result = eval(user_code)
puts "the code evaluated to: " + result
rescue
puts “the code had errors.”
end

Unfortunately, it is still possible to make the program crash if the
user code contains syntax errors which interfere with begin/rescue/end.

user_code = “end ‘hello there’”
begin
result = eval(user_code)
puts "the code evaluated to: " + result
rescue
puts “the code had errors.”
end

The above code will crash the entire application with “syntax error,
unexpected kEND”.

So I ask you: is it possible to execute arbitrary user-submitted code in
such a way that the user’s code won’t crash the server if it contains
innocent mistakes? I am not interested in protecting from malicious
code, just user mistakes.

Alternatively, is it possible to determine whether a given string is
syntactically-correct ruby code? If so, I could simply not eval() such
code.

I welcome any suggestions. Thanks!

On Friday 05 November 2010, Nick B. wrote:

|
|
|
|So I ask you: is it possible to execute arbitrary user-submitted code in
|such a way that the user’s code won’t crash the server if it contains
|innocent mistakes? I am not interested in protecting from malicious
|code, just user mistakes.
|
|Alternatively, is it possible to determine whether a given string is
|syntactically-correct ruby code? If so, I could simply not eval() such
|code.
|
|I welcome any suggestions. Thanks!

You need to replace rescue with

rescue Exception

Without any exception classes following it, rescue only rescues
exceptions
derived from StandardError.

Stefano

Without any exception classes following it, rescue only rescues
exceptions
derived from StandardError.

Thanks you Stefano; that did the trick!

On Fri, Nov 5, 2010 at 10:15 PM, Nick B. [email protected] wrote:

Without any exception classes following it, rescue only rescues
exceptions
derived from StandardError.

Also, you probably thought of that, but you want stop them from
doing system(“rm -rf ~/*”) or similar :slight_smile: