From: Florian Gross Date: 2004-05-11T02:53:55+09:00 Subject: Re: safe eval? Ara.T.Howard wrote: > i have a project i'm working on where i'd like to support complex > boolean/relational requests, where those requests must be satisfied on the > context of defined objects... i'm loath to create an entire parser/scanner > just to evaluate these expression when ruby's own is already written but also > don't want to risk using eval for the obvious reason. so, for example, i'll > have a command line option for a request: > > prog.rb --request='a < 42 and b == true' Just use this: module Safe; end class << Safe # Runs passed code in a relatively safe sandboxed environment. # # You can pass a block which is called with the sandbox as its first # argument to apply custom changes to the sandbox environment. # # Returns an Array with the result of the executed code and # an exception, if one occured. # # Example of usage: # # result, error = safe "1.0 / rand(10)" # puts if error then # "Error: #{error.inspect}" # else # result.inspect # end def safe(code, sandbox=nil) error = nil begin thread = Thread.new { $-w = nil sandbox ||= Object.new.taint yield(sandbox) if block_given? $SAFE = 5 eval(code, sandbox.send(:binding)) } value = thread.value result = Marshal.load(Marshal.dump(thread.value)) rescue Exception => error error = Marshal.load(Marshal.dump(error)) end return result, error end end def safe(*args, &block) Safe::safe(*args, &block) end Regards, Florian Gross