jruby_sandbox 0.1.4-java → 0.2.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: