ruby_box 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module MiniRacer
2
+ VERSION = "0.1.4"
3
+ end
@@ -0,0 +1,261 @@
1
+ require "mini_racer/version"
2
+ require "mini_racer_extension"
3
+ require "thread"
4
+
5
+ module MiniRacer
6
+
7
+ class EvalError < StandardError; end
8
+ class ScriptTerminatedError < EvalError; end
9
+ class ParseError < EvalError; end
10
+ class SnapshotError < StandardError; end
11
+ class PlatformAlreadyInitialized < StandardError; end
12
+
13
+ class FailedV8Conversion
14
+ attr_reader :info
15
+ def initialize(info)
16
+ @info = info
17
+ end
18
+ end
19
+
20
+ class RuntimeError < EvalError
21
+ def initialize(message)
22
+ message, js_backtrace = message.split("\n", 2)
23
+ if js_backtrace && !js_backtrace.empty?
24
+ @js_backtrace = js_backtrace.split("\n")
25
+ @js_backtrace.map!{|f| "JavaScript #{f.strip}"}
26
+ else
27
+ @js_backtrace = nil
28
+ end
29
+ super(message)
30
+ end
31
+
32
+ def backtrace
33
+ val = super
34
+ return unless val
35
+ if @js_backtrace
36
+ @js_backtrace + val
37
+ else
38
+ val
39
+ end
40
+ end
41
+ end
42
+
43
+ # helper class returned when we have a JavaScript function
44
+ class JavaScriptFunction
45
+ def to_s
46
+ "JavaScript Function"
47
+ end
48
+ end
49
+
50
+ class Isolate
51
+ def initialize(snapshot = nil)
52
+ unless snapshot.nil? || snapshot.is_a?(Snapshot)
53
+ raise ArgumentError, "snapshot must be a Snapshot object, passed a #{snapshot.inspect}"
54
+ end
55
+
56
+ @lock = Mutex.new
57
+
58
+ # defined in the C class
59
+ init_with_snapshot(snapshot)
60
+ end
61
+
62
+ def with_lock
63
+ @lock.synchronize { yield }
64
+ end
65
+ end
66
+
67
+ class Platform
68
+ class << self
69
+ def set_flags!(*args, **kwargs)
70
+ flags_to_strings([args, kwargs]).each do |flag|
71
+ # defined in the C class
72
+ set_flag_as_str!(flag)
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def flags_to_strings(flags)
79
+ flags.flatten.map { |flag| flag_to_string(flag) }.flatten
80
+ end
81
+
82
+ # normalize flags to strings, and adds leading dashes if needed
83
+ def flag_to_string(flag)
84
+ if flag.is_a?(Hash)
85
+ flag.map do |key, value|
86
+ "#{flag_to_string(key)} #{value}"
87
+ end
88
+ else
89
+ str = flag.to_s
90
+ str = "--#{str}" unless str.start_with?('--')
91
+ str
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ # eval is defined in the C class
98
+ class Context
99
+
100
+ class ExternalFunction
101
+ def initialize(name, callback, parent)
102
+ unless String === name
103
+ raise ArgumentError, "parent_object must be a String"
104
+ end
105
+ parent_object, _ , @name = name.rpartition(".")
106
+ @callback = callback
107
+ @parent = parent
108
+ @parent_object_eval = nil
109
+ @parent_object = nil
110
+
111
+ unless parent_object.empty?
112
+ @parent_object = parent_object
113
+
114
+ @parent_object_eval = ""
115
+ prev = ""
116
+ first = true
117
+ parent_object.split(".").each do |obj|
118
+ prev << obj
119
+ if first
120
+ @parent_object_eval << "if (typeof #{prev} === 'undefined') { #{prev} = {} };\n"
121
+ else
122
+ @parent_object_eval << "#{prev} = #{prev} || {};\n"
123
+ end
124
+ prev << "."
125
+ first = false
126
+ end
127
+ @parent_object_eval << "#{parent_object};"
128
+ end
129
+ notify_v8
130
+ end
131
+ end
132
+
133
+ attr_reader :isolate
134
+
135
+ def initialize(options = nil)
136
+ options ||= {}
137
+
138
+ check_init_options!(options)
139
+
140
+ @functions = {}
141
+ @timeout = nil
142
+ @current_exception = nil
143
+ @timeout = options[:timeout]
144
+ @isolate = options[:isolate] || Isolate.new(options[:snapshot])
145
+
146
+ @callback_mutex = Mutex.new
147
+ @callback_running = false
148
+ @thread_raise_called = false
149
+ @eval_thread = nil
150
+
151
+ isolate.with_lock do
152
+ # defined in the C class
153
+ init_with_isolate(@isolate)
154
+ end
155
+ end
156
+
157
+ def load(filename)
158
+ # TODO do this native cause no need to allocate VALUE here
159
+ eval(File.read(filename))
160
+ end
161
+
162
+ def eval(str)
163
+ @eval_thread = Thread.current
164
+ isolate.with_lock do
165
+ @current_exception = nil
166
+ timeout do
167
+ eval_unsafe(str)
168
+ end
169
+ end
170
+ ensure
171
+ @eval_thread = nil
172
+ end
173
+
174
+
175
+ def attach(name, callback)
176
+
177
+ wrapped = lambda do |*args|
178
+ begin
179
+ @callback_mutex.synchronize{
180
+ @callback_running = true
181
+ }
182
+
183
+ callback.call(*args)
184
+ ensure
185
+ @callback_mutex.synchronize {
186
+ @callback_running = false
187
+
188
+ # this is some odd code, but it is required
189
+ # if we raised on this thread we better wait for it
190
+ # otherwise we may end up raising in an unsafe spot
191
+ if @thread_raise_called
192
+ sleep 0.1
193
+ end
194
+ @thread_raise_called = false
195
+ }
196
+ end
197
+ end
198
+
199
+ isolate.with_lock do
200
+ external = ExternalFunction.new(name, wrapped, self)
201
+ @functions["#{name}"] = external
202
+ end
203
+ end
204
+
205
+ private
206
+
207
+ def stop_attached
208
+ @callback_mutex.synchronize{
209
+ if @callback_running
210
+ @eval_thread.raise ScriptTerminatedError, "Terminated during callback"
211
+ @thread_raise_called = true
212
+ end
213
+ }
214
+ end
215
+
216
+ def timeout(&blk)
217
+ return blk.call unless @timeout
218
+
219
+ _,wp = IO.pipe
220
+
221
+ Thread.new do
222
+ begin
223
+ result = IO.select([wp],[],[],(@timeout/1000.0))
224
+ if !result
225
+ stop
226
+ end
227
+ rescue
228
+ STDERR.puts "FAILED TO TERMINATE DUE TO TIMEOUT"
229
+ end
230
+ end
231
+
232
+ rval = blk.call
233
+ wp.write("done")
234
+
235
+ rval
236
+ end
237
+
238
+ def check_init_options!(options)
239
+ assert_option_is_nil_or_a('isolate', options[:isolate], Isolate)
240
+ assert_option_is_nil_or_a('snapshot', options[:snapshot], Snapshot)
241
+
242
+ if options[:isolate] && options[:snapshot]
243
+ raise ArgumentError, 'can only pass one of isolate and snapshot options'
244
+ end
245
+ end
246
+
247
+ def assert_option_is_nil_or_a(option_name, object, klass)
248
+ unless object.nil? || object.is_a?(klass)
249
+ raise ArgumentError, "#{option_name} must be a #{klass} object, passed a #{object.inspect}"
250
+ end
251
+ end
252
+ end
253
+
254
+ # `size` and `warmup!` public methods are defined in the C class
255
+ class Snapshot
256
+ def initialize(str = '')
257
+ # defined in the C class
258
+ load(str)
259
+ end
260
+ end
261
+ end
metadata ADDED
@@ -0,0 +1,205 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_box
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Alec Larsen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: libv8
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake-compiler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: opal
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.10'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '4.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.10'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: codeclimate-test-reporter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: benchmark-ips
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description:
154
+ email:
155
+ - aleclarsen42@gmail.com
156
+ executables: []
157
+ extensions:
158
+ - vendor/gems/mini_racer/ext/mini_racer_extension/extconf.rb
159
+ extra_rdoc_files: []
160
+ files:
161
+ - lib/ruby_box.rb
162
+ - lib/ruby_box/bindings.rb
163
+ - lib/ruby_box/boxed_error.rb
164
+ - lib/ruby_box/bridging.rb
165
+ - lib/ruby_box/compilation_error.rb
166
+ - lib/ruby_box/error.rb
167
+ - lib/ruby_box/execution.rb
168
+ - lib/ruby_box/execution_error.rb
169
+ - lib/ruby_box/metal.rb
170
+ - lib/ruby_box/runtime_environment.rb
171
+ - lib/ruby_box/thread_safety.rb
172
+ - lib/ruby_box/timeout_error.rb
173
+ - lib/ruby_box/version.rb
174
+ - vendor/gems/mini_racer/ext/mini_racer_extension/extconf.rb
175
+ - vendor/gems/mini_racer/ext/mini_racer_extension/mini_racer_extension.cc
176
+ - vendor/gems/mini_racer/lib/mini_racer.rb
177
+ - vendor/gems/mini_racer/lib/mini_racer/version.rb
178
+ - vendor/gems/mini_racer/lib/mini_racer_extension.bundle
179
+ homepage: https://github.com/anarchocurious/ruby_box
180
+ licenses:
181
+ - MIT
182
+ metadata: {}
183
+ post_install_message:
184
+ rdoc_options: []
185
+ require_paths:
186
+ - lib
187
+ - vendor/gems/mini_racer/lib
188
+ - vendor/gems/mini_racer/ext
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: 2.3.0
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project:
201
+ rubygems_version: 2.5.1
202
+ signing_key:
203
+ specification_version: 4
204
+ summary: RubyBox allows the execution of untrusted Ruby code safely in a sandbox.
205
+ test_files: []