- Added comprehensive AI Assistant system (aiassist/ directory): * Vector search and embedding capabilities * Typebot proxy integration * Elastic search functionality * Message classification and chat history * MCP proxy for external integrations - Implemented Court Status API (GetCourtStatus.php): * Real-time court document status checking * Integration with external court systems * Comprehensive error handling and logging - Enhanced S3 integration: * Improved file backup system with metadata * Batch processing capabilities * Enhanced error logging and recovery * Copy operations with URL fixing - Added Telegram contact creation API - Improved error logging across all modules - Enhanced callback system for AI responses - Extensive backup file storage with timestamps - Updated documentation and README files - File storage improvements: * Thousands of backup files with proper metadata * Fix operations for broken file references * Project-specific backup and recovery systems * Comprehensive file integrity checking Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
1576 lines
52 KiB
PHP
1576 lines
52 KiB
PHP
<?php
|
|
/**
|
|
This File was developed by Stefan Warnat <vtiger@stefanwarnat.de>
|
|
|
|
It belongs to the Workflow Designer and must not be distributed without complete extension
|
|
|
|
@version 1.23
|
|
@lastupdate 2017-08-01
|
|
|
|
* # 1.23
|
|
* Fixed a bug with missing Quotes
|
|
* # 1.22
|
|
* Timeout Bug resolved
|
|
* # 1.21
|
|
* Profiler based Performance Improvements
|
|
* # 1.2
|
|
Logical Operators && and ||
|
|
* Performance Improvements
|
|
* # 1.14
|
|
- fix one variable as array bug
|
|
* # 1.131
|
|
- introduce !==
|
|
# 1.13
|
|
- introduce ===
|
|
- introduce !
|
|
# 1.11
|
|
* - [FIX] Array [] Operator
|
|
* # 1.1
|
|
* - Introduce Arrays, foreach
|
|
* # 1.03
|
|
* - fix a problem in "if" condition
|
|
* # 1.02
|
|
* - add Number handling
|
|
* # 1.01
|
|
* - fix bug with If construct
|
|
**/
|
|
namespace Workflow;
|
|
|
|
class ExpressionParser {
|
|
private $_expression = false;
|
|
/**
|
|
* @var \Workflow\VTEntity $_context
|
|
*/
|
|
private $_context = false;
|
|
private $_tokens = false;
|
|
private $_tokenCount = 0;
|
|
|
|
private $_currentPos =0;
|
|
private $_intend = 0;
|
|
|
|
private $_return = null;
|
|
|
|
private $_variables = array();
|
|
private $_stop = false;
|
|
|
|
private $_debug = false;
|
|
|
|
private $_maxTime = 0;
|
|
private $_timeout = 30;
|
|
|
|
private $_disableFunctionlist = false;
|
|
private $_loopLimit = 150;
|
|
|
|
private $_NegotiateCompare = false;
|
|
|
|
private static $EvalAllowed = -1;
|
|
|
|
public static $INSTANCE = false;
|
|
|
|
public static $WhitelistPHPfunctions = array(
|
|
'json_encode',
|
|
'nl2br',
|
|
'date_default_timezone_get',
|
|
'date_default_timezone_set',
|
|
"round",
|
|
"md5",
|
|
"rand",
|
|
"count",
|
|
"implode",
|
|
"substr",
|
|
"floor",
|
|
"ceil",
|
|
"explode",
|
|
"microtime",
|
|
"date",
|
|
"trim",
|
|
"time",
|
|
"sha1",
|
|
"hash",
|
|
"intval",
|
|
"floatval",
|
|
"ucfirst",
|
|
"number_format",
|
|
'is_numeric',
|
|
'sqrt',
|
|
'pow',
|
|
'mt_rand',
|
|
'json_encode',
|
|
'json_decode',
|
|
'urlencode',
|
|
'urldecode',
|
|
//'substr_count'
|
|
);
|
|
|
|
protected $_nextByReference = false;
|
|
|
|
private $StaticReference = array();
|
|
|
|
private $_startTime = 0;
|
|
/**
|
|
* @param $expression
|
|
* @param $context
|
|
* @param bool $debug If set, complex debug output will be shown
|
|
*/
|
|
public function __construct($expression, &$context, $debug = false, $checkSyntax = true) {
|
|
$expression = str_replace(''', "'", $expression);
|
|
$this->_expression = str_replace(array("<p>", "</p>", "<div>", "</div>"), "", ($expression));
|
|
$this->_context = $context;
|
|
$this->_debug = $debug;
|
|
|
|
$this->_variables["env"] = $context->getEnvironment();
|
|
|
|
self::$INSTANCE = $this;
|
|
|
|
if($checkSyntax == true) {
|
|
$SyntaxCheck = $this->checkSyntax();
|
|
|
|
if($SyntaxCheck !== false) {
|
|
throw new \Exception($expression." - Expression Syntax Error Line ".$SyntaxCheck[1].".\n ".$SyntaxCheck[0], E_NONBREAK_ERROR);
|
|
$this->_expression = "return '';";
|
|
}
|
|
}
|
|
}
|
|
|
|
public function setTimeout($timeout = 30) {
|
|
$this->_timeout = floatval($timeout);
|
|
}
|
|
|
|
public function getContext() {
|
|
return $this->_context;
|
|
}
|
|
|
|
protected function isEvalAllowed() {
|
|
if(self::$EvalAllowed !== -1) {
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
if(!function_exists("ini_get")) {
|
|
self::$EvalAllowed = false;
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
if(ini_get("suhosin.executor.disable_eval") == "1") {
|
|
self::$EvalAllowed = false;
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
$check = ini_get("disable_functions")." ".ini_get("suhosin.executor.func.blacklist");
|
|
|
|
if(strpos($check, "eval") !== false) {
|
|
self::$EvalAllowed = false;
|
|
return self::$EvalAllowed;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
/**
|
|
* @param $code
|
|
* @return array|bool
|
|
* @author nicolas dot grekas+php at gmail dot com ¶
|
|
*/
|
|
public function checkSyntax() {
|
|
$code = trim($this->_expression);
|
|
$code = html_entity_decode($code, ENT_NOQUOTES, "UTF-8");
|
|
$checkCode = $code;
|
|
$braces = 0;
|
|
$inString = 0;
|
|
|
|
//\Workflow2::$enableError = false;
|
|
// First of all, we need to know if braces are correctly balanced.
|
|
// This is not trivial due to variable interpolation which
|
|
// occurs in heredoc, backticked and double quoted strings
|
|
foreach (token_get_all('<?php ' . $code) as $token)
|
|
{
|
|
if (is_array($token))
|
|
{
|
|
switch ($token[0])
|
|
{
|
|
case T_CURLY_OPEN:
|
|
case T_DOLLAR_OPEN_CURLY_BRACES:
|
|
case T_START_HEREDOC: ++$inString; break;
|
|
case T_END_HEREDOC: --$inString; break;
|
|
}
|
|
}
|
|
else if ($inString & 1)
|
|
{
|
|
switch ($token)
|
|
{
|
|
case '`':
|
|
case '"': --$inString; break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ($token)
|
|
{
|
|
case '`':
|
|
case '"': ++$inString; break;
|
|
|
|
case '{': ++$braces; break;
|
|
case '(': ++$braces; break;
|
|
case '}':
|
|
case ')':
|
|
if ($inString) --$inString;
|
|
else
|
|
{
|
|
--$braces;
|
|
if ($braces < 0) break 2;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Display parse error messages and use output buffering to catch them
|
|
$inString = @ini_set('log_errors', false);
|
|
$token = @ini_set('display_errors', true);
|
|
ob_start();
|
|
|
|
if($braces != 0) return array('Check Braces!!! ', 0);
|
|
// If $braces is not zero, then we are sure that $code is broken.
|
|
// We run it anyway in order to catch the error message and line number.
|
|
|
|
// Else, if $braces are correctly balanced, then we can safely put
|
|
// $code in a dead code sandbox to prevent its execution.
|
|
// Note that without this sandbox, a function or class declaration inside
|
|
// $code could throw a "Cannot redeclare" fatal error.
|
|
|
|
// $code = html_entity_decode(htmlspecialchars_decode($code, ENT_NOQUOTES), ENT_NOQUOTES, "UTF-8");
|
|
|
|
$code = "if(0){{$code};\n}";
|
|
|
|
// If eval not allowed, don't execute this
|
|
if(!$this->isEvalAllowed()) {
|
|
if($braces) {
|
|
return array('syntax error: unexpected $end', 0);
|
|
}
|
|
}
|
|
|
|
|
|
if(class_exists('\\Error')) {
|
|
try {
|
|
eval($code);
|
|
} catch (\Error $e) {
|
|
return array(
|
|
$e->getMessage(),
|
|
$e->getLine()
|
|
);
|
|
}
|
|
ob_end_clean();
|
|
$code = false;
|
|
} else {
|
|
|
|
if (false === eval($code)) {
|
|
if ($braces) $braces = PHP_INT_MAX;
|
|
else {
|
|
// Get the maximum number of lines in $code to fix a border case
|
|
false !== strpos($code, "\r") && $code = strtr(str_replace("\r\n", "\n", $code), "\r", "\n");
|
|
$braces = substr_count($code, "\n");
|
|
}
|
|
|
|
$code = ob_get_clean();
|
|
$code = strip_tags($code);
|
|
|
|
// Get the error message and line number
|
|
if (preg_match("'syntax error, (.+) in .+ on line (\d+)'s", $code, $code)) {
|
|
$code[2] = (int)$code[2];
|
|
$code = $code[2] <= $braces
|
|
? array($code[1], $code[2])
|
|
: array('unexpected $end' . substr($code[1], 14), $braces);
|
|
} else $code = array('syntax error', 0);
|
|
|
|
$oldHandler = set_error_handler('var_dump', 0);
|
|
@$undef_var;
|
|
if (!empty($oldHandler)) {
|
|
set_error_handler($oldHandler);
|
|
}
|
|
|
|
} else {
|
|
ob_end_clean();
|
|
$code = false;
|
|
}
|
|
}
|
|
|
|
/*if($code === false) {
|
|
if(strpos($checkCode, 'return') === false) {
|
|
$code = array('No return statement', 0);
|
|
}
|
|
}*/
|
|
|
|
@ini_set('display_errors', $token);
|
|
@ini_set('log_errors', $inString);
|
|
|
|
//\Workflow2::$enableError = true;
|
|
|
|
return $code;
|
|
|
|
}
|
|
public function setEnvironment($env) {
|
|
$this->_variables["env"] = $env;
|
|
}
|
|
public function run() {
|
|
$this->_startTime = time();
|
|
|
|
$this->_tokens = $this->_getTokens();
|
|
$this->_tokenCount = count($this->_tokens);
|
|
|
|
$this->_maxTime = time() + $this->_timeout;
|
|
|
|
// Solange abarbeiten, bis Return erreicht oder Ende der Ausgabe
|
|
do {
|
|
$this->_nextCommand();
|
|
} while($this->_currentPos < $this->_tokenCount && $this->_stop == false);
|
|
|
|
if(!empty($this->_variables["env"])) {
|
|
$this->_context->loadEnvironment($this->_variables["env"]);
|
|
}
|
|
}
|
|
|
|
public static function getDefinedCustomFunctions() {
|
|
$files = glob(dirname(__FILE__) . DS . '..' . DS . '..'. DS . 'extends' . DS . 'functions' . DS . '*.inc.php');
|
|
$functions = array();
|
|
foreach($files as $file) {
|
|
$functions = array_merge($functions, self::_get_defined_custom_functions_file($file));
|
|
}
|
|
return $functions;
|
|
}
|
|
private static function _get_defined_custom_functions_file($file) {
|
|
$source = file_get_contents($file);
|
|
$tokens = token_get_all($source);
|
|
|
|
$functions = array();
|
|
$nextStringIsFunc = false;
|
|
$inClass = false;
|
|
$bracesCount = 0;
|
|
|
|
foreach($tokens as $token) {
|
|
switch($token[0]) {
|
|
case T_CLASS:
|
|
$inClass = true;
|
|
break;
|
|
case T_FUNCTION:
|
|
if(!$inClass) $nextStringIsFunc = true;
|
|
break;
|
|
|
|
case T_STRING:
|
|
if($nextStringIsFunc) {
|
|
$nextStringIsFunc = false;
|
|
$functions[] = $token[1];
|
|
}
|
|
break;
|
|
|
|
// Anonymous functions
|
|
case '(':
|
|
case ';':
|
|
$nextStringIsFunc = false;
|
|
break;
|
|
|
|
// Exclude Classes
|
|
case '{':
|
|
if($inClass) $bracesCount++;
|
|
break;
|
|
|
|
case '}':
|
|
if($inClass) {
|
|
$bracesCount--;
|
|
if($bracesCount === 0) $inClass = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $functions;
|
|
}
|
|
private function checkRuntime() {
|
|
if(time() > $this->_maxTime) {
|
|
throw new ExpressionException('Runtime too high. Please check Exception!');
|
|
}
|
|
}
|
|
|
|
/* Internal functions */
|
|
private function _debug($text) {
|
|
if($this->_debug == true) {
|
|
echo "<pre>";
|
|
echo(str_pad($this->_currentPos, 3, ' ', STR_PAD_LEFT).' '.str_repeat("<span style='color:#eee'>|</span> ", $this->_intend). $text)."\n";
|
|
echo "</pre>";
|
|
}
|
|
}
|
|
private function _getTokens() {
|
|
$functions = token_get_all("<?php ".$this->_expression);
|
|
|
|
$count = count($functions);
|
|
$tokens = array();
|
|
|
|
for($a = 0; $a < $count; $a++) {
|
|
|
|
// remove Whitespaces
|
|
if($functions[$a][0] == T_WHITESPACE ||$functions[$a][0] == T_OPEN_TAG) continue;
|
|
$tokens[] = $functions[$a];
|
|
}
|
|
|
|
return $tokens;
|
|
}
|
|
|
|
public function getReturn() {
|
|
if($this->_return === null) {
|
|
return "";
|
|
# removed the error, because there are too much problems
|
|
}
|
|
|
|
return $this->_return;
|
|
}
|
|
public function _setReturn($return) {
|
|
$this->_return = $return;
|
|
$this->_stop = true;
|
|
}
|
|
public static function IsAllowedFunction($functionName) {
|
|
return in_array($functionName, self::$WhitelistPHPfunctions) || substr($functionName, 0, 3) == "str" || substr($functionName, 0, 5) == "date_" || substr($functionName, 0, 3) == "wf_";
|
|
}
|
|
private function _next($increase = true) {
|
|
if($increase == true && !is_string($this->_tokens[$this->_currentPos])) {
|
|
//$this->_debug("[ ] _next(".($increase?"true":"false").") [".$this->_currentPos."]");
|
|
$this->_intend++;
|
|
|
|
//$this->_debug("[".($this->_currentPos)."] ".token_name($this->_tokens[$this->_currentPos][0]));
|
|
|
|
$this->_intend--;
|
|
}
|
|
|
|
if($this->_tokenCount <= $this->_currentPos) {
|
|
return -1;
|
|
}
|
|
|
|
#//$this->_debug("[-] _next");
|
|
if($increase == true) {
|
|
return $this->_tokens[$this->_currentPos++];
|
|
} else {
|
|
return $this->_tokens[$this->_currentPos];
|
|
}
|
|
}
|
|
|
|
private function _nextCommand() {
|
|
$return = "";
|
|
//$this->_debug("[+] _nextCommand");
|
|
$this->_intend++;
|
|
$nextToken = $this->_next();
|
|
/*
|
|
if(is_string($nextToken)) {
|
|
//$this->_debug("[+] _runString \" ".$nextToken." \"");
|
|
} else {
|
|
//$this->_debug("[+] _runCommand (".token_name($nextToken[0]).") [".htmlentities($nextToken[1])."]");
|
|
}
|
|
*/
|
|
$this->_intend++;
|
|
|
|
$this->checkRuntime();
|
|
|
|
switch($nextToken[0]) {
|
|
case ";":
|
|
return $return;
|
|
break;
|
|
case T_IF:
|
|
$return = $this->_run_if();
|
|
break;
|
|
case T_FOR:
|
|
$this->_run_for();
|
|
break;
|
|
case T_FOREACH:
|
|
$this->_run_foreach();
|
|
break;
|
|
case T_ARRAY:
|
|
$return = $this->_getArrayValues();
|
|
break;
|
|
case T_VARIABLE:
|
|
if($this->_nextByReference == true) {
|
|
$byRef = true;
|
|
$this->_nextByReference = false;
|
|
} else {
|
|
$byRef = false;
|
|
}
|
|
$varName = substr($nextToken[1], 1);
|
|
$tmpToken = $this->_next(false);
|
|
|
|
$pointerSet = false;
|
|
$varPointer = false;
|
|
$addItem = false;
|
|
|
|
if($tmpToken == "[") {
|
|
$keys = array();
|
|
//$this->_debug('Array found');
|
|
|
|
while($this->_next(false) == "[") {
|
|
$this->_currentPos++;
|
|
if($this->_next(false) == "]") {
|
|
$this->_currentPos++;
|
|
$addItem = true;
|
|
break;
|
|
}
|
|
$keys[] = $this->_getArrayKey();
|
|
}
|
|
|
|
$pointerSet = true;
|
|
|
|
unset($varPointer);
|
|
|
|
if(is_array($this->_variables[$varName])) {
|
|
$varPointer = &$this->_variables[$varName];
|
|
} else {
|
|
$varPointer = $this->_variables[$varName];
|
|
}
|
|
|
|
# Array Struktur herabgehen
|
|
foreach($keys as $key) {
|
|
if(!is_array($varPointer) && !is_string($varPointer)) {
|
|
$varPointer = array();
|
|
}
|
|
$pointerSet = true;
|
|
|
|
if(!is_string($varPointer)) {
|
|
$varPointer = &$varPointer[$key];
|
|
} else {
|
|
if(is_numeric($key)) {
|
|
$varPointer = $varPointer[$key];
|
|
} else {
|
|
unset($varPointer);
|
|
$varPointer = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle [] suffix on array
|
|
if($addItem == true) {
|
|
$TMPpointer = &$varPointer;
|
|
if(!is_array($TMPpointer)) {
|
|
$varPointer = array();
|
|
}
|
|
array_push($TMPpointer, null);
|
|
$pointerSet = true;
|
|
$varPointer = &$TMPpointer[count($varPointer) - 1];
|
|
}
|
|
}
|
|
|
|
$tmpToken = $this->_next(false);
|
|
|
|
if(
|
|
(
|
|
!is_array($tmpToken) && $tmpToken == "="
|
|
) ||
|
|
(
|
|
is_array($tmpToken) && in_array($tmpToken[0], array(T_PLUS_EQUAL, T_MINUS_EQUAL, T_INC, T_DEC, T_CONCAT_EQUAL, T_MUL_EQUAL))
|
|
)
|
|
) {
|
|
// Wird eine Zuweisung
|
|
|
|
//$this->_debug(" # prepare Assignment [".$varName."]");
|
|
|
|
$this->_currentPos++;
|
|
|
|
if(
|
|
!is_array($tmpToken) ||
|
|
!in_array($tmpToken[0], array(T_PLUS_EQUAL, T_MINUS_EQUAL, T_MUL_EQUAL))
|
|
) {
|
|
$valueOfVariable = $this->_nextCommand();
|
|
}
|
|
|
|
if(is_array($tmpToken) && in_array($tmpToken[0], array(T_PLUS_EQUAL, T_MINUS_EQUAL, T_MUL_EQUAL, T_INC, T_DEC, T_CONCAT_EQUAL))) {
|
|
|
|
if(!$pointerSet) {
|
|
if(isset($this->_variables[$varName])) {
|
|
$startvalue = $this->_variables[$varName];
|
|
//$this->_debug(" # _getVariable [".$varName."] = ".$startvalue);
|
|
}
|
|
} else {
|
|
$startvalue = $varPointer;
|
|
//$this->_debug(" # _getArrayVariable [".$varName."][".implode("][", $keys)."] = ".$startvalue);
|
|
}
|
|
|
|
} else {
|
|
$startvalue = 0;
|
|
}
|
|
|
|
if(is_array($tmpToken) === true) {
|
|
switch($tmpToken[0]) {
|
|
case T_MINUS_EQUAL:
|
|
$valueOfVariable = $startvalue - $this->_nextCommand();
|
|
break;
|
|
case T_PLUS_EQUAL:
|
|
$valueOfVariable = $startvalue + $this->_nextCommand();
|
|
break;
|
|
case T_MUL_EQUAL:
|
|
$valueOfVariable = $startvalue * $this->_nextCommand();
|
|
break;
|
|
case T_INC:
|
|
$valueOfVariable = $startvalue + 1;
|
|
break;
|
|
case T_DEC:
|
|
$valueOfVariable = $startvalue - 1;
|
|
break;
|
|
case T_CONCAT_EQUAL:
|
|
$valueOfVariable = $startvalue . $valueOfVariable;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if($varName == "disableFunctionlist" && $valueOfVariable == "1") {
|
|
$this->_disableFunctionlist = true;
|
|
}
|
|
if($varName == "loopLimit") {
|
|
$this->_loopLimit = intval($valueOfVariable);
|
|
}
|
|
|
|
if($pointerSet == false) {
|
|
//$this->_debug(" # _setVariable [".$varName."] = ".serialize($valueOfVariable));
|
|
$this->_variables[$varName] = $valueOfVariable;
|
|
} else {
|
|
//$this->_debug(" # _setArrayVariable [".$varName."][".implode("][", $keys)."] = ".serialize($valueOfVariable));
|
|
$varPointer = $valueOfVariable;
|
|
}
|
|
|
|
} elseif(isset($this->_variables[$varName]) || $pointerSet == true) {
|
|
if($pointerSet == false) {
|
|
|
|
if($byRef == true) {
|
|
$value = &$this->_variables[$varName];
|
|
} else {
|
|
$value = $this->_variables[$varName];
|
|
}
|
|
|
|
//$this->_debug(" # _getVariable ".($byRef == true?"&":"")."[".$varName."] = ".json_encode($value));
|
|
} else {
|
|
if($byRef == true) {
|
|
$value = &$varPointer;
|
|
} else {
|
|
$value = $varPointer;
|
|
}
|
|
//$this->_debug(" # _getArrayVariable ".($byRef == true?"&":"")."[".$varName."][".implode("][", $keys)."] = ".$value);
|
|
}
|
|
|
|
$return = $value;
|
|
} elseif(is_array($tmpToken) && $tmpToken[0] == T_OBJECT_OPERATOR) {
|
|
//$this->_debug(" # _getValue from reference");
|
|
|
|
$this->_currentPos++;
|
|
$moduleToken = $this->_next(false);
|
|
|
|
if($varName != "current_user") {
|
|
/**
|
|
* @var $reference VTEntity
|
|
*/
|
|
$reference = $this->_context->getReference($moduleToken[1], $varName);
|
|
} else {
|
|
global $current_user;
|
|
/**
|
|
* @var $reference VTEntity
|
|
*/
|
|
$reference = VTEntity::getForId($current_user->id, $moduleToken[1]);
|
|
}
|
|
|
|
$this->_currentPos++;
|
|
$tmpToken = $this->_next(false);
|
|
if(is_array($tmpToken) && $tmpToken[0] == T_OBJECT_OPERATOR) {
|
|
$this->_currentPos++;
|
|
$tmpToken = $this->_next(false);
|
|
|
|
$this->_currentPos++;
|
|
if($reference instanceof VTEntity) {
|
|
$return = $reference->get($tmpToken[1]);
|
|
} else {
|
|
#error_log("No Reference defined for $".$varName."->".$moduleToken[1]);
|
|
throw new ExpressionException("No Reference defined for $".$varName."->".$moduleToken[1]);
|
|
}
|
|
} else {
|
|
throw new ExpressionException("Error in ExpressionParser near $".$varName."->".$moduleToken[1]);
|
|
}
|
|
|
|
} else {
|
|
$return = $this->_context->get($varName);
|
|
//$this->_debug(" # _getValue $varName = ('".$return."')");
|
|
}
|
|
|
|
$tmpToken = $this->_next(false);
|
|
|
|
if(
|
|
(
|
|
is_array($tmpToken) && in_array($tmpToken[0], array(T_IS_SMALLER_OR_EQUAL, T_IS_EQUAL, T_IS_IDENTICAL, T_IS_NOT_IDENTICAL, T_IS_NOT_EQUAL, T_IS_GREATER_OR_EQUAL))
|
|
) ||
|
|
$tmpToken == '<' ||
|
|
$tmpToken == '>'
|
|
) {
|
|
$startvalue = $return;
|
|
|
|
$next = $this->_next();
|
|
|
|
$value = $this->_nextCommand();
|
|
|
|
$return = $this->_compareOperator($startvalue, $value, $tmpToken);
|
|
|
|
//$this->_debug(" # _ShortCompare ".$startvalue . " -- " . $value . ' '.serialize($return));
|
|
|
|
if($this->_NegotiateCompare == true) { $return = !$return; $this->_NegotiateCompare = false; }
|
|
|
|
}
|
|
break;
|
|
case T_DNUMBER:
|
|
$return = $nextToken[1];
|
|
break;
|
|
case T_STRING:
|
|
if(defined($nextToken[1])) {
|
|
//$this->_debug(" # Constant Found");
|
|
$return = constant($nextToken[1]);
|
|
} elseif(function_exists("VT_".$nextToken[1])) {
|
|
//$this->_debug(" # Custom function");
|
|
// Methodennamen werden umgeschrieben um nur bestimmte Funktionen zuzulassen
|
|
$methodName = "VT_".$nextToken[1];
|
|
|
|
$parameter = $this->_getFunctionParameters();
|
|
$return = call_user_func_array($methodName, $parameter);
|
|
} elseif(
|
|
$this->_disableFunctionlist === true ||
|
|
self::IsAllowedFunction($nextToken[1]) ||
|
|
substr($nextToken[1], 0, 5) == "array"
|
|
) {
|
|
//$this->_debug(" # Whitelisted PHP Function");
|
|
$parameter = $this->_getFunctionParameters();
|
|
|
|
$return = call_user_func_array($nextToken[1], $parameter);
|
|
}
|
|
|
|
//$this->_debug(" return Value '".substr(serialize($return), 0, 250)."'");
|
|
break;
|
|
case "-":
|
|
#$this->_currentPos++;
|
|
$nextValue = $this->_next();
|
|
$return = -1 * $nextValue[1];
|
|
break;
|
|
case "&":
|
|
$this->_nextByReference = true;
|
|
break;
|
|
case "(":
|
|
$return = $this->_nextCommand();
|
|
$this->_currentPos++;
|
|
break;
|
|
case ")":
|
|
//$this->_debug(" RETURN Brackets ['".$return."']");
|
|
$this->_intend--;
|
|
$this->_intend--;
|
|
return $return;
|
|
break;
|
|
case T_LNUMBER:
|
|
$return = floatval($nextToken[1]);
|
|
break;
|
|
case T_CONSTANT_ENCAPSED_STRING:
|
|
|
|
if((substr($nextToken[1], 0, 1) == "'" || substr($nextToken[1], 0, 1) == '"') && substr($nextToken[1], -1, 1) == substr($nextToken[1], 0, 1)) {
|
|
$nextToken[1] = trim($nextToken[1], substr($nextToken[1], 0, 1));
|
|
}
|
|
$return = $nextToken[1];
|
|
break;
|
|
case T_EMPTY:
|
|
$parameter = $this->_getFunctionParameters();
|
|
|
|
if(empty($parameter[0])) return true;
|
|
|
|
break;
|
|
case T_RETURN:
|
|
$return = $this->_nextCommand();
|
|
$this->_setReturn($return);
|
|
break;
|
|
case T_COMMENT;
|
|
$return = $this->_nextCommand();
|
|
break;
|
|
case T_IS_NOT_IDENTICAL:
|
|
case T_IS_EQUAL:
|
|
case T_IS_GREATER_OR_EQUAL:
|
|
case T_IS_IDENTICAL:
|
|
case T_IS_NOT_EQUAL:
|
|
case T_IS_SMALLER_OR_EQUAL:
|
|
$this->_currentPos--;
|
|
$return = false;
|
|
break;
|
|
default;
|
|
break;
|
|
}
|
|
|
|
//$this->_debug("potential next: ".json_encode($this->_next(false)));
|
|
|
|
if($this->_next(false) == ".") {
|
|
$this->_currentPos++;
|
|
//$this->_debug("[ ] _foundCombination");
|
|
$return .= $this->_nextCommand();
|
|
}
|
|
|
|
$tmpToken = $this->_next(false);
|
|
|
|
if(in_array($tmpToken, array("+", "-", "*", "/", "^"))) {
|
|
//$this->_debug(" found Operation");
|
|
|
|
$this->_currentPos++;
|
|
$valueOfVariable = $this->_nextCommand();
|
|
if(empty($return)) {
|
|
$return = 0;
|
|
}
|
|
if(empty($valueOfVariable)) {
|
|
$valueOfVariable = 0;
|
|
}
|
|
//$this->_debug(" run Operation ('return ".$return." ".$tmpToken." ".$valueOfVariable.";')");
|
|
|
|
$return = eval('return '.$return.' '.$tmpToken.' '.$valueOfVariable.';');
|
|
}
|
|
|
|
if((is_array($tmpToken) && in_array($tmpToken[0], array(T_IS_SMALLER_OR_EQUAL, T_IS_EQUAL, T_IS_IDENTICAL, T_IS_NOT_IDENTICAL, T_IS_NOT_EQUAL, T_IS_GREATER_OR_EQUAL))) || $tmpToken == '<' || $tmpToken == '>') {
|
|
$startvalue = $return;
|
|
|
|
$next = $this->_next();
|
|
|
|
$value = $this->_nextCommand();
|
|
|
|
$return = $this->_compareOperator($startvalue, $value, $tmpToken);
|
|
|
|
//$this->_debug(" # _ShortCompare ".$startvalue . " -- " . $value . ' '.serialize($return));
|
|
|
|
if($this->_NegotiateCompare == true) { $return = !$return; $this->_NegotiateCompare = false; }
|
|
|
|
}
|
|
$this->_intend--;
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] _nextCommand [".htmlentities(json_encode($return)."")."]");
|
|
|
|
return $return;
|
|
}
|
|
|
|
public function setReference($variable, VTEntity $context) {
|
|
$this->StaticReference[$variable] = $context;
|
|
}
|
|
public function setVariable($variable, $value) {
|
|
$this->_variables[$variable] = $value;
|
|
}
|
|
|
|
private function _getArrayKey() {
|
|
if($this->_next(false) == "[") {
|
|
$this->_currentPos++;
|
|
}
|
|
$next = $this->_nextCommand();
|
|
|
|
if($this->_next(false) == "]") {
|
|
$this->_currentPos++;
|
|
}
|
|
|
|
return $next;
|
|
}
|
|
private function _getArrayValues() {
|
|
//$this->_debug("[+] _getArrayValues");
|
|
$this->_intend++;
|
|
|
|
$parameter = array();
|
|
do {
|
|
$this->checkRuntime();
|
|
$nextToken = $this->_next(false);
|
|
|
|
if($nextToken == ";") {
|
|
throw new ExpressionException("Error in ExpressionParser near. An ')' is missing!");
|
|
}
|
|
|
|
if($nextToken == "(" || $nextToken == "," || $nextToken == ")") {
|
|
$this->_currentPos++;
|
|
|
|
if($nextToken == "(" && $this->_next(false) == ")") {
|
|
$this->_intend--;
|
|
//$this->_debug("[-] _getArrayValues (No Args)");
|
|
|
|
$this->_currentPos++;
|
|
return array();
|
|
}
|
|
}
|
|
|
|
if($nextToken == ")") {
|
|
break;
|
|
}
|
|
|
|
$value = $this->_nextCommand();
|
|
|
|
$nextToken = $this->_next(false);
|
|
if(is_array($nextToken) && $nextToken[0] == T_DOUBLE_ARROW) {
|
|
$setValue = $this->_next();
|
|
$setValue = $this->_nextCommand();
|
|
$parameter[$value] = $setValue;
|
|
} else {
|
|
$parameter[] = $value;
|
|
}
|
|
|
|
|
|
if($this->_currentPos > $this->_tokenCount) {
|
|
break;
|
|
}
|
|
} while(1 == 1);
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] _getArrayValues (".json_encode($parameter).")");
|
|
|
|
return $parameter;
|
|
}
|
|
private function _getFunctionParameters() {
|
|
//$this->_debug("[+] __getFunctionParameters");
|
|
$this->_intend++;
|
|
|
|
$parameter = array();
|
|
do {
|
|
$nextToken = $this->_next(false);
|
|
|
|
if($nextToken == ";") {
|
|
throw new ExpressionException("Error in ExpressionParser near. An ')' is missing!");
|
|
}
|
|
|
|
if($nextToken == "(" || $nextToken == "," || $nextToken == ")") {
|
|
$this->_currentPos++;
|
|
|
|
if($nextToken == "(" && $this->_next(false) == ")") {
|
|
$this->_intend--;
|
|
//$this->_debug("[-] __getFunctionParameters (No Args)");
|
|
|
|
$this->_currentPos++;
|
|
return array();
|
|
}
|
|
}
|
|
|
|
if($nextToken == ")") {
|
|
break;
|
|
}
|
|
|
|
$parameter[] = $this->_nextCommand();
|
|
|
|
if($this->_currentPos > $this->_tokenCount) {
|
|
break;
|
|
}
|
|
} while(1 == 1);
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] __getFunctionParameters ('".implode("','", $parameter)."')");
|
|
|
|
return $parameter;
|
|
}
|
|
|
|
private function _getValueString() {
|
|
//$this->_debug("[+] _getValueString");
|
|
$nextToken = $this->_next();
|
|
|
|
switch($nextToken[0]) {
|
|
|
|
# case
|
|
}
|
|
//$this->_debug("[-] _getValueString");
|
|
}
|
|
|
|
private function _executeBlock() {
|
|
$shouldClose = 1;
|
|
do {
|
|
$next = $this->_next(false);
|
|
|
|
if($next == "{") {
|
|
$shouldClose++;
|
|
}
|
|
if($next == "}") {
|
|
$this->_currentPos++;
|
|
$shouldClose--;
|
|
|
|
if($shouldClose <= 0) {
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
$this->_nextCommand();
|
|
|
|
if($next === -1) {
|
|
throw new \Exception("ERROR IN EXPRESSION ".$this->_expression, E_NONBREAK_ERROR);
|
|
}
|
|
} while(1==1);
|
|
}
|
|
|
|
private function _run_for() {
|
|
//$this->_debug("[+] _run_for");
|
|
$this->_intend++;
|
|
|
|
$nextValue = $this->_next(false);
|
|
|
|
if($nextValue != "(") {
|
|
throw new ExpressionException("Error in ExpressionParser near for");
|
|
}
|
|
$this->_next();
|
|
|
|
# Setter Init
|
|
$nextValue1 = $this->_nextCommand();
|
|
|
|
$this->_skip_useless();
|
|
|
|
$startPos = $this->_currentPos;
|
|
$counter = 0;
|
|
$first = true;
|
|
|
|
do {
|
|
//$this->_debug("[ ] start new Loop");
|
|
|
|
if($first === false) {
|
|
//$this->_debug(" do Modification Part");
|
|
$this->_currentPos = $startModifyPos;
|
|
$this->_nextCommand();
|
|
$this->_currentPos = $startCondPos;
|
|
|
|
} else {
|
|
|
|
$startCondPos = $this->_currentPos;
|
|
|
|
}
|
|
|
|
$finishCheck = $this->_nextCommand();
|
|
/*
|
|
$operator = $this->_next();
|
|
$nextValue2 = $this->_nextCommand();
|
|
*/
|
|
|
|
//$finishCheck = $this->_compareOperator($nextValue1, $nextValue2, $operator);
|
|
|
|
if($finishCheck == false || $counter >= $this->_loopLimit) {
|
|
break;
|
|
}
|
|
$counter++;
|
|
|
|
if($first == false) {
|
|
$this->_currentPos = $startExecPos;
|
|
}
|
|
|
|
$this->_skip_useless();
|
|
|
|
if($first === true) {
|
|
$startModifyPos = $this->_currentPos;
|
|
|
|
//$this->_debug("skip operation for first run");
|
|
|
|
do {
|
|
$this->_next();
|
|
} while($this->_next(false) != "{");
|
|
|
|
//$this->_debug("skip operation for first run END");
|
|
$this->_next();
|
|
$first = false;
|
|
|
|
$startExecPos = $this->_currentPos;
|
|
$first = false;
|
|
}
|
|
|
|
$this->_executeBlock();
|
|
|
|
} while(true);
|
|
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] _run_for");
|
|
}
|
|
|
|
private function _run_foreach() {
|
|
//$this->_debug("[+] _run_foreach");
|
|
$this->_intend++;
|
|
|
|
$nextValue = $this->_next(false);
|
|
if($nextValue == "(") {
|
|
$keyVar = false;
|
|
$valueVar = false;
|
|
|
|
$this->_currentPos++;
|
|
$arrayVar = $this->_nextCommand();
|
|
|
|
$as = $this->_next();
|
|
$firstVar = $this->_next();
|
|
|
|
if($firstVar != "{") {
|
|
if(!is_array($firstVar) || $firstVar[0] != T_VARIABLE) {
|
|
if(is_array($firstVar)) {
|
|
throw new ExpressionException("Error in ExpressionParser near as ".$firstVar[1].")");
|
|
} else {
|
|
throw new ExpressionException("Error in ExpressionParser near as ".$firstVar.")");
|
|
}
|
|
}
|
|
$firstVar = $firstVar[1];
|
|
|
|
$nextValue = $this->_next();
|
|
if($nextValue == ")") {
|
|
$keyVar = false;
|
|
$valueVar = $firstVar;
|
|
} elseif($nextValue[0] == T_DOUBLE_ARROW) {
|
|
$secondVar = $this->_next();
|
|
if(!is_array($secondVar) || $secondVar[0] != T_VARIABLE) {
|
|
if(is_array($secondVar)) {
|
|
throw new ExpressionException("Error in ExpressionParser near ".$firstVar." => ".$secondVar[1].")");
|
|
} else {
|
|
throw new ExpressionException("Error in ExpressionParser near ".$firstVar." => ".$secondVar.")");
|
|
}
|
|
}
|
|
$secondVar = $secondVar[1];
|
|
|
|
$keyVar = $firstVar;
|
|
$valueVar = $secondVar;
|
|
|
|
## Skip )
|
|
$nextValue = $this->_next();
|
|
}
|
|
|
|
$next = $this->_next(false);
|
|
} else {
|
|
$next = "{";
|
|
$this->_currentPos--;
|
|
}
|
|
|
|
if($next == "{") {
|
|
$this->_currentPos++;
|
|
|
|
//$this->_debug("[+] start ".count($arrayVar)." iteration [key=".$keyVar." value=".$valueVar."]");
|
|
$startPos = $this->_currentPos;
|
|
|
|
foreach($arrayVar as $runIndex => $runValue) {
|
|
$this->_currentPos = $startPos;
|
|
//$this->_debug("[+] run foreach Block [".$runIndex."=>".$runValue."]");
|
|
$this->_intend++;
|
|
|
|
if($keyVar !== false) {
|
|
$this->_variables[substr($keyVar, 1)] = $runIndex;
|
|
}
|
|
if($valueVar !== false) {
|
|
$this->_variables[substr($valueVar, 1)] = $runValue;
|
|
}
|
|
$this->_executeBlock();
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] run foreach Block");
|
|
}
|
|
//$this->_debug("[-] stop iteration");
|
|
|
|
//$this->_debug("[-] run foreach Block");
|
|
}
|
|
|
|
}
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] _run_foreach");
|
|
}
|
|
|
|
private function _skip_useless() {
|
|
$useless = array(" ", ";");
|
|
//$this->_debug("[+] _skip_useless");
|
|
$this->_intend++;
|
|
|
|
while(in_array($this->_next(false), $useless)) {
|
|
//$this->_debug("skip '".$this->_next(false)."'");
|
|
$this->_next();
|
|
}
|
|
$this->_intend--;
|
|
}
|
|
private function _run_if() {
|
|
//$this->_debug("[+] _run_IF");
|
|
|
|
$nextValue = $this->_next(false);
|
|
if($nextValue == "(") {
|
|
$this->_currentPos++;
|
|
$compareResult = $this->_compare();
|
|
|
|
//$this->_debug("[ ] _run_IF Result: ".intval($compareResult));
|
|
if($compareResult == true) {
|
|
$next = $this->_next(false);
|
|
|
|
if($next == "{") {
|
|
$this->_currentPos++;
|
|
$shouldClose = 1;
|
|
|
|
//$this->_debug("[+] run first Block");
|
|
$this->_intend++;
|
|
do {
|
|
$next = $this->_next(false);
|
|
|
|
|
|
if(empty($next)) {
|
|
throw new \Exception("ERROR IN EXPRESSION ".$this->_expression, E_EXPRESSION_ERROR);
|
|
}
|
|
if($next == "{") {
|
|
$shouldClose++;
|
|
}
|
|
if($next == "}") {
|
|
$this->_currentPos++;
|
|
$shouldClose--;
|
|
if($shouldClose <= 0) {
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
$this->_nextCommand();
|
|
|
|
if($next === -1) {
|
|
throw new \Exception("ERROR IN EXPRESSION ".$this->_expression, E_EXPRESSION_ERROR);
|
|
}
|
|
} while(1==1);
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] run first Block");
|
|
}
|
|
|
|
// $this->_currentPos++;
|
|
// $this->_currentPos++;
|
|
$nextToken = $this->_next(false);
|
|
|
|
if($nextToken[0] == T_ELSE) {
|
|
$shouldClose = 0;
|
|
//$this->_debug("[ ] skip second Block");
|
|
$this->_intend++;
|
|
do {
|
|
$next = $this->_next();
|
|
|
|
if($next == "{") {
|
|
$shouldClose++;
|
|
}
|
|
if($next == "}") {
|
|
$shouldClose--;
|
|
if($shouldClose <= 0) {
|
|
break;
|
|
}
|
|
}
|
|
if($next === -1) {
|
|
throw new \Exception("ERROR IN EXPRESSION ".$this->_expression, E_EXPRESSION_ERROR);
|
|
}
|
|
} while(1==1);
|
|
$this->_intend--;
|
|
}
|
|
} else {
|
|
$shouldClose = 0;
|
|
//$this->_debug("[ ] skip first Block");
|
|
$this->_intend++;
|
|
do {
|
|
$next = $this->_next();
|
|
|
|
|
|
if($next == "{") {
|
|
$shouldClose++;
|
|
}
|
|
if($next == "}") {
|
|
$shouldClose--;
|
|
if($shouldClose <= 0) {
|
|
break;
|
|
}
|
|
}
|
|
if($next === -1) {
|
|
throw new \Exception("ERROR IN EXPRESSION ".$this->_expression, E_EXPRESSION_ERROR);
|
|
}
|
|
} while(1==1);
|
|
$this->_intend--;
|
|
|
|
$nextToken = $this->_next(false);
|
|
|
|
if($nextToken[0] == T_ELSE) {
|
|
$this->_currentPos++;
|
|
$nextToken = $this->_next(false);
|
|
if($nextToken == "{") {
|
|
$this->_currentPos++;
|
|
}
|
|
|
|
//$this->_debug("[+] run second Block");
|
|
$shouldClose = 1;
|
|
$this->_intend++;
|
|
do {
|
|
$next = $this->_next(false);
|
|
|
|
if($next === -1) {
|
|
throw new \Exception("ERROR IN EXPRESSION ".$this->_expression, E_EXPRESSION_ERROR);
|
|
}
|
|
|
|
if($next == "{") {
|
|
$shouldClose++;
|
|
}
|
|
if($next == "}") {
|
|
$this->_currentPos++;
|
|
$shouldClose--;
|
|
if($shouldClose <= 0) {
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
$this->_nextCommand();
|
|
|
|
} while(1==1);
|
|
|
|
$this->_intend--;
|
|
//$this->_debug("[-] run second Block");
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
//$this->_debug("[-] _run_IF");
|
|
}
|
|
|
|
private function _compare() {
|
|
//$this->_debug("[+] _compare");$this->_intend++;
|
|
$compareResult = true;
|
|
$negotiate = false;
|
|
|
|
$nextValue = $this->_next(false);
|
|
|
|
if($nextValue == "!") {
|
|
while($nextValue == "!") {
|
|
$this->_currentPos++;
|
|
$negotiate = !$negotiate;
|
|
$nextValue = $this->_next(false);
|
|
}
|
|
}
|
|
|
|
if($nextValue == "(") {
|
|
//$this->_debug("[ ] Found SubCompare");
|
|
$this->_currentPos++;
|
|
$compareResult = $this->_compare();
|
|
} else {
|
|
$this->_NegotiateCompare = $negotiate;
|
|
$compareResult = $this->_nextCommand();
|
|
if($negotiate === true && $this->_NegotiateCompare === false) {
|
|
$negotiate = false;
|
|
}
|
|
}
|
|
|
|
do {
|
|
$operator = $this->_next(true);
|
|
|
|
if($operator == ")") {
|
|
break;
|
|
}
|
|
if($operator === -1 || $operator == "{") {
|
|
throw new \Exception("ERROR IN EXPRESSION _compare", E_EXPRESSION_ERROR);
|
|
}
|
|
|
|
if(is_array($operator) && in_array($operator[0], array(T_BOOLEAN_AND, T_BOOLEAN_OR, T_LOGICAL_AND, T_LOGICAL_OR))) {
|
|
//$this->_currentPos++;
|
|
//$this->_debug("[ ] _compare Before ".$operator[1]." Logical Operator: ".serialize($compareResult));
|
|
$skip = false;
|
|
if(($operator[0] == T_BOOLEAN_AND || $operator[0] == T_LOGICAL_AND) && $compareResult == false && $negotiate == false) {
|
|
$skip = true;
|
|
}
|
|
if(($operator[0] == T_BOOLEAN_OR || $operator[0] == T_LOGICAL_OR) && $compareResult == true && $negotiate == false) {
|
|
$skip = true;
|
|
}
|
|
|
|
if($skip === true) {
|
|
$nextValue = $operator;
|
|
if($nextValue != ")") {
|
|
//var_dump($this->_currentPos, $nextValue);echo '<br/>';
|
|
$counter = 0;
|
|
$shouldClose = 1;
|
|
while($shouldClose != 0) {
|
|
$nextValue = $this->_next(false);
|
|
$this->_currentPos++;
|
|
if($nextValue == '(') {
|
|
$shouldClose++;
|
|
}
|
|
if($nextValue == ')') {
|
|
$shouldClose--;
|
|
}
|
|
}
|
|
}
|
|
|
|
//$this->_debug("[-] _compare Skip Next check because OR Operator Result: ".serialize($compareResult));$this->_intend--;
|
|
return $compareResult;
|
|
}
|
|
|
|
$nextPart = $this->_compare();
|
|
//var_dump($operator);
|
|
if($operator[0] == T_BOOLEAN_AND || $operator[0] == T_LOGICAL_AND) {
|
|
$compareResult = $compareResult && $nextPart;
|
|
} elseif($operator[0] == T_BOOLEAN_OR || $operator[0] == T_LOGICAL_OR) {
|
|
$compareResult = $compareResult || $nextPart;
|
|
}
|
|
|
|
//$this->_debug("[-] _compare Result1: ".serialize($compareResult));$this->_intend--;
|
|
return $compareResult;
|
|
}
|
|
|
|
|
|
$nextValue = $this->_next(false);
|
|
if($nextValue == "(") {
|
|
$this->_currentPos++;
|
|
$checkValue = $this->_compare();
|
|
} else {
|
|
$checkValue = $this->_nextCommand();
|
|
}
|
|
|
|
$compareResult = $this->_compareOperator($compareResult, $checkValue, $operator);
|
|
|
|
if($negotiate == true) {
|
|
//$this->_debug("[ ] Negate Result");
|
|
$compareResult = !$compareResult;
|
|
$negotiate = false;
|
|
}
|
|
|
|
$operator = $this->_next(false);
|
|
|
|
$firstValue = $checkValue;
|
|
} while(1 == 1);
|
|
|
|
if($negotiate == true) { $compareResult = !$compareResult; $negotiate = false; }
|
|
|
|
/*
|
|
do {
|
|
$operator = $this->_next(true);
|
|
if($operator == ")") {
|
|
break;
|
|
}
|
|
if($operator === -1 || $operator == "{") {
|
|
throw new \Exception("ERROR IN EXPRESSION _compare", E_EXPRESSION_ERROR);
|
|
}
|
|
|
|
$nextValue = $this->_next(false);
|
|
if($nextValue == "(") {
|
|
$this->_currentPos++;
|
|
$checkValue = $this->_compare();
|
|
} else {
|
|
$checkValue = $this->_nextCommand();
|
|
}
|
|
|
|
$compareResult = $compareResult && $this->_compareOperator($firstValue, $checkValue, $operator);
|
|
|
|
|
|
$firstValue = $checkValue;
|
|
} while(1 == 1);
|
|
*/
|
|
//$this->_debug("[-] _compare Result2: ".serialize($compareResult));$this->_intend--;
|
|
return $compareResult;
|
|
}
|
|
|
|
private function _compareOperator($value1, $value2, $operatorToken) {
|
|
if(is_string($operatorToken)) {
|
|
$compareOperator = $operatorToken;
|
|
} else {
|
|
$compareOperator = $operatorToken[0];
|
|
}
|
|
|
|
//$this->_debug('[ ] Compare Operators '.$value1.' '.$value2.' '.json_encode($operatorToken));
|
|
switch($compareOperator) {
|
|
case "<":
|
|
return $value1 < $value2;
|
|
break;
|
|
case ">":
|
|
return $value1 > $value2;
|
|
break;
|
|
case T_IS_EQUAL:
|
|
return $value1 == $value2;
|
|
break;
|
|
case T_IS_GREATER_OR_EQUAL:
|
|
return $value1 >= $value2;
|
|
break;
|
|
case T_IS_IDENTICAL:
|
|
return $value1 === $value2;
|
|
break;
|
|
|
|
case T_IS_NOT_EQUAL:
|
|
return $value1 != $value2;
|
|
break;
|
|
|
|
case T_IS_NOT_IDENTICAL:
|
|
return $value1 !== $value2;
|
|
break;
|
|
|
|
case T_IS_SMALLER_OR_EQUAL:
|
|
return $value1 <= $value2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class ExpressionException extends \Exception
|
|
{
|
|
|
|
}
|
|
|
|
$alle = glob(dirname(__FILE__).'/../../extends/functions/*.inc.php');
|
|
foreach($alle as $datei) { include_once(realpath($datei)); }
|
|
|
|
if(!file_exists('php_check_syntax')) {
|
|
/**
|
|
* Check Syntax
|
|
* Performs a Syntax check within a php script, without killing the parser (hopefully)
|
|
* Do not use this with PHP 5 <= PHP 5.0.4, or rename this function.
|
|
*
|
|
* @params string PHP to be evaluated
|
|
* @return array Parse error info or true for success
|
|
**/
|
|
function php_check_syntax($php, $isFile = false)
|
|
{
|
|
# Get the string tokens
|
|
$tokens = token_get_all('<?php ' . trim($php));
|
|
|
|
# Drop our manually entered opening tag
|
|
array_shift($tokens);
|
|
token_fix($tokens);
|
|
|
|
# Check to see how we need to proceed
|
|
# prepare the string for parsing
|
|
if (isset($tokens[0][0]) && $tokens[0][0] === T_OPEN_TAG)
|
|
$evalStr = $php;
|
|
else
|
|
$evalStr = "<?php\n{$php}?>";
|
|
|
|
if ($isFile OR ($tf = tempnam(NULL, 'parse-') AND file_put_contents($tf, $php) !== FALSE) AND $tf = $php) {
|
|
# Prevent output
|
|
ob_start();
|
|
system('php -l < ' . $php, $ret);
|
|
$output = ob_get_clean();
|
|
|
|
if ($ret !== 0) {
|
|
# Parse error to report?
|
|
if ((bool)preg_match('/Parse error:\s*syntax error,(.+?)\s+in\s+.+?\s*line\s+(\d+)/', $output, $match)) {
|
|
return array(
|
|
'line' => (int)$match[2],
|
|
'msg' => $match[1]
|
|
);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function token_fix(&$tokens)
|
|
{
|
|
if (!is_array($tokens) || (count($tokens) < 2)) {
|
|
return;
|
|
}
|
|
//return of no fixing needed
|
|
if (is_array($tokens[0]) && (($tokens[0][0] == T_OPEN_TAG) || ($tokens[0][0] == T_OPEN_TAG_WITH_ECHO))) {
|
|
return;
|
|
}
|
|
//continue
|
|
$p1 = (is_array($tokens[0]) ? $tokens[0][1] : $tokens[0]);
|
|
$p2 = (is_array($tokens[1]) ? $tokens[1][1] : $tokens[1]);
|
|
$p3 = '';
|
|
|
|
if (($p1 . $p2 == '<?') || ($p1 . $p2 == '<%')) {
|
|
$type = ($p2 == '?') ? T_OPEN_TAG : T_OPEN_TAG_WITH_ECHO;
|
|
$del = 2;
|
|
//update token type for 3rd part?
|
|
if (count($tokens) > 2) {
|
|
$p3 = is_array($tokens[2]) ? $tokens[2][1] : $tokens[2];
|
|
$del = (($p3 == 'php') || ($p3 == '=')) ? 3 : 2;
|
|
$type = ($p3 == '=') ? T_OPEN_TAG_WITH_ECHO : $type;
|
|
}
|
|
//rebuild erroneous token
|
|
$temp = array($type, $p1 . $p2 . $p3);
|
|
if (version_compare(phpversion(), '5.2.2', '<') === false)
|
|
$temp[] = isset($tokens[0][2]) ? $tokens[0][2] : 'unknown';
|
|
|
|
//rebuild
|
|
$tokens[1] = '';
|
|
if ($del == 3) $tokens[2] = '';
|
|
$tokens[0] = $temp;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
?>
|