How Can I Use It?


Example from documentation

use Safe;

$compartment = new Safe;

$compartment->permit(qw(time sort :browse));

$result = $compartment->reval($unsafe_code);


Discussion of example

Obviously, it is object oriented. The object is the ``compartment'' in which to run the code.

The permit method opens up access to the specified operators in addition to any already permitted. Some operators are allowed by default. It also uses an operator tag to specify a group of operators to allow. Note that the operators allowed by default are specified by the :default tag. For more information on operator names, tags, and sets, see the Opcode module's documentation.

The reval method evaluates the code in $unsafe_code in a new namespace. Note that since nothing was shared with the compartment that the only identifiers available to the compartment are the ``underscore'' variables (e.g. $_ and @_).


Failure

What happens if the code evaluated tries to access a name or operator that has not been allowed?

Name
If access of a name that is not internal and has not been shared is attempted, then the evaluation will abort and return the error message in $@. Example:

Unable to create sub named "*Safe::Root3::unshared" at /opt/TKLCelap/bin/rob_cmds line 1, <STDIN> chunk 7.

Operator
If access of an operator that has been masked is attempted, then the evaluation will abort and return the error message in $@. Example:

unlink trapped by operation mask at /opt/TKLCelap/bin/rob_cmds line 1, <STDIN> chunk 3.


Methods

new
Optional argument is the root namespace to use for the compartment (defaults to ``Safe::Root0'', where the number is incremented each time new is called).

permit(OP, ...)
Add operators to the set of permitted operators.

permit_only(OP, ...)
Replace set of permitted operators.

deny(OP, ...)
Remove operators from the set of permitted operators.

deny_only(OP, ...)
Replace set of permitted operators with the inverse of this list.

trap(OP, ...)
Same as deny.

untrap(OP, ...)
Same as permit.

share(NAME, ...)
Shares names from the current package with the compartment. (Think @EXPORT.) The leading identifier ($, @, %, *) is required for all but subroutines.

Filehandles must be shared in order to be accessable. They are shared using the typeglob (e.g. *STDOUT).

Local subroutines used by shared subroutines need not be shared. However, subroutines in other packages must be shared separately.

Note that the operator mask does not apply to shared subroutines because they are not compiled as part of the eval.

share_from(PACKAGE, ARRAYREF)
Same as share except that symbols from other packages can be shared and that the names are specified in an array passed by reference.

Example from documentation:

$safe->share_from('main', [ '$foo', '%bar', 'func' ]);

varglob(VARNAME)
Provides a way to set variables in the code to be evaluated by returning a glob reference of VARNAME in the compartment's package.

Example from documentation:

$cpt = new Safe 'Root';

$Root::foo = "Hello world";

# Equivalent version which doesn't need to know $cpt's package name:

${$cpt->varglob('foo')} = "Hello world";

reval(STRING)
Other than evaluating under the constraints of the compartment, just like eval.

rdo(FILENAME)
Other than doing the file under the constraints of the compartment, just like do.