mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-17 22:39:03 +02:00
fix few Evaluators code
This commit is contained in:
@@ -16,6 +16,10 @@ class ClassConstFetchEvaluator extends AbstractExprEvaluator {
|
||||
$sClassName = $oExpr->class->name;
|
||||
$sProperty = $oExpr->name->name;
|
||||
|
||||
if ('class' === $sProperty){
|
||||
return $sClassName;
|
||||
}
|
||||
|
||||
if (class_exists($sClassName)){
|
||||
$class = new \ReflectionClass($sClassName);
|
||||
if (array_key_exists($sProperty, $class->getConstants())) {
|
||||
@@ -26,10 +30,6 @@ class ClassConstFetchEvaluator extends AbstractExprEvaluator {
|
||||
}
|
||||
}
|
||||
|
||||
if ('class' === $sProperty){
|
||||
return $sClassName;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,17 @@ namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
use ModuleFileReaderException;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use ReflectionFunction;
|
||||
|
||||
class FuncCallEvaluator extends AbstractExprEvaluator {
|
||||
public const WHITELIST=[
|
||||
"function_exists",
|
||||
"class_exists",
|
||||
"method_exists"
|
||||
];
|
||||
|
||||
public function GetHandledExpressionType(): ?string {
|
||||
return FuncCall::class;
|
||||
}
|
||||
@@ -15,9 +23,12 @@ class FuncCallEvaluator extends AbstractExprEvaluator {
|
||||
public function Evaluate(Expr $oExpr): mixed {
|
||||
/** @var FuncCall $oExpr */
|
||||
|
||||
$sFunction = $oExpr->name->name;
|
||||
$aWhiteList = ["function_exists", "class_exists", "method_exists"];
|
||||
if (! in_array($sFunction, $aWhiteList)){
|
||||
if ($oExpr->name instanceof Name){
|
||||
$sFunction = $oExpr->name->name;
|
||||
} else {
|
||||
$sFunction = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
}
|
||||
if (! in_array($sFunction, self::WHITELIST)){
|
||||
throw new ModuleFileReaderException("FuncCall $sFunction not supported");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,33 +4,45 @@ namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Identifier;
|
||||
use ReflectionClass;
|
||||
|
||||
class MethodCallEvaluator extends AbstractExprEvaluator {
|
||||
class MethodCallEvaluator extends AbstractExprEvaluator {
|
||||
public function GetHandledExpressionType(): ?string {
|
||||
return MethodCall::class;
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetHandledExpressionTypes(): ?array {
|
||||
return [MethodCall::class, Expr\NullsafeMethodCall::class];
|
||||
}
|
||||
|
||||
public function Evaluate(Expr $oExpr): mixed {
|
||||
/** @var MethodCall $oExpr */
|
||||
|
||||
$oVar = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->var);
|
||||
if (is_null($oVar)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$aArgs = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->args);
|
||||
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||
|
||||
$oMethods = $oReflectionClass->getMethods();
|
||||
if (array_key_exists($sName, $oMethods)){
|
||||
$oMethods = $oMethods[$sName];
|
||||
if ($oMethods->isPublic()){
|
||||
return $oMethods->invokeArgs($oVar, $aArgs);
|
||||
}
|
||||
$aArgs=[];
|
||||
foreach ($oExpr->args as $arg){
|
||||
/** @var \PhpParser\Node\Arg $arg */
|
||||
$aArgs[]=$arg->value->value;
|
||||
}
|
||||
|
||||
if ($oExpr->name instanceof Identifier){
|
||||
$sName = $oExpr->name->name;
|
||||
} else {
|
||||
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
}
|
||||
|
||||
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||
try{
|
||||
$oMethod = $oReflectionClass->getMethod($sName);
|
||||
if ($oMethod->isPublic()){
|
||||
return $oMethod->invokeArgs($oVar, $aArgs);
|
||||
}
|
||||
} catch (\ReflectionException $t) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\NullsafeMethodCall;
|
||||
use ReflectionClass;
|
||||
|
||||
class NullsafeMethodCallEvaluator extends AbstractExprEvaluator {
|
||||
public function GetHandledExpressionType(): ?string {
|
||||
return NullsafeMethodCall::class;
|
||||
}
|
||||
|
||||
public function Evaluate(Expr $oExpr): mixed {
|
||||
/** @var NullsafeMethodCall $oExpr */
|
||||
|
||||
$oVar = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->var);
|
||||
if (is_null($oVar)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$aArgs = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->args);
|
||||
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||
|
||||
$oMethods = $oReflectionClass->getMethods();
|
||||
if (array_key_exists($sName, $oMethods)){
|
||||
$oMethods = $oMethods[$sName];
|
||||
if ($oMethods->isPublic()){
|
||||
return $oMethods->invokeArgs($oVar, $aArgs);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\NullsafePropertyFetch;
|
||||
use ReflectionClass;
|
||||
|
||||
class NullsafePropertyFetchEvaluator extends AbstractExprEvaluator {
|
||||
public function GetHandledExpressionType(): ?string {
|
||||
return NullsafePropertyFetch::class;
|
||||
}
|
||||
|
||||
public function Evaluate(Expr $oExpr): mixed {
|
||||
/** @var NullsafePropertyFetch $oExpr */
|
||||
|
||||
$oVar = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->var);
|
||||
if (is_null($oVar)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||
|
||||
$oProperties = $oReflectionClass->getProperties();
|
||||
if (array_key_exists($sName, $oProperties)){
|
||||
$oProperty = $oProperties[$sName];
|
||||
if ($oProperty->isPublic()){
|
||||
return $oProperty->getValue($oVar);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
|
||||
use ModuleFileParser;
|
||||
use ModuleFileReaderException;
|
||||
use PhpParser\ConstExprEvaluator;
|
||||
use PhpParser\Node\Expr;
|
||||
|
||||
class PhpExpressionEvaluator {
|
||||
@@ -57,7 +58,24 @@ class PhpExpressionEvaluator {
|
||||
static::$oInstance = $oInstance;
|
||||
}
|
||||
|
||||
public function EvaluateExpression(Expr $oExpression) : mixed
|
||||
public function EvaluateExpression(Expr $oExpression, int $iMode=self::LIB_AND_FALLBACK) : mixed
|
||||
{
|
||||
if ($iMode==self::ITOP_ALGO){
|
||||
return $this->EvaluateExpressionLocally($oExpression);
|
||||
}
|
||||
|
||||
if ($iMode==self::LIB_ONLY){
|
||||
$oConstExprEvaluator = new ConstExprEvaluator();
|
||||
} else {
|
||||
$oConstExprEvaluator = new ConstExprEvaluator([$this, "EvaluateExpressionLocally"]);
|
||||
}
|
||||
|
||||
$oConstExprEvaluator->setFunctionsWhitelist(FuncCallEvaluator::WHITELIST);
|
||||
$oConstExprEvaluator->setStaticcallsWhitelist(StaticCallEvaluator::WHITELIST);
|
||||
return $oConstExprEvaluator->evaluateDirectly($oExpression);
|
||||
}
|
||||
|
||||
public function EvaluateExpressionLocally(Expr $oExpression) : mixed
|
||||
{
|
||||
$sClass = get_class($oExpression);
|
||||
$oPhpParserEvaluator = static::$aPhpParserEvaluators[$sClass] ?? null;
|
||||
@@ -79,7 +97,10 @@ class PhpExpressionEvaluator {
|
||||
return $this->ParseAndEvaluateExpression($sBooleanExpr);
|
||||
}
|
||||
|
||||
public function ParseAndEvaluateExpression(string $sExpr) : mixed
|
||||
const LIB_AND_FALLBACK=1;
|
||||
const LIB_ONLY=2;
|
||||
const ITOP_ALGO=3;
|
||||
public function ParseAndEvaluateExpression(string $sExpr, int $iMode=self::LIB_AND_FALLBACK) : mixed
|
||||
{
|
||||
$sPhpContent = <<<PHP
|
||||
<?php
|
||||
@@ -88,7 +109,7 @@ PHP;
|
||||
try{
|
||||
$aNodes = ModuleFileParser::GetInstance()->ParsePhpCode($sPhpContent);
|
||||
$oExpr = $aNodes[0];
|
||||
return $this->EvaluateExpression($oExpr->expr);
|
||||
return $this->EvaluateExpression($oExpr->expr, $iMode);
|
||||
} catch (\Throwable $t) {
|
||||
throw new ModuleFileReaderException("Eval of '$sExpr' caused an error:".$t->getMessage());
|
||||
}
|
||||
|
||||
@@ -4,44 +4,38 @@ namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Identifier;
|
||||
use ReflectionClass;
|
||||
|
||||
class PropertyFetchEvaluator extends AbstractExprEvaluator {
|
||||
public function GetHandledExpressionType(): ?string {
|
||||
return PropertyFetch::class;
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetHandledExpressionTypes(): ?array {
|
||||
return [PropertyFetch::class, Expr\NullsafePropertyFetch::class];
|
||||
}
|
||||
|
||||
public function Evaluate(Expr $oExpr): mixed {
|
||||
/** @var PropertyFetch $oExpr */
|
||||
|
||||
$oVar = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->var);
|
||||
if (is_null($oVar)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||
if ($oExpr->name instanceof Identifier){
|
||||
$sName = $oExpr->name->name;
|
||||
} else {
|
||||
$sName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
}
|
||||
|
||||
$oProperties = $oReflectionClass->getProperties();
|
||||
if (array_key_exists($sName, $oProperties)){
|
||||
$oProperty = $oProperties[$sName];
|
||||
$oReflectionClass = new ReflectionClass(get_class($oVar));
|
||||
try{
|
||||
$oProperty = $oReflectionClass->getProperty($sName);
|
||||
if ($oProperty->isPublic()){
|
||||
return $oProperty->getValue($oVar);
|
||||
}
|
||||
} catch (\ReflectionException $t) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$aArgs=[];
|
||||
|
||||
$oMethods = $oReflectionClass->getMethods();
|
||||
if (array_key_exists($sName, $oMethods)){
|
||||
$oMethod = $oMethods[$sName];
|
||||
if ($oMethod->isPublic()){
|
||||
return $oMethod->invokeArgs(null, $aArgs);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,14 @@ namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
use ModuleFileReaderException;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
|
||||
class StaticCallEvaluator extends AbstractExprEvaluator {
|
||||
public const WHITELIST=[
|
||||
"SetupInfo::ModuleIsSelected",
|
||||
"utils::GetItopVersionWikiSyntax"
|
||||
];
|
||||
|
||||
public function GetHandledExpressionType(): ?string {
|
||||
return StaticCall::class;
|
||||
}
|
||||
@@ -15,11 +21,14 @@ class StaticCallEvaluator extends AbstractExprEvaluator {
|
||||
/** @var StaticCall $oExpr */
|
||||
|
||||
$sClassName = $oExpr->class->name;
|
||||
$sMethodName = $oExpr->name->name;
|
||||
if ($oExpr->name instanceof Identifier){
|
||||
$sMethodName = $oExpr->name->name;
|
||||
} else {
|
||||
$sMethodName = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
}
|
||||
|
||||
$aWhiteList = ["SetupInfo::ModuleIsSelected", "utils::GetItopVersionWikiSyntax"];
|
||||
$sStaticCallDescription = "$sClassName::$sMethodName";
|
||||
if (! in_array($sStaticCallDescription, $aWhiteList)){
|
||||
if (! in_array($sStaticCallDescription, self::WHITELIST)){
|
||||
throw new ModuleFileReaderException("StaticCall $sStaticCallDescription not supported");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Combodo\iTop\PhpParser\Evaluation;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||
use PhpParser\Node\Identifier;
|
||||
|
||||
class StaticPropertyFetchEvaluator extends AbstractExprEvaluator {
|
||||
public function GetHandledExpressionType(): ?string {
|
||||
@@ -14,7 +15,11 @@ class StaticPropertyFetchEvaluator extends AbstractExprEvaluator {
|
||||
/** @var StaticPropertyFetch $oExpr */
|
||||
|
||||
$sClassName = $oExpr->class->name;
|
||||
$sProperty = $oExpr->name->name;
|
||||
if ($oExpr->name instanceof Identifier){
|
||||
$sProperty = $oExpr->name->name;
|
||||
} else {
|
||||
$sProperty = PhpExpressionEvaluator::GetInstance()->EvaluateExpression($oExpr->name);
|
||||
}
|
||||
|
||||
if (class_exists($sClassName)){
|
||||
$class = new \ReflectionClass($sClassName);
|
||||
|
||||
@@ -21,7 +21,6 @@ class VariableEvaluator extends AbstractExprEvaluator {
|
||||
}
|
||||
|
||||
$sVarname=$oExpr->name;
|
||||
|
||||
global $$sVarname;
|
||||
return $$sVarname;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user