Class: Shikashi::Sandbox
- Inherits:
-
Object
- Object
- Shikashi::Sandbox
- Defined in:
- lib/shikashi/sandbox.rb
Overview
The sandbox class run the sandbox, because of internal behaviour only can be use one instance of sandbox by thread (each different thread may have its own sandbox running in the same time)
Example
require “rubygems” require “shikashi”
include Shikashi
s = Sandbox.new priv = Privileges.new priv.allow_method :print
s.run(priv, ‘print “hello worldn”’)
Defined Under Namespace
Classes: EvalhookHandler, Packet
Instance Attribute Summary collapse
-
#chain ⇒ Object
readonly
Binding of execution, the default is a binding in a global context allowing the definition of module of classes.
-
#hook_handler ⇒ Object
readonly
Returns the value of attribute hook_handler.
-
#privileges ⇒ Object
readonly
array of privileges of restricted code within sandbox.
Class Method Summary collapse
-
.run(*args) ⇒ Object
Same as Sandbox.new.run.
Instance Method Summary collapse
-
#add_source_chain(outer, inner) ⇒ Object
add a chain of sources, used internally.
- #base_namespace ⇒ Object
- #create_hook_handler(*args) ⇒ Object
- #dispose ⇒ Object
- #generate_id ⇒ Object
-
#initialize ⇒ Sandbox
constructor
A new instance of Sandbox.
-
#packet(*args) ⇒ Object
Creates a packet of code with the given privileges to execute later as many times as neccessary.
-
#run(*args) ⇒ Object
Run the code in sandbox with the given privileges (see examples).
Constructor Details
#initialize ⇒ Sandbox
Returns a new instance of Sandbox.
87 88 89 90 91 92 93 94 95 |
# File 'lib/shikashi/sandbox.rb', line 87 def initialize @privileges = Hash.new @chain = Hash.new @hook_handler_list = Array.new @hook_handler = instantiate_evalhook_handler @hook_handler.sandbox = self @base_namespace = create_adhoc_base_namespace @hook_handler.base_namespace = @base_namespace end |
Instance Attribute Details
#chain ⇒ Object (readonly)
Binding of execution, the default is a binding in a global context allowing the definition of module of classes
68 69 70 |
# File 'lib/shikashi/sandbox.rb', line 68 def chain @chain end |
#hook_handler ⇒ Object (readonly)
Returns the value of attribute hook_handler.
70 71 72 |
# File 'lib/shikashi/sandbox.rb', line 70 def hook_handler @hook_handler end |
#privileges ⇒ Object (readonly)
array of privileges of restricted code within sandbox
Example sandbox.privileges.allow_method :raise
66 67 68 |
# File 'lib/shikashi/sandbox.rb', line 66 def privileges @privileges end |
Class Method Details
.run(*args) ⇒ Object
Same as Sandbox.new.run
76 77 78 |
# File 'lib/shikashi/sandbox.rb', line 76 def self.run(*args) Sandbox.new.run(Shikashi.global_binding, *args) end |
Instance Method Details
#add_source_chain(outer, inner) ⇒ Object
add a chain of sources, used internally
98 99 100 |
# File 'lib/shikashi/sandbox.rb', line 98 def add_source_chain(outer, inner) @chain[inner] = outer end |
#base_namespace ⇒ Object
102 103 104 |
# File 'lib/shikashi/sandbox.rb', line 102 def base_namespace @base_namespace end |
#create_hook_handler(*args) ⇒ Object
419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/shikashi/sandbox.rb', line 419 def create_hook_handler(*args) hook_handler = instantiate_evalhook_handler hook_handler.sandbox = self @base_namespace = args.pick(:base_namespace) do create_adhoc_base_namespace end hook_handler.base_namespace = @base_namespace source = args.pick(:source) do generate_id end privileges_ = args.pick(Privileges,:privileges) do Privileges.new end self.privileges[source] = privileges_ hook_handler end |
#dispose ⇒ Object
433 434 435 |
# File 'lib/shikashi/sandbox.rb', line 433 def dispose @hook_handler_list.each(&:dispose) end |
#generate_id ⇒ Object
83 84 85 |
# File 'lib/shikashi/sandbox.rb', line 83 def generate_id "sandbox-#{rand(1000000)}" end |
#packet(*args) ⇒ Object
Creates a packet of code with the given privileges to execute later as many times as neccessary
(see examples)
Arguments
:code Mandatory argument of class String with the code to execute restricted in the sandbox :privileges Optional argument of class Shikashi::Sandbox::Privileges to indicate the restrictions of the
code executed in the sandbox. The default is an empty Privileges (absolutly no permission)
Must be of class Privileges or passed as hash_key (:privileges => privileges)
:source Optional argument to indicate the “source name”, (visible in the backtraces). Only can
be specified as hash parameter
:base_namespace Alternate module to contain all classes and constants defined by the unprivileged code
if not specified, by default, the base_namespace is created with the sandbox itself
:no_base_namespace Specify to do not use a base_namespace (default false, not recommended to change) :encoding Specify the encoding of source (example: “utf-8”), the encoding also can be
specified on header like a ruby normal source file
NOTE: arguments are the same as for Sandbox#run method, except for timeout and binding which can be used when calling Shikashi::Sandbox::Packet#run
Example:
require “rubygems” require “shikashi”
include Shikashi
sandbox = Sandbox.new
privileges = Privileges.allow_method(:print)
# this is equivallent to sandbox.run(‘print “hello worldn”’) packet = sandbox.packet(‘print “hello worldn”’, privileges) packet.run
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/shikashi/sandbox.rb', line 380 def packet(*args) code = args.pick(String,:code) base_namespace = args.pick(:base_namespace) do nil end no_base_namespace = args.pick(:no_base_namespace) do @no_base_namespace end privileges_ = args.pick(Privileges,:privileges) do Privileges.new end encoding = get_source_encoding(code) || args.pick(:encoding) do nil end hook_handler = nil if base_namespace hook_handler = instantiate_evalhook_handler hook_handler.base_namespace = base_namespace hook_handler.sandbox = self else hook_handler = @hook_handler base_namespace = hook_handler.base_namespace end source = args.pick(:source) do generate_id end self.privileges[source] = privileges_ code = "nil;\n " + code unless no_base_namespace if (eval(base_namespace.to_s).instance_of? Module) code = "module #{base_namespace}\n #{code}\n end\n" else code = "class #{base_namespace}\n #{code}\n end\n" end end if encoding code = "# encoding: #{encoding}\n" + code end evalhook_packet = @hook_handler.packet(code) Shikashi::Sandbox::Packet.new(evalhook_packet, privileges_, source) end |
#run(*args) ⇒ Object
Run the code in sandbox with the given privileges (see examples)
Arguments
:code Mandatory argument of class String with the code to execute restricted in the sandbox :privileges Optional argument of class Shikashi::Sandbox::Privileges to indicate the restrictions of the
code executed in the sandbox. The default is an empty Privileges (absolutly no permission)
Must be of class Privileges or passed as hash_key (:privileges => privileges)
:binding Optional argument with the binding object of the context where the code is to be executed
The default is a binding in the global context
:source Optional argument to indicate the “source name”, (visible in the backtraces). Only can
be specified as hash parameter
:timeout Optional argument to restrict the execution time of the script to a given value in seconds
(accepts integer and decimal values), when timeout hits Shikashi::Timeout::Error is raised
:base_namespace Alternate module to contain all classes and constants defined by the unprivileged code
if not specified, by default, the base_namespace is created with the sandbox itself
:no_base_namespace Specify to do not use a base_namespace (default false, not recommended to change) :encoding Specify the encoding of source (example: “utf-8”), the encoding also can be
specified on header like a ruby normal source file
The arguments can be passed in any order and using hash notation or not, examples:
sandbox.run code, privileges sandbox.run code, :privileges => privileges sandbox.run :code => code, :privileges => privileges sandbox.run code, privileges, binding sandbox.run binding, code, privileges #etc sandbox.run binding, code, privileges, :source => source sandbox.run binding, :code => code, :privileges => privileges, :source => source
Example:
require “rubygems” require “shikashi”
include Shikashi
sandbox = Sandbox.new privileges = Privileges.new privileges.allow_method :print sandbox.run(‘print “hello worldn”’, :privileges => privileges)
Example 2: require “rubygems” require “shikashi”
include Shikashi
sandbox = Sandbox.new privileges = Privileges.new privileges.allow_method :print privileges.allow_method :singleton_method_added
sandbox.run(‘
def self.foo
print "hello world\n"
end
', :privileges => privileges)
340 341 342 |
# File 'lib/shikashi/sandbox.rb', line 340 def run(*args) run_i(*args) end |