ruby_box 0.0.0

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,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: []