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.
- checksums.yaml +7 -0
- data/lib/ruby_box/bindings.rb +39 -0
- data/lib/ruby_box/boxed_error.rb +15 -0
- data/lib/ruby_box/bridging.rb +119 -0
- data/lib/ruby_box/compilation_error.rb +6 -0
- data/lib/ruby_box/error.rb +6 -0
- data/lib/ruby_box/execution.rb +62 -0
- data/lib/ruby_box/execution_error.rb +6 -0
- data/lib/ruby_box/metal.rb +15 -0
- data/lib/ruby_box/runtime_environment.rb +75 -0
- data/lib/ruby_box/thread_safety.rb +97 -0
- data/lib/ruby_box/timeout_error.rb +6 -0
- data/lib/ruby_box/version.rb +3 -0
- data/lib/ruby_box.rb +29 -0
- data/vendor/gems/mini_racer/ext/mini_racer_extension/extconf.rb +54 -0
- data/vendor/gems/mini_racer/ext/mini_racer_extension/mini_racer_extension.cc +910 -0
- data/vendor/gems/mini_racer/lib/mini_racer/version.rb +3 -0
- data/vendor/gems/mini_racer/lib/mini_racer.rb +261 -0
- data/vendor/gems/mini_racer/lib/mini_racer_extension.bundle +0 -0
- metadata +205 -0
@@ -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
|
Binary file
|
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: []
|