NAME
Eval::Safe - Simplified safe evaluation of Perl code
SYNOPSIS
Eval::Safe is a Perl module to allow executing Perl code like with the eval function, but in isolation from the main program. This is similar to the Safe module, but faster, as we don't try to be safe.
my $eval = Eval::Safe->new();
$eval->eval($some_code);
$eval->share('$foo'); # 'our $foo' can now be used in code provided to eval.
DESCRIPTION
The standard Safe module does 4 things when running user-provided code: compiling and running the string as Perl code; running the code in a specific package so that variables in the calling code are not modified by mistake; hiding all the existing packages so that the executed code cannot modify them; and limiting the set of operations that can be executed by the code to further try to make it safe (prevents it from modifying the system, etc.).
By comparison, the Eval::Safe module here only does the first two of these things (compiling the code and changing the namespace in which it is executed) to make it conveniant to run user-provided code, as long as you can trust that code. The benefit is that this is around three times faster than using Safe (especially for small pieces of code).
CONSTRUCTOR/DESTRUCTOR
new(%options)
Creates a new Eval::Safe object. Some options may be passed to this call:
- safe => int
-
If passed on positive value, then the evaluation of the code will use the Safe module instead of the eval function. This is slower but means that the code won't be able to read or modify variables from your code unless explicitly shared.
- strict => options
-
If passed a
true
value then the code executed by the Eval::Safe object will be compiled underuse strict
. You can pass a reference to an array or hash to provide options that are passed to theuse strict
pragma. - warnings => options
-
If passed a
true
value then the code executed by the Eval::Safe object will be compiled underuse warnings
. You can pass a reference to an array or hash to provide options that are passed to theuse warnings
pragma. - debug => FILE
-
Sets debug mode. You should pass this option a file reference to which the debug output will be written. This is typically
*STDERR
. - package => string
-
Specify explicitly the package that will be used to compile the code passed to the Eval::Safe object. This must be a valid package name and the package itself must not yet exist.
Note that if you have explicit mention of this package in your code then the Perl compiler will auto-vivify the package and it will fail the "must not exist yet" test. You can work around this limitation either by wrapping such reference to the package in an
eval(str)
call, or by using the force_package option below. - force_package => boolean
-
Remove all check on the package name specified with package (both in term of validity and of existance).
Be careful that by default the package will be deleted when the Eval::Safe object is deleted. This means that existing variables that would refer to that package are no longer valid, even assigning to these variable will not re-create the package (unless the code setting the variable is compiled again through an
eval(str)
expression or you're using a string as a reference to the package or variable).
destructor
When the object goes out of scope, its main package and all its sub-packages are deleted automatically.
METHODS
eval($code)
Executes the given string as Perl code in the environment of the current object.
The current package seen by the code will be a package specific to the Safe::Eval object (that is initially empty). How that package is exposed depends on the value of the safe option passed to the constructor, if any. If the option was not passed (or was passed a false
value), then the code will have access to the content of all the existing packages and will see the real name of its package. If the safe option was passed a true
value, then the code will believe that it runs in the root package and it will not have access to the content of any other existing packages.
In all cases, if the code passed to eval
cannot be compiled or if it dies during its execution, then the call to eval
will return undef
and $@
will be set.
If the call returns a code reference or a data-structure that contains code references, these references are all modified so that when executed they will run as if through this eval
method. In particular, exceptions will be trapped and $@
will be set instead. This property is recursive to all the code-references possibly returned in turn by these functions.
wrap($code)
Returns a code-reference that, when executed, execute the content of the Perl code passed in the string in the context of the Eval::Safe object. This call is similar to $eval-
eval("sub { STR }")>.
share('$var', '@foo', ...)
Shares the listed variables from the current package with the Perl environment of the Eval::Safe object. The list must be a list of strings containing the names of the variables to share, including their leading sigils (one of $, @, %, &, or *). When sharing a glob (*foo
) then all the foo
variables are shared.
share_from('Package', '$var', ...)
Shares the listed variables from a specific package. The variables are shared into the main package of the Perl environment of the Eval::Safe object as when using the share
method.
package()
Returns the name of the package used by the Eval::Safe object. This is the package that was passed to the constructor if one was specified explicitly.
interpolate($str)
Interpolates the given string in the environment of the Eval::Safe object.
var_ref('$var_name')
Returns a reference to the variable whose name is given from the Eval::Safe object package. The variable name must have its leading sigil (one of $, @, %, &, or *).
do('file_name')
Loads the given file name into the environment of the Eval::Safe object. The file name may be relative or absolute but the @INC array is not used (as opposed to the standard do function).
If do can read the file but cannot compile it, it returns undef and sets an error message in $@. If do cannot read the file, it returns undef and sets $! to the error. Always check $@ first, as compilation could fail in a way that also sets $!. If the file is successfully compiled, do returns the value of the last expression evaluated.
CAVEATS
To bypass a bug with the Safe that hides all exceptions that could occur in code wrapped by it, this module is currently using a forked version of the standard Safe module. This may cause issues as that module relies on undocumented internals of Perl that are maybe subject to change.
AUTHOR
This program has been written by Mathias Kende.
LICENCE
Copyright 2019 Mathias Kende
This program is distributed under the MIT (X11) License: http://www.opensource.org/licenses/mit-license.php
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.