Class: Sandbox::Safe

Inherits:
Full
  • Object
show all
Defined in:
lib/sandbox/safe.rb

Instance Method Summary collapse

Instance Method Details

#activate!Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/sandbox/safe.rb', line 7

def activate!
  activate_fakefs

  keep_singleton_methods(:Kernel, KERNEL_S_METHODS)
  keep_singleton_methods(:Symbol, SYMBOL_S_METHODS)
  keep_singleton_methods(:String, STRING_S_METHODS)
  keep_singleton_methods(:IO, IO_S_METHODS)

  keep_methods(:Kernel, KERNEL_METHODS)
  keep_methods(:NilClass, NILCLASS_METHODS)
  keep_methods(:Symbol, SYMBOL_METHODS)
  keep_methods(:TrueClass, TRUECLASS_METHODS)
  keep_methods(:FalseClass, FALSECLASS_METHODS)
  keep_methods(:Enumerable, ENUMERABLE_METHODS)
  keep_methods(:String, STRING_METHODS)

  Kernel.class_eval do
    def `(*args) # `<- fix highlight by editor
      raise NoMethodError, "` is unavailable"
    end

    def system(*args)
      raise NoMethodError, "system is unavailable"
    end
  end
end

#activate_fakefsObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sandbox/safe.rb', line 34

def activate_fakefs
  require "fileutils"

  # unfortunately, the authors of FakeFS used `extend self` in FileUtils, instead of `module_function`.
  # I fixed it for them
  (FakeFS::FileUtils.methods - Module.methods - Kernel.methods).each do |module_method_name|
    FakeFS::FileUtils.send(:module_function, module_method_name)
  end

  import  FakeFS
  ref     FakeFS::Dir
  ref     FakeFS::File
  ref     FakeFS::FileTest
  import  FakeFS::FileUtils #import FileUtils because it is a module

  # this is basically what FakeFS.activate! does, but we want to do it in the sandbox
  # so we have to live with this:
  eval <<-RUBY
    Object.class_eval do
      remove_const(:Dir)
      remove_const(:File)
      remove_const(:FileTest)
      remove_const(:FileUtils)

      const_set(:Dir,       FakeFS::Dir)
      const_set(:File,      FakeFS::File)
      const_set(:FileUtils, FakeFS::FileUtils)
      const_set(:FileTest,  FakeFS::FileTest)
    end

    [Dir, File, FileUtils, FileTest].each do |fake_class|
      fake_class.class_eval do
        def self.class_eval
          raise NoMethodError, "class_eval is unavailable"
        end
        def self.instance_eval
          raise NoMethodError, "instance_eval is unavailable"
        end
      end
    end
  RUBY

  FakeFS::FileSystem.clear
end

#eval(code, options = {}) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/sandbox/safe.rb', line 79

def eval(code, options={})
  if options.is_a?(Binding)
    eval_with_binding(code, options)
  elsif seconds = options[:timeout]
    sandbox_timeout(code, seconds) do
      super code
    end
  else
    super code
  end
end