40
They talk a lot about eval
, but sometimes I wonder if he really is the problem or is the person sitting in front of the computer (the supposed programmer).
My whole life (in programming) I have heard criticism, jokes, jokes about this function eval
, but the curious thing is that, even those who mock, end up using libraries that use it internally, without knowing.
An example of this is Laravel 3
, that in the system of views, uses eval
.
Example (I removed the comments from the original code):
public function get()
{
$__data = $this->data();
$__contents = $this->load();
ob_start() and extract($__data, EXTR_SKIP);
try
{
eval('?>'.$__contents);
}
catch (\Exception $e)
{
ob_get_clean(); throw $e;
}
$content = ob_get_clean();
if (Event::listeners('view.filter'))
{
return Event::first('view.filter', array($content, $this->path));
}
return $content;
}
True, it is already discontinued, but it is not in a distant era (its version is for PHP 5.3). But it would come as no surprise if one of the critics of eval
had using that framework unaware of this information.
And yet I give another example, that many programmers also use, but without knowing it. The Superclosure that is used in Laravel 4 and Laravel 5. This library aims to provide a possibility to serialize closures in PHP, since natively closures PHP does not support serialization. This library becomes useful for those who need to use queue systems, such as Beanstalkd, where the information passed is usually a string, and therefore PHP data needs to be serialized.
Example:
/**
* Reconstruct a closure.
*
* HERE BE DRAGONS!
*
* The infamous `eval()` is used in this method, along with the error
* suppression operator, and variable variables (i.e., double dollar signs) to
* perform the unserialization logic. I'm sorry, world!
*
* This is also done inside a plain function instead of a method so that the
* binding and scope of the closure are null.
*
* @param array $__data Unserialized closure data.
*
* @return Closure|null
* @internal
*/
function __reconstruct_closure(array $__data)
{
// Simulate the original context the closure was created in.
foreach ($__data['context'] as $__var_name => &$__value) {
if ($__value instanceof SerializableClosure) {
// Unbox any SerializableClosures in the context.
$__value = $__value->getClosure();
} elseif ($__value === Serializer::RECURSION) {
// Track recursive references (there should only be one).
$__recursive_reference = $__var_name;
}
// Import the variable into this scope.
${$__var_name} = $__value;
}
// Evaluate the code to recreate the closure.
try {
if (isset($__recursive_reference)) {
// Special handling for recursive closures.
@eval("\${$__recursive_reference} = {$__data['code']};");
$__closure = ${$__recursive_reference};
} else {
@eval("\$__closure = {$__data['code']};");
}
} catch (\ParseError $e) {
// Discard the parse error.
}
return isset($__closure) ? $__closure : null;
}
Github - Serializableclosure.php - line 187.
Thinking about the usefulness of the classes of the libraries presented above, remembering that they are only two examples, but there must be other cases, I wondered if I should still speak bad of eval
or simply make an analysis and evaluate when it is good or bad to use it.
On the other hand, if I think that "all of it, regardless of how it is implemented, is a risk", I will probably have to stop using the libraries I mentioned above, and do a whole manual job...
What are the risks of using
eval
in a project?I must always avoid it?
If the answer is yes to "should I avoid it," then should I also stop using libraries that implement it? After all, that can’t put my code at risk?
The
eval
should be used in some very specific cases (such as code generation only) or I can use it freely, as long as I am aware of what I am doing?
Note: Please do not edit and put tags as php or Larable, for the examples were only to show cases where eval
was "well received". If there are examples of other languages that use it, you are welcome.
A "little eval" from time to time while does not hurt anyone, hehehe
– Wallace Maxters
I could give this answer here, although it is about Javascript. But I’m not sure what kind of answer you’re looking for. The
eval
exists, and there is no verdict uses/does not use, a Cad does as you want.– Sergio
@Sergio want to leave this question here more to break down the prejudice (mainly mine, which I learned mechanically). But seeing these Ibraries, it really bothered me to remember these criticisms
– Wallace Maxters
@Guilhermenascimento to emphasize: "The misuse Eval can lead to code injection attacks"
– Wallace Maxters