Module: Kernel

Defined in:
lib/sandboxed.rb,
lib/sandboxed/compat.rb

Constant Summary collapse

SAFE_FIBER =

initialize worker fiber for sandboxed execution

Fiber.new do |msg|
  while true
    obj, m, args, block = msg
    begin
      msg = Fiber.yield(block ? obj.send(m, *args, &block) : obj.send(m, *args))
    rescue Exception => e
      msg = Fiber.yield(e)
    end
  end
end.freeze

Instance Method Summary collapse

Instance Method Details

#safe(*args, &block) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/sandboxed.rb', line 19

def safe(*args, &block)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  level = opts.delete(:level) || 4
  ctx = opts.delete(:context) || eval('self', block.binding) # rebind to actual declaring object
  args << opts unless opts.empty? # be nicer about passed in hashes

  bound = block.bind(ctx) # TODO 1.8 compat is missing out here. How to?
  Fiber.new do |l, c, b, a|
    $SAFE = l
    b.call *a
  end.resume(level, ctx, bound, args)
end

#safe_method(*ms) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/sandboxed.rb', line 32

def safe_method(*ms)
  ms.each do |m|
    safe_m = :"#{m}__safe_"
    alias_method safe_m, m
    define_method m do |*args, &block|
      result = SAFE_FIBER.resume([self, safe_m, args, block])
      result.is_a?(Exception) ? throw(result) : result  # TODO find a better way
    end
  end
end