Class: SafeRuby

Inherits:
Object
  • Object
show all
Defined in:
lib/safe_ruby.rb,
lib/safe_ruby_runner.rb

Constant Summary collapse

VERSION =
"1.0.1"
DEFAULTS =
{ timeout: 5,
raise_errors: true }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(code, options = {}) ⇒ SafeRuby

Returns a new instance of SafeRuby.



9
10
11
12
13
14
15
# File 'lib/safe_ruby_runner.rb', line 9

def initialize(code, options={})
  options = DEFAULTS.merge(options)

  @code         = code
  @raise_errors = options[:raise_errors]
  @timeout      = options[:timeout]
end

Class Method Details

.check(code, expected) ⇒ Object



50
51
52
# File 'lib/safe_ruby_runner.rb', line 50

def self.check(code, expected)
  eval(code) == eval(expected)
end

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



17
18
19
# File 'lib/safe_ruby_runner.rb', line 17

def self.eval(code, options={})
  new(code, options).eval
end

Instance Method Details

#evalObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/safe_ruby_runner.rb', line 21

def eval
  temp = build_tempfile
  read, write = IO.pipe
  ChildProcess.build("ruby", temp.path).tap do |process|
    process.io.stdout = write
    process.io.stderr = write
    process.start
    begin
      process.poll_for_exit(@timeout)
    rescue ChildProcess::TimeoutError => e
      process.stop # tries increasingly harsher methods to kill the process.
      return e
    end
    write.close
    temp.unlink
  end

  data = read.read
  begin
    Marshal.load(data)
  rescue => e
    if @raise_errors
      raise data
    else
      return data
    end
  end
end