jruby-safe 0.2.2-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,39 @@
1
+ package sandbox;
2
+
3
+ import org.jruby.Profile;
4
+ import org.jruby.Ruby;
5
+ import org.jruby.RubyClass;
6
+ import org.jruby.RubyModule;
7
+ import org.jruby.anno.JRubyClass;
8
+ import org.jruby.anno.JRubyMethod;
9
+ import org.jruby.runtime.builtin.IRubyObject;
10
+
11
+ public class SandboxModule {
12
+ /**
13
+ * Create the Sandbox module and add it to the Ruby runtime.
14
+ */
15
+ public static RubyModule createSandboxModule(final Ruby runtime) {
16
+ RubyModule mSandbox = runtime.defineModule("Sandbox");
17
+ mSandbox.defineAnnotatedMethods(SandboxModule.class);
18
+
19
+ RubyClass cObject = runtime.getObject();
20
+ RubyClass cSandboxFull = mSandbox.defineClassUnder("Full", cObject, SandboxFull.FULL_ALLOCATOR);
21
+ cSandboxFull.defineAnnotatedMethods(SandboxFull.class);
22
+ RubyClass cStandardError = runtime.getStandardError();
23
+ RubyClass cSandboxException = mSandbox.defineClassUnder("SandboxException", cStandardError, cStandardError.getAllocator());
24
+
25
+ return mSandbox;
26
+ }
27
+
28
+ @JRubyClass(name="Sandbox::SandboxException", parent="StandardError")
29
+ public static class SandboxException {}
30
+
31
+ @JRubyMethod(name="current", meta=true)
32
+ public static IRubyObject s_current(IRubyObject recv) {
33
+ Profile prof = recv.getRuntime().getProfile();
34
+ if (prof instanceof SandboxProfile) {
35
+ return ((SandboxProfile) prof).getSandbox();
36
+ }
37
+ return recv.getRuntime().getNil();
38
+ }
39
+ }
@@ -0,0 +1,22 @@
1
+ package sandbox;
2
+
3
+ import org.jruby.Profile;
4
+ import org.jruby.runtime.builtin.IRubyObject;
5
+
6
+ public class SandboxProfile implements Profile {
7
+ private IRubyObject sandbox;
8
+
9
+ public SandboxProfile(IRubyObject sandbox) {
10
+ this.sandbox = sandbox;
11
+ }
12
+
13
+ public IRubyObject getSandbox() {
14
+ return sandbox;
15
+ }
16
+
17
+ public boolean allowBuiltin(String name) { return true; }
18
+ public boolean allowClass(String name) { return true; }
19
+ public boolean allowModule(String name) { return true; }
20
+ public boolean allowLoad(String name) { return true; }
21
+ public boolean allowRequire(String name) { return true; }
22
+ }
@@ -0,0 +1,17 @@
1
+ package sandbox;
2
+
3
+ import java.io.IOException;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.runtime.load.BasicLibraryService;
7
+
8
+ public class SandboxService implements BasicLibraryService {
9
+ public boolean basicLoad(Ruby runtime) throws IOException {
10
+ init(runtime);
11
+ return true;
12
+ }
13
+
14
+ private void init(Ruby runtime) {
15
+ SandboxModule.createSandboxModule(runtime);
16
+ }
17
+ }
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sandbox/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "jruby-safe"
7
+ s.version = Sandbox::VERSION
8
+ s.platform = "java"
9
+ s.authors = ["Kazuhiro yamada"]
10
+ s.email = ["yamadakazu45@gmail.com"]
11
+ s.homepage = "http://github.com/k-yamada/jruby-safe"
12
+ s.summary = "Sandbox support for JRuby"
13
+ s.description = "A version of _why's Freaky Freaky Sandbox for JRuby."
14
+
15
+ s.files = `git ls-files`.split("\n") + ["lib/sandbox/sandbox.jar"]
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency "fakefs"
21
+
22
+ s.add_development_dependency "rake"
23
+ s.add_development_dependency "rake-compiler"
24
+ s.add_development_dependency "rspec"
25
+ s.add_development_dependency "yard"
26
+ end
data/lib/jruby-safe.rb ADDED
@@ -0,0 +1 @@
1
+ require 'sandbox'
data/lib/sandbox.rb ADDED
@@ -0,0 +1,18 @@
1
+ require "sandbox/binding"
2
+ require "sandbox/sandbox"
3
+ require "sandbox/version"
4
+ require "sandbox/safe"
5
+
6
+ module Sandbox
7
+ PRELUDE = File.expand_path("../sandbox/prelude.rb", __FILE__).freeze # :nodoc:
8
+
9
+ class << self
10
+ def new
11
+ Full.new
12
+ end
13
+
14
+ def safe
15
+ Safe.new
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ class Binding
2
+ # Returns the value of some variable.
3
+ #
4
+ # a = 2
5
+ # binding["a"] #=> 2
6
+ #
7
+ def [](x)
8
+ if RUBY_VERSION.to_f > 2.1
9
+ local_variable_get(x)
10
+ else
11
+ eval(x.to_s)
12
+ end
13
+ end
14
+
15
+ # Set the value of a local variable.
16
+ #
17
+ # b = binding
18
+ # b["a"] = 4
19
+ # eval("a", b) #=> 4
20
+ def []=(l, v)
21
+ if RUBY_VERSION.to_f > 2.1
22
+ local_variable_set(l, v)
23
+ else
24
+ eval("#{l} = nil; lambda {|v| #{l} = v}").call(v)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # Alternate "safer" versions of Ruby methods. Mostly non-blocking.
2
+ [Fixnum, Bignum, Float].each do |klass|
3
+ klass.class_eval do
4
+ # A very weak version of pow, it doesn't work on Floats, but it's gonna
5
+ # fill the most common uses for now.
6
+ def **(x)
7
+ case x
8
+ when 0; 1
9
+ when 1; self
10
+ else
11
+ y = 1
12
+ while 0 <= (x -= 1) do
13
+ y *= self
14
+ end
15
+ y
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,397 @@
1
+ require "fakefs/safe"
2
+
3
+ module Sandbox
4
+ TimeoutError = Class.new(Exception)
5
+
6
+ class Safe < Full
7
+ def activate!
8
+ activate_fakefs
9
+
10
+ keep_singleton_methods(:Kernel, KERNEL_S_METHODS)
11
+ keep_singleton_methods(:Symbol, SYMBOL_S_METHODS)
12
+ keep_singleton_methods(:String, STRING_S_METHODS)
13
+ keep_singleton_methods(:IO, IO_S_METHODS)
14
+
15
+ keep_methods(:Kernel, KERNEL_METHODS)
16
+ keep_methods(:NilClass, NILCLASS_METHODS)
17
+ keep_methods(:Symbol, SYMBOL_METHODS)
18
+ keep_methods(:TrueClass, TRUECLASS_METHODS)
19
+ keep_methods(:FalseClass, FALSECLASS_METHODS)
20
+ keep_methods(:Enumerable, ENUMERABLE_METHODS)
21
+ keep_methods(:String, STRING_METHODS)
22
+
23
+ Kernel.class_eval do
24
+ def `(*args) # `<- fix highlight by editor
25
+ raise NoMethodError, "` is unavailable"
26
+ end
27
+
28
+ def system(*args)
29
+ raise NoMethodError, "system is unavailable"
30
+ end
31
+ end
32
+ end
33
+
34
+ def activate_fakefs
35
+ require "fileutils"
36
+
37
+ # unfortunately, the authors of FakeFS used `extend self` in FileUtils, instead of `module_function`.
38
+ # I fixed it for them
39
+ (FakeFS::FileUtils.methods - Module.methods - Kernel.methods).each do |module_method_name|
40
+ FakeFS::FileUtils.send(:module_function, module_method_name)
41
+ end
42
+
43
+ import FakeFS
44
+ ref FakeFS::Dir
45
+ ref FakeFS::File
46
+ ref FakeFS::FileTest
47
+ import FakeFS::FileUtils #import FileUtils because it is a module
48
+
49
+ # this is basically what FakeFS.activate! does, but we want to do it in the sandbox
50
+ # so we have to live with this:
51
+ eval <<-RUBY
52
+ Object.class_eval do
53
+ remove_const(:Dir)
54
+ remove_const(:File)
55
+ remove_const(:FileTest)
56
+ remove_const(:FileUtils)
57
+
58
+ const_set(:Dir, FakeFS::Dir)
59
+ const_set(:File, FakeFS::File)
60
+ const_set(:FileUtils, FakeFS::FileUtils)
61
+ const_set(:FileTest, FakeFS::FileTest)
62
+ end
63
+
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
72
+ end
73
+ end
74
+ RUBY
75
+
76
+ FakeFS::FileSystem.clear
77
+ end
78
+
79
+ def eval(code, options={})
80
+ if options.is_a?(Binding)
81
+ eval_with_binding(code, options)
82
+ elsif seconds = options[:timeout]
83
+ sandbox_timeout(code, seconds) do
84
+ super code
85
+ end
86
+ else
87
+ super code
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def sandbox_timeout(name, seconds)
94
+ val, exc = nil
95
+
96
+ thread = Thread.start(name) do
97
+ begin
98
+ val = yield
99
+ rescue Exception => exc
100
+ end
101
+ end
102
+
103
+ thread.join(seconds)
104
+
105
+ if thread.alive?
106
+ if thread.respond_to? :kill!
107
+ thread.kill!
108
+ else
109
+ thread.kill
110
+ end
111
+
112
+ timed_out = true
113
+ end
114
+
115
+ if timed_out
116
+ raise TimeoutError, "#{self.class} timed out"
117
+ elsif exc
118
+ raise exc
119
+ else
120
+ val
121
+ end
122
+ end
123
+
124
+ IO_S_METHODS = %w[
125
+ new
126
+ foreach
127
+ open
128
+ ]
129
+
130
+ KERNEL_S_METHODS = %w[
131
+ Array
132
+ binding
133
+ block_given?
134
+ catch
135
+ chomp
136
+ chomp!
137
+ chop
138
+ chop!
139
+ eval
140
+ fail
141
+ Float
142
+ format
143
+ global_variables
144
+ gsub
145
+ gsub!
146
+ Integer
147
+ iterator?
148
+ lambda
149
+ local_variables
150
+ loop
151
+ method_missing
152
+ proc
153
+ raise
154
+ scan
155
+ split
156
+ sprintf
157
+ String
158
+ sub
159
+ sub!
160
+ throw
161
+ ].freeze
162
+
163
+ SYMBOL_S_METHODS = %w[
164
+ all_symbols
165
+ ].freeze
166
+
167
+ STRING_S_METHODS = %w[
168
+ new
169
+ ].freeze
170
+
171
+ KERNEL_METHODS = %w[
172
+ ==
173
+ ===
174
+ =~
175
+ Array
176
+ binding
177
+ block_given?
178
+ catch
179
+ chomp
180
+ chomp!
181
+ chop
182
+ chop!
183
+ class
184
+ clone
185
+ dup
186
+ eql?
187
+ equal?
188
+ eval
189
+ fail
190
+ Float
191
+ format
192
+ freeze
193
+ frozen?
194
+ global_variables
195
+ gsub
196
+ gsub!
197
+ hash
198
+ id
199
+ initialize_copy
200
+ inspect
201
+ instance_eval
202
+ instance_of?
203
+ instance_variables
204
+ instance_variable_get
205
+ instance_variable_set
206
+ instance_variable_defined?
207
+ Integer
208
+ is_a?
209
+ iterator?
210
+ kind_of?
211
+ lambda
212
+ local_variables
213
+ loop
214
+ methods
215
+ method_missing
216
+ nil?
217
+ private_methods
218
+ print
219
+ proc
220
+ protected_methods
221
+ public_methods
222
+ raise
223
+ remove_instance_variable
224
+ respond_to?
225
+ respond_to_missing?
226
+ scan
227
+ send
228
+ singleton_methods
229
+ singleton_method_added
230
+ singleton_method_removed
231
+ singleton_method_undefined
232
+ split
233
+ sprintf
234
+ String
235
+ sub
236
+ sub!
237
+ taint
238
+ tainted?
239
+ throw
240
+ to_a
241
+ to_s
242
+ type
243
+ untaint
244
+ __send__
245
+ ].freeze
246
+
247
+ NILCLASS_METHODS = %w[
248
+ &
249
+ inspect
250
+ nil?
251
+ to_a
252
+ to_f
253
+ to_i
254
+ to_s
255
+ ^
256
+ |
257
+ ].freeze
258
+
259
+ SYMBOL_METHODS = %w[
260
+ ===
261
+ id2name
262
+ inspect
263
+ to_i
264
+ to_int
265
+ to_s
266
+ to_sym
267
+ ].freeze
268
+
269
+ TRUECLASS_METHODS = %w[
270
+ &
271
+ to_s
272
+ ^
273
+ |
274
+ ].freeze
275
+
276
+ FALSECLASS_METHODS = %w[
277
+ &
278
+ to_s
279
+ ^
280
+ |
281
+ ].freeze
282
+
283
+ ENUMERABLE_METHODS = %w[
284
+ all?
285
+ any?
286
+ collect
287
+ detect
288
+ each_with_index
289
+ entries
290
+ find
291
+ find_all
292
+ grep
293
+ include?
294
+ inject
295
+ map
296
+ max
297
+ member?
298
+ min
299
+ partition
300
+ reject
301
+ select
302
+ sort
303
+ sort_by
304
+ to_a
305
+ zip
306
+ ].freeze
307
+
308
+ STRING_METHODS = %w[
309
+ %
310
+ *
311
+ +
312
+ <<
313
+ <=>
314
+ ==
315
+ =~
316
+ capitalize
317
+ capitalize!
318
+ casecmp
319
+ center
320
+ chomp
321
+ chomp!
322
+ chop
323
+ chop!
324
+ concat
325
+ count
326
+ crypt
327
+ delete
328
+ delete!
329
+ downcase
330
+ downcase!
331
+ dump
332
+ each
333
+ each_byte
334
+ each_line
335
+ empty?
336
+ eql?
337
+ gsub
338
+ gsub!
339
+ hash
340
+ hex
341
+ include?
342
+ index
343
+ initialize
344
+ initialize_copy
345
+ insert
346
+ inspect
347
+ intern
348
+ length
349
+ ljust
350
+ lines
351
+ lstrip
352
+ lstrip!
353
+ match
354
+ next
355
+ next!
356
+ oct
357
+ replace
358
+ reverse
359
+ reverse!
360
+ rindex
361
+ rjust
362
+ rstrip
363
+ rstrip!
364
+ scan
365
+ size
366
+ slice
367
+ slice!
368
+ split
369
+ squeeze
370
+ squeeze!
371
+ strip
372
+ strip!
373
+ start_with?
374
+ sub
375
+ sub!
376
+ succ
377
+ succ!
378
+ sum
379
+ swapcase
380
+ swapcase!
381
+ to_f
382
+ to_i
383
+ to_s
384
+ to_str
385
+ to_sym
386
+ tr
387
+ tr!
388
+ tr_s
389
+ tr_s!
390
+ upcase
391
+ upcase!
392
+ upto
393
+ []
394
+ []=
395
+ ].freeze
396
+ end
397
+ end