jruby-safe 0.2.2-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.
@@ -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