Closed1
安全な?eval電卓
にインスパイアされたPHP-Parserを用いたPoC。
<?php
require dirname(__FILE__) . '/vendor/autoload.php';
use PhpParser\Error;
use PhpParser\ParserFactory;
use PhpParser\{Node, NodeTraverser, NodeVisitorAbstract};
$formula = "3 + 4 * 4 / 2 - 1";
$parser = (new ParserFactory())->createForNewestSupportedVersion();
try {
$ast = $parser->parse('<?php ' . $formula . ';');
} catch (Error $error) {
echo "Parse error: {$error->getMessage()}\n";
return;
}
$traverser = new NodeTraverser;
$traverser->addVisitor(new class extends NodeVisitorAbstract {
public function enterNode(Node $node) {
if ($node instanceof Node\Stmt\Expression && $node->expr instanceof Node\Expr\BinaryOp
|| $node instanceof Node\Expr\BinaryOp
|| $node instanceof Node\Scalar\Int_
|| $node instanceof Node\Scalar\Float_
) {
return $node;
}
throw new \RuntimeException('invalid expression.');
}
});
try {
$traverser->traverse($ast);
} catch (Error $error) {
echo "Validation error: {$error->getMessage()}\n";
return;
}
echo eval(sprintf('return %s;', $formula));
このスクラップは3ヶ月前にクローズされました