ts wrote:

> safe('
> class << a = []
>    def _dump(a)
>       $stderr.puts "More you make it complex, more it will be easy to break"
>    end
> end
> a')

Heh, good one. Thanks for pointing this out.

Try this fixed version:

module Safe
   extend self

   def safe(code, sandbox=nil)
     error, result = nil, nil

     begin
       thread = Thread.new do
         sandbox ||= Object.new.taint
         yield(sandbox) if block_given?

         $SAFE = 5
         $-w = nil

         eval(code, sandbox.send(:binding))
       end
       result = secure_object(thread.value)
     rescue Exception => error
       error = secure_object(error)
     end

     return result, error
   end

   def secure_object(obj)
     # We can't dup immediate values. But that's no problem
     # because most of them can't have any singleton methods
     # anyway. (nil, true and false can, but they can't be
     # defined in safe contexts.)
     immediate_classes = [Fixnum, Symbol, NilClass, TrueClass,
       FalseClass]
     return obj if immediate_classes.any? { |klass| klass === obj }

     # Dup won't copy any singleton methods and without any
     # of them the Object will be safe. (But we can't call
     # the Object's .dup because it might be evil already.)
     safe_dup = Object.instance_method(:dup).bind(obj)
     safe_dup.call
   end
end

def safe(*args, &block)
   Safe.safe(*args, &block)
end

Regards,
Florian Gross