class Sandrbox::Value
Attributes
line[RW]
line_no[RW]
result[RW]
time[RW]
unbound_constants[RW]
unbound_methods[RW]
Public Class Methods
new(line, line_no)
click to toggle source
# File lib/sandrbox/value.rb, line 5 def initialize(line, line_no) self.unbound_methods = [] self.unbound_constants = [] self.line = line self.line_no = line_no evaluate end
Public Instance Methods
evaluate()
click to toggle source
# File lib/sandrbox/value.rb, line 13 def evaluate t = Thread.new do $SAFE = 2 begin Timeout::timeout(0.5) do Sandrbox.config.bad_methods.each {|meth| remove_method(meth.first, meth.last)} Sandrbox.config.bad_constants.each {|const| remove_constant(const)} self.result = eval(line, TOPLEVEL_BINDING, "sandrbox", line_no) end rescue Exception => e self.result = "#{e.class}: #{e.to_s}" ensure restore_constants restore_methods end end timeout = t.join(3) self.result = "SandrboxError: execution expired" if timeout.nil? self end
to_s()
click to toggle source
# File lib/sandrbox/value.rb, line 36 def to_s self.result end
Private Instance Methods
remove_constant(constant)
click to toggle source
# File lib/sandrbox/value.rb, line 81 def remove_constant(constant) self.unbound_constants << Object.send(:remove_const, constant) if Object.const_defined?(constant) end
remove_method(klass, method)
click to toggle source
# File lib/sandrbox/value.rb, line 42 def remove_method(klass, method) const = Object.const_get(klass.to_s) if const.methods.include?(method) || const.instance_methods.include?(method) self.unbound_methods << [const, const.method(method).unbind] metaclass = class << const; self; end message = if const == Object "undefined local variable or method `#{method}' for main:Object" else "undefined local variable or method `#{method}' for #{klass}:#{const.class}" end metaclass.send(:define_method, method) do |*args| raise NameError, message end const.send(:define_method, method) do |*args| raise NameError, message end end end
restore_constants()
click to toggle source
# File lib/sandrbox/value.rb, line 85 def restore_constants self.unbound_constants.each {|const| Object.const_set(const.to_s.to_sym, const) unless Object.const_defined?(const.to_s.to_sym)} end
restore_methods()
click to toggle source
# File lib/sandrbox/value.rb, line 64 def restore_methods self.unbound_methods.each do |unbound| klass = unbound.first method = unbound.last metaclass = class << klass; self; end metaclass.send(:define_method, method.name) do |*args| method.bind(klass).call(*args) end klass.send(:define_method, method.name) do |*args| method.bind(klass).call(*args) end end end