/** * Return true if code is not obtrusive * * @param string $code * @param boolean $multi_lines * @param mixed $extra_tokens * @param array $invalid_vars * @param boolean $ignore_not_callable * @return boolean */ static final function isValidPHPCode($code, $multi_lines = true, $valid_tokens = null, $invalid_vars = array('$this', '$_SESSION', '$GLOBALS', '$_POST', '$_GET', '$_FILES', '$_COOKIE', '$_ENV', '$_REQUEST'), $allow_classes = false, $allow_functions = false) { if (is_null($valid_tokens)) { $valid_tokens = DIV_PHP_VALID_TOKENS_FOR_EXPRESSIONS . ',' . DIV_PHP_VALID_TOKENS_FOR_MACROS; } $t = token_get_all("<?php {$code} ?>"); foreach ($t as $key => $value) { if (is_array($value)) { $t[$key][0] = token_name($value[0]); } } $count = count($t); if (is_string($valid_tokens)) { $valid_tokens = explode(",", $valid_tokens); } foreach ($valid_tokens as $kk => $tk) { $tk = strtoupper(trim($tk)); $valid_tokens[$tk] = $tk; } /* * foreach ( $callable_enabled as $kk => $tk ) { * $tk = strtoupper(trim($tk)); * $callable_enabled[$tk] = $tk; * } * * foreach ( $callable_disabled as $kk => $tk ) { * $tk = strtoupper(trim($tk)); * $callable_disabled[$tk] = $tk; * } */ if (is_null(self::$__allowed_php_functions)) { $keys = explode(",", DIV_PHP_ALLOWED_FUNCTIONS); self::$__allowed_php_functions = array_combine($keys, $keys); } $object_operator = false; $last_token = null; foreach ($t as $idx => $token) { if ($token == ';' && $multi_lines == false) { self::internalMsg("Multi-lines not allowed", "php_validations"); return false; } if (is_array($token)) { $n = $token[0]; switch ($n) { case 'T_VARIABLE': if (array_search($token[1], $invalid_vars) !== false) { self::internalMsg("Access denied to {$token[1]}", "php_validations"); return false; } break; case 'T_OPEN_TAG': if ($idx > 0) { self::internalMsg("Invalid token T_OPEN_TAG", "php_validations"); return false; } break; case 'T_CLOSE_TAG': if ($idx < $count - 1) { self::internalMsg("Invalid token T_CLOSE_TAG", "php_validations"); return false; } break; case 'T_STRING': $classname = false; $funcname = false; $f = $token[1]; if ($last_token == 'T_CLASS') { $classname = true; } if ($last_token == 'T_FUNCTION') { $funcname = true; } $lw = strtolower($f); if (!isset(self::$__allowed_methods[$f])) { if ($lw != 'true' && $lw != 'false' && $lw != 'null') { if (is_callable($f)) { if (!isset(self::$__allowed_php_functions[$f])) { if (!isset(self::$__allowed_functions[$f])) { self::internalMsg("Invalid function {$f}", "php_validations"); return false; } if (self::$__allowed_functions[$f] === false) { self::internalMsg("Invalid function {$f}", "php_validations"); return false; } } } else { if (($classname && $allow_classes || $funcname && $allow_functions) === false) { self::internalMsg("{$f} is not callable", "php_validations"); return false; } } } } break; default: if (!isset($valid_tokens[$n])) { self::internalMsg("Invalid token {$n}", "php_validations"); return false; } } if ($n != 'T_WHITESPACE') { $last_token = $n; } } } return true; }