We all know how dangerous eval() is in terms of security, but still it is the necessary evil sometimes.
I’ve been developing a script last week that required eval() execution. I did pretty granular input validation with regular expressions and known troubleish test cases. Still, some expressions passed to the eval() function were prone to parse errors.
Reading a bit I tried to use the exceptions handling mechanism in PHP 5 (try – catch blocks) to provide a solution, or using a error handler with the set_error_handler function. They work for exceptions and some basic errors, but most of the errors (including the parse erorr) pass.
I don’t mind the system being unable to call a valid function, but I want to protect the frontend. So the best call I found is using this trick.
Create a function with this content:
return @eval('return true;' . $code);
Where $code is the code you need to normally call in eval().
This statement returns true if your eval is valid – or false if it is going to break. Without breaking the frontend and the PHP execution.
So calling this before running your eval and testing for true will prevent the ugly errors on the page load.
Just one problem with this solution, When you try to validatecheck a code with a function declared in it you cant run the code again since you will get a “Fatal error: Cannot redeclare ….”
Yeah that’s a valid concern, thanks for explicitly mentioning this one 🙂
Thank you!
https://wordpress.org/plugins/options-inspector/changelog/
Good example. As a note you can wrap the syntax check code in a function which will thus nest any functions declared within the syntax check code — avoiding the ‘re-declare’ error:
return @eval(‘return true;function evalTest(){‘ . $code . ‘}’);
You can also do the following (tested using PHP 7.1):
function checkSyntax($code)
{
try
{ eval(‘return true;function testEval(){‘ . $code . ‘}’);
}
catch(ParseError $e)
{
return false;
}
return true;
}
YES JASON!
only thing that worked for me :
try {
eval(“return “.$string.”;”);
} catch (ParseError $e) {
$EVALerror=TRUE;
//echo ‘Caught exception: ‘.$e->getMessage().”n”;
}
if($EVALerror){
// you got PAIN
}