jruby_sandbox 0.1.4-java → 0.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 072482dce6da86c8ee7a942fb1e66fd00debe215
4
+ data.tar.gz: 01767fa5c25221cd5fc66dd15210b7e6c6106078
5
+ SHA512:
6
+ metadata.gz: fee8ee1cde9b266b761c4300e17d05354da618afcb04ed56462042fdff8ed2b5af8edf1459a6d66b59d7f8378199e907cd283530c83e469ea80744f62651ac2f
7
+ data.tar.gz: 869380ff05222788d77bb6be8fe24a68998d28734b53150f6aef5963bcd8cf3cd9e1749d79ee1cac84c77720515ec08ff3329282fb897d299d38e7d99436be37
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ jruby-1.7.6
data/Gemfile.lock CHANGED
@@ -8,7 +8,7 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- jruby_sandbox (0.1.2-java)
11
+ jruby_sandbox (0.2.0-java)
12
12
  fakefs
13
13
 
14
14
  GEM
@@ -17,11 +17,13 @@ import org.jruby.runtime.Block;
17
17
  import org.jruby.runtime.builtin.IRubyObject;
18
18
  import org.jruby.common.IRubyWarnings;
19
19
  import org.jruby.exceptions.RaiseException;
20
+ import org.jruby.runtime.DynamicScope;
20
21
 
21
22
 
22
23
  @JRubyClass(name="Sandbox::Full")
23
24
  public class SandboxFull extends RubyObject {
24
25
  private Ruby wrapped;
26
+ private DynamicScope currentScope;
25
27
 
26
28
  public SandboxFull(Ruby runtime, RubyClass type) {
27
29
  super(runtime, type);
@@ -45,6 +47,8 @@ public class SandboxFull extends RubyObject {
45
47
 
46
48
  RubyClass cBoxedClass = wrapped.defineClass("BoxedClass", wrapped.getObject(), wrapped.getObject().getAllocator());
47
49
  cBoxedClass.defineAnnotatedMethods(BoxedClass.class);
50
+
51
+ currentScope = wrapped.getCurrentContext().getCurrentScope();
48
52
 
49
53
  return this;
50
54
  }
@@ -52,7 +56,7 @@ public class SandboxFull extends RubyObject {
52
56
  @JRubyMethod(required=1)
53
57
  public IRubyObject eval(IRubyObject str) {
54
58
  try {
55
- IRubyObject result = wrapped.evalScriptlet(str.asJavaString(), wrapped.getCurrentContext().getCurrentScope());
59
+ IRubyObject result = wrapped.evalScriptlet(str.asJavaString(), currentScope);
56
60
  return unbox(result);
57
61
  } catch (RaiseException e) {
58
62
  String msg = e.getException().callMethod(wrapped.getCurrentContext(), "message").asJavaString();
@@ -107,29 +111,29 @@ public class SandboxFull extends RubyObject {
107
111
  // superclasses as well.
108
112
  sup = importClassPath(runtimeModule.getSuperClass().getName(), true);
109
113
  }
110
-
114
+
111
115
  RubyClass klass = (RubyClass) sup;
112
116
  if (wrappedModule == wrapped.getObject()) {
113
-
117
+
114
118
  if (link || runtimeModule instanceof RubyClass){ // if this is a ref and not an import
115
119
  wrappedModule = wrapped.defineClass(name, klass, klass.getAllocator());
116
120
  } else {
117
121
  wrappedModule = wrapped.defineModule(name);
118
122
  }
119
-
123
+
120
124
  } else {
121
125
  if (runtimeModule instanceof RubyClass){
122
126
  wrappedModule = wrappedModule.defineClassUnder(name, klass, klass.getAllocator());
123
127
  } else {
124
128
  wrappedModule = wrappedModule.defineModuleUnder(name);
125
129
  }
126
-
130
+
127
131
  }
128
132
  } else {
129
133
  // ...or just resolve it, if it was already known
130
134
  wrappedModule = (RubyModule) wrappedModule.getConstantAt(name);
131
135
  }
132
-
136
+
133
137
  // Check the consistency of the hierarchy
134
138
  if (runtimeModule instanceof RubyClass) {
135
139
  if (!link && !runtimeModule.getSuperClass().getName().equals(wrappedModule.getSuperClass().getName())) {
Binary file
@@ -1,3 +1,3 @@
1
1
  module Sandbox
2
- VERSION = '0.1.4'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/sandbox.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require 'sandbox/sandbox'
2
2
  require 'sandbox/version'
3
3
  require 'fakefs/safe'
4
- require 'timeout'
5
4
 
6
5
  module Sandbox
7
6
  PRELUDE = File.expand_path('../sandbox/prelude.rb', __FILE__).freeze # :nodoc:
7
+
8
+ TimeoutError = Class.new(Exception)
8
9
 
9
10
  class << self
10
11
  def new
@@ -19,7 +20,7 @@ module Sandbox
19
20
  class Safe < Full
20
21
  def activate!
21
22
  activate_fakefs
22
-
23
+
23
24
  keep_singleton_methods(:Kernel, KERNEL_S_METHODS)
24
25
  keep_singleton_methods(:Symbol, SYMBOL_S_METHODS)
25
26
  keep_singleton_methods(:String, STRING_S_METHODS)
@@ -33,62 +34,97 @@ module Sandbox
33
34
  keep_methods(:Enumerable, ENUMERABLE_METHODS)
34
35
  keep_methods(:String, STRING_METHODS)
35
36
  end
36
-
37
+
37
38
  def activate_fakefs
38
39
  require 'fileutils'
39
-
40
+
40
41
  # unfortunately, the authors of FakeFS used `extend self` in FileUtils, instead of `module_function`.
41
42
  # I fixed it for them
42
43
  (FakeFS::FileUtils.methods - Module.methods - Kernel.methods).each do |module_method_name|
43
44
  FakeFS::FileUtils.send(:module_function, module_method_name)
44
45
  end
45
-
46
+
46
47
  import FakeFS
47
48
  ref FakeFS::Dir
48
49
  ref FakeFS::File
49
50
  ref FakeFS::FileTest
50
51
  import FakeFS::FileUtils #import FileUtils because it is a module
51
-
52
+
53
+ # this is basically what FakeFS.activate! does, but we want to do it in the sandbox
54
+ # so we have to live with this:
52
55
  eval <<-RUBY
53
56
  Object.class_eval do
54
57
  remove_const(:Dir)
55
58
  remove_const(:File)
56
59
  remove_const(:FileTest)
57
60
  remove_const(:FileUtils)
58
-
61
+
59
62
  const_set(:Dir, FakeFS::Dir)
60
63
  const_set(:File, FakeFS::File)
61
64
  const_set(:FileUtils, FakeFS::FileUtils)
62
65
  const_set(:FileTest, FakeFS::FileTest)
66
+ end
63
67
 
64
- [Dir, File, FileUtils, FileTest].each do |fake_class|
65
- fake_class.class_eval do
66
- def self.class_eval
67
- raise NoMethodError, "class_eval is unavailable"
68
- end
69
- def self.instance_eval
70
- raise NoMethodError, "instance_eval is unavailable"
71
- end
68
+ [Dir, File, FileUtils, FileTest].each do |fake_class|
69
+ fake_class.class_eval do
70
+ def self.class_eval
71
+ raise NoMethodError, "class_eval is unavailable"
72
+ end
73
+ def self.instance_eval
74
+ raise NoMethodError, "instance_eval is unavailable"
72
75
  end
73
76
  end
74
77
  end
75
78
  RUBY
76
-
79
+
77
80
  FakeFS::FileSystem.clear
78
81
  end
79
-
80
- def eval_with_timeout(code, timeout=10)
81
- require 'timeout'
82
-
83
- timeout_code = <<-RUBY
84
- Timeout.timeout(#{timeout}) do
85
- #{code}
82
+
83
+ def eval(code, options={})
84
+
85
+ if seconds = options[:timeout]
86
+ sandbox_timeout(code, seconds) do
87
+ super code
86
88
  end
87
- RUBY
88
-
89
- eval timeout_code
89
+ else
90
+ super code
91
+ end
92
+
90
93
  end
91
-
94
+
95
+ private
96
+
97
+ def sandbox_timeout(name, seconds)
98
+ val, exc = nil
99
+
100
+ thread = Thread.start(name) do
101
+ begin
102
+ val = yield
103
+ rescue Exception => exc
104
+ end
105
+ end
106
+
107
+ thread.join(seconds)
108
+
109
+ if thread.alive?
110
+ if thread.respond_to? :kill!
111
+ thread.kill!
112
+ else
113
+ thread.kill
114
+ end
115
+
116
+ timed_out = true
117
+ end
118
+
119
+ if timed_out
120
+ raise TimeoutError, "#{self.class} timed out"
121
+ elsif exc
122
+ raise exc
123
+ else
124
+ val
125
+ end
126
+ end
127
+
92
128
  IO_S_METHODS = %w[
93
129
  new
94
130
  foreach
data/spec/sandbox_spec.rb CHANGED
@@ -23,7 +23,7 @@ describe Sandbox do
23
23
  subject.eval('`echo hello`').should == "hello\n"
24
24
 
25
25
  subject.activate!
26
-
26
+
27
27
  expect {
28
28
  subject.eval('`echo hello`')
29
29
  }.to raise_error(Sandbox::SandboxException)
@@ -55,7 +55,7 @@ describe Sandbox do
55
55
 
56
56
  expect {
57
57
  subject.eval(%{FileUtils.cp('/bar.txt', '/baz.txt')})
58
- }.to_not raise_error(Sandbox::SandboxException, /Sandbox::SandboxException: NoMethodError: /)
58
+ }.to_not raise_error(Sandbox::SandboxException, /NoMethodError/)
59
59
  end
60
60
  end
61
61
 
@@ -73,7 +73,7 @@ describe Sandbox do
73
73
  end
74
74
  end
75
75
 
76
- describe "#eval_with_timeout" do
76
+ describe "#eval with timeout" do
77
77
  subject { Sandbox.safe }
78
78
 
79
79
  context "before it's been activated" do
@@ -83,8 +83,18 @@ describe Sandbox do
83
83
  RUBY
84
84
 
85
85
  expect {
86
- subject.eval_with_timeout(long_code, 1)
87
- }.to raise_error(Sandbox::SandboxException, /Timeout/)
86
+ subject.eval(long_code, timeout: 1)
87
+ }.to raise_error(Sandbox::TimeoutError)
88
+ end
89
+
90
+ it "should not raise a timeout error if the code runs in under the passed in time" do
91
+ short_code = <<-RUBY
92
+ 1+1
93
+ RUBY
94
+
95
+ expect {
96
+ subject.eval(short_code, timeout: 1)
97
+ }.to_not raise_error(Sandbox::TimeoutError)
88
98
  end
89
99
  end
90
100
 
@@ -97,10 +107,16 @@ describe Sandbox do
97
107
  RUBY
98
108
 
99
109
  expect {
100
- Timeout.timeout(3) do
101
- subject.eval_with_timeout(long_code, 1)
102
- end
103
- }.to raise_error(Sandbox::SandboxException, /Timeout/)
110
+ subject.eval(long_code, timeout: 1)
111
+ }.to raise_error(Sandbox::TimeoutError)
112
+ end
113
+
114
+ it "should persist state between evaluations" do
115
+ subject.eval('o = Object.new', timeout: 1)
116
+
117
+ expect {
118
+ subject.eval('o', timeout: 1)
119
+ }.to_not raise_error(Sandbox::SandboxException)
104
120
  end
105
121
  end
106
122
  end
metadata CHANGED
@@ -1,97 +1,86 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jruby_sandbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: java
7
6
  authors:
8
7
  - Dray Lacy
9
8
  - Eric Allam
10
- autorequire:
9
+ autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-11-07 00:00:00.000000000 Z
12
+ date: 2013-11-08 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: fakefs
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
17
21
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
22
  requirements:
20
- - - ! '>='
23
+ - - '>='
21
24
  - !ruby/object:Gem::Version
22
25
  version: '0'
23
- type: :runtime
24
26
  prerelease: false
27
+ type: :runtime
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
25
30
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
31
  requirements:
28
- - - ! '>='
32
+ - - '>='
29
33
  - !ruby/object:Gem::Version
30
34
  version: '0'
31
- - !ruby/object:Gem::Dependency
32
- name: rake
33
35
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
36
  requirements:
36
- - - ! '>='
37
+ - - '>='
37
38
  - !ruby/object:Gem::Version
38
39
  version: '0'
39
- type: :development
40
40
  prerelease: false
41
+ type: :development
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake-compiler
41
44
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
45
  requirements:
44
- - - ! '>='
46
+ - - '>='
45
47
  - !ruby/object:Gem::Version
46
48
  version: '0'
47
- - !ruby/object:Gem::Dependency
48
- name: rake-compiler
49
49
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
50
  requirements:
52
- - - ! '>='
51
+ - - '>='
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
55
- type: :development
56
54
  prerelease: false
55
+ type: :development
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
57
58
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
59
  requirements:
60
- - - ! '>='
60
+ - - '>='
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
- - !ruby/object:Gem::Dependency
64
- name: rspec
65
63
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
64
  requirements:
68
- - - ! '>='
65
+ - - '>='
69
66
  - !ruby/object:Gem::Version
70
67
  version: '0'
71
- type: :development
72
68
  prerelease: false
69
+ type: :development
70
+ - !ruby/object:Gem::Dependency
71
+ name: yard
73
72
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
73
  requirements:
76
- - - ! '>='
74
+ - - '>='
77
75
  - !ruby/object:Gem::Version
78
76
  version: '0'
79
- - !ruby/object:Gem::Dependency
80
- name: yard
81
77
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
78
  requirements:
84
- - - ! '>='
79
+ - - '>='
85
80
  - !ruby/object:Gem::Version
86
81
  version: '0'
87
- type: :development
88
82
  prerelease: false
89
- version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
- requirements:
92
- - - ! '>='
93
- - !ruby/object:Gem::Version
94
- version: '0'
83
+ type: :development
95
84
  description: A version of _why's Freaky Freaky Sandbox for JRuby.
96
85
  email:
97
86
  - dray@envylabs.com
@@ -101,6 +90,7 @@ extensions: []
101
90
  extra_rdoc_files: []
102
91
  files:
103
92
  - .gitignore
93
+ - .ruby-version
104
94
  - .rvmrc
105
95
  - Gemfile
106
96
  - Gemfile.lock
@@ -122,30 +112,28 @@ files:
122
112
  - lib/sandbox/sandbox.jar
123
113
  homepage: http://github.com/omghax/jruby-sandbox
124
114
  licenses: []
125
- post_install_message:
115
+ metadata: {}
116
+ post_install_message:
126
117
  rdoc_options: []
127
118
  require_paths:
128
119
  - lib
129
120
  required_ruby_version: !ruby/object:Gem::Requirement
130
- none: false
131
121
  requirements:
132
- - - ! '>='
122
+ - - '>='
133
123
  - !ruby/object:Gem::Version
134
124
  version: '0'
135
125
  required_rubygems_version: !ruby/object:Gem::Requirement
136
- none: false
137
126
  requirements:
138
- - - ! '>='
127
+ - - '>='
139
128
  - !ruby/object:Gem::Version
140
129
  version: '0'
141
130
  requirements: []
142
131
  rubyforge_project: jruby_sandbox
143
- rubygems_version: 1.8.23
144
- signing_key:
145
- specification_version: 3
132
+ rubygems_version: 2.1.9
133
+ signing_key:
134
+ specification_version: 4
146
135
  summary: Sandbox support for JRuby
147
136
  test_files:
148
137
  - spec/exploits_spec.rb
149
138
  - spec/sandbox_spec.rb
150
139
  - spec/support/foo.txt
151
- has_rdoc: