function ast_node_type($node, $namespace) { if ($node instanceof \ast\Node) { switch ($node->kind) { case \ast\AST_NAME: if ($node->flags & \ast\flags\NAME_NOT_FQ) { $result = $namespace . $node->children[0]; } else { $result = $node->children[0]; } break; case \ast\AST_TYPE: if ($node->flags == \ast\flags\TYPE_CALLABLE) { $result = 'callable'; } else { if ($node->flags == \ast\flags\TYPE_ARRAY) { $result = 'array'; } else { assert(false, "Unknown type: {$node->flags}"); } } break; default: Log::err(Log::EFATAL, "ast_node_type: unknown node type: " . \ast\get_kind_name($node->kind)); break; } } else { $result = (string) $node; } return $result; }
public static function create($decoder) { if (!isset(self::$sDecoders[$decoder])) { throw new Exception(Log::err("Unknown decoder '{$decoder}'")); } $decoderClass = self::$sDecoders[$decoder]; return new $decoderClass(); }
public static function create($type, $properties) { if (!isset(self::$sTypes[$type])) { throw new Exception(Log::err("Unknown user db type '{$type}'")); } $userdbClass = self::$sTypes[$type]; return new $userdbClass($properties); }
public function __construct($file) { parent::__construct($file, FileDecoder::DECODER_DIRECT); $this->tResource = fopen($file, "r"); if ($this->tResource === false) { throw new Exception(Log::err("Cannot open file '{$file}' for reading")); } }
public function __construct($file) { parent::__construct($file, FileDecoder::DECODER_BZIP2); if (!extension_loaded("bz2")) { throw new Exception(Log::err("Missing extension 'bz2' for bzip2 decoding")); } $this->tResource = bzopen($file, "r"); if ($this->tResource === false) { throw new Exception(Log::err("Cannot open file '{$file}' for reading")); } }
public static function extensions($names) { $missing = array(); foreach ($names as $name) { if (!extension_loaded($name)) { $missing[] = $name; } } if (count($missing) > 0) { throw new Exception(Log::err(sprintf("Missing required extension(s): %s", Strings::format($missing)))); } }
public function renderLogin() { if (!empty($this->context->params['user_login']) && !empty($this->context->params['user_pwd'])) { try { $authentResult = $this->get('auth')->login($this->context->params['user_login'], $this->context->params['user_pwd']); if ($authentResult) { $this->redirect('user'); } } catch (Exception $e) { Log::err($e->getMessage()); $this->redirect('user', array('msg' => $e->getCode())); } } $this->redirect('user', array('msg' => ERR_LOGIN)); }
protected function __construct($dbh) { $this->tDbh = $dbh; session_name(self::SESSION_NAME); if (!session_start()) { throw new Exception(Log::err("Cannot start session")); } if (!isset($_SESSION[self::SESSION_LANG])) { $_SESSION[self::SESSION_LANG] = self::getDefaultLang(); } self::mergeSession(self::SESSION_LANG); $this->tL12n = L12n::match($this->getSessionLang()); if (!isset($_SESSION[self::SESSION_MOBILE])) { $_SESSION[self::SESSION_MOBILE] = self::getDefaultMobile(); } self::mergeSession(self::SESSION_MOBILE); }
/** * Handler for uncatched exceptions. * * @param Exception $exception */ public static function exceptionHandler($exception) { error_log("Unhandled exception: Code {$exception->getCode()}; Message: {$exception->getMessage()}"); if (class_exists('Log') && !is_null(Log::getLogger())) { Log::err(sprintf('Lpf_ExceptionHandler: Unhandled exception [%s] `%s`', $exception->getCode(), $exception->getMessage())); } if (Config::DEBUG_MODE) { echo "[Debug mode] Unhandled exception: Code {$exception->getCode()}; Message: {$exception->getMessage()}\r\n"; echo $exception->getTraceAsString(); exit; } else { if ($exception->getCode() == 404) { header("HTTP/1.0 404 Not Found", true, 404); die('<h1 style="text-align:center;">Error 404: Page Not Found</h1>'); } else { header("HTTP/1.0 500 Internal Server Error", true, 500); die('<h1 style="text-align:center;">Error 500: Internal Server Error</h1>'); } } }
public function sendError($exception) { $errorName = 'Erreur inconnue'; $errorType = array(E_ERROR => 'Fatal error', E_WARNING => 'Warning', E_PARSE => 'Parse error', E_NOTICE => 'Notice', ERROR_SQL => 'SQL', ERROR_BEHAVIOR => 'Behavior'); if (!empty($errorType[$exception->getCode()])) { $errorName = $errorType[$exception->getCode()]; } $sessionDatas = "<br/><br/>Valeurs de session : <br/>"; if ($this->context->get('user_id')) { $sessionDatas .= 'user_id => ' . $this->context->get('user_id') . '<br/>'; } if ($this->context->get('user_login')) { $sessionDatas .= 'user_login => ' . $this->context->get('user_login') . '<br/>'; } if ($this->context->get('user_valid')) { $sessionDatas .= 'user_valid => ' . $this->context->get('user_valid') . '<br/>'; } $message = nl2br('<b>Erreur ' . $errorName . ' :</b>' . '<br/><br/>' . $exception->getMessage() . '<br/><br/>' . $sessionDatas . '<br/><br/>Stack :<br/>' . $exception->getTraceAsString()); Log::err(str_replace(array('<br/>', '<b>', '</b>', '<br />'), array("\n", '', '', ''), $message)); return $this->send(ADMIN_MAIL, 'Erreur sur MetalLink !', $message, false); }
public static function setUp($logSettings) { Log::$err = $logSettings['errors']; Log::$warn = $logSettings['warnings']; Log::$all = $logSettings['all']; Log::$debug = $logSettings['debug']; Log::$req = $logSettings['requests']; //removing old files if (file_exists(Log::$err)) { unlink(Log::$err); } if (file_exists(Log::$warn)) { unlink(Log::$warn); } if (file_exists(Log::$all)) { unlink(Log::$all); } if (file_exists(Log::$debug)) { unlink(Log::$debug); } if (file_exists(Log::$req)) { unlink(Log::$req); } }
/** * @return void */ public function __invoke() { Log::err($this->getIssue()->getCategory(), $this->getIssue()->getType(), $this->getIssue()->getSeverity(), call_user_func_array('sprintf', array_merge([$this->getIssue()->getTemplate()], $this->getTemplateParameters())), $this->getFile(), $this->getLine()); }
function node_type($file, $namespace, $node, $current_scope, $current_class, &$taint = null, $check_var_exists = true) { global $classes, $functions, $scope, $namespace_map, $internal_arginfo; if (!$node instanceof \ast\Node) { if ($node === null) { return ''; } return type_map(gettype($node)); } else { if ($node->kind == \ast\AST_ARRAY) { return 'array'; } else { if ($node->kind == \ast\AST_BINARY_OP) { $taint = var_taint_check($file, $node, $current_scope); switch ($node->flags) { // Always a string from a concat case \ast\flags\BINARY_CONCAT: $temp_taint = false; node_type($file, $namespace, $node->children[0], $current_scope, $current_class, $temp_taint); if ($temp_taint) { $taint = true; return 'string'; } node_type($file, $namespace, $node->children[1], $current_scope, $current_class, $temp_taint); if ($temp_taint) { $taint = true; } return 'string'; break; // Boolean unless invalid operands // Boolean unless invalid operands case \ast\flags\BINARY_IS_IDENTICAL: case \ast\flags\BINARY_IS_NOT_IDENTICAL: case \ast\flags\BINARY_IS_EQUAL: case \ast\flags\BINARY_IS_NOT_EQUAL: case \ast\flags\BINARY_IS_SMALLER: case \ast\flags\BINARY_IS_SMALLER_OR_EQUAL: $taint = false; return 'bool'; break; // Add is special because you can add arrays // Add is special because you can add arrays case \ast\flags\BINARY_ADD: $temp = node_type($file, $namespace, $node->children[0], $current_scope, $current_class); if (!$temp) { $left = ''; } else { $left = type_map($temp); } $temp = node_type($file, $namespace, $node->children[1], $current_scope, $current_class); if (!$temp) { $right = ''; } else { $right = type_map($temp); } if ($left == 'array' && $right == 'array') { return 'array'; } else { if ($left == 'array' && !type_check($right, 'array')) { Log::err(Log::ETYPE, "invalid operator: left operand is array and right is not", $file, $node->lineno); return ''; } else { if ($right == 'array' && !type_check($left, 'array')) { Log::err(Log::ETYPE, "invalid operator: right operand is array and left is not", $file, $node->lineno); return ''; } else { if ($left == 'int' && $right == 'int') { return 'int'; } else { if ($left == 'float' || $right == 'float') { return 'float'; } else { if ($left == 'array' || $right == 'array') { // If it is a '+' and we know one side is an array and the other is unknown, assume array return 'array'; } } } } } } return 'int|float'; $taint = false; break; // Everything else should be an int/float // Everything else should be an int/float default: $temp = node_type($file, $namespace, $node->children[0], $current_scope, $current_class); if (!$temp) { $left = ''; } else { $left = type_map($temp); } $temp = node_type($file, $namespace, $node->children[1], $current_scope, $current_class); if (!$temp) { $right = ''; } else { $right = type_map($temp); } if ($left == 'array' || $right == 'array') { Log::err(Log::ETYPE, "invalid array operator", $file, $node->lineno); return ''; } else { if ($left == 'int' && $right == 'int') { return 'int'; } else { if ($left == 'float' || $right == 'float') { return 'float'; } } } return 'int|float'; $taint = false; break; } } else { if ($node->kind == \ast\AST_CAST) { $taint = var_taint_check($file, $node->children[0], $current_scope); switch ($node->flags) { case \ast\flags\TYPE_NULL: return 'null'; break; case \ast\flags\TYPE_BOOL: $taint = false; return 'bool'; break; case \ast\flags\TYPE_LONG: $taint = false; return 'int'; break; case \ast\flags\TYPE_DOUBLE: $taint = false; return 'float'; break; case \ast\flags\TYPE_STRING: return 'string'; break; case \ast\flags\TYPE_ARRAY: return 'array'; break; case \ast\flags\TYPE_OBJECT: return 'stdClass'; break; default: Log::err(Log::EFATAL, "Unknown type (" . $node->flags . ") in cast"); } } else { if ($node->kind == \ast\AST_NEW) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); if ($class_name) { return $classes[strtolower($class_name)]['type']; } return 'object'; } else { if ($node->kind == \ast\AST_DIM) { $taint = var_taint_check($file, $node->children[0], $current_scope); // TODO: Do something smart with array elements return ''; } else { if ($node->kind == \ast\AST_VAR) { return var_type($file, $node, $current_scope, $taint, $check_var_exists); } else { if ($node->kind == \ast\AST_ENCAPS_LIST) { foreach ($node->children as $encap) { if ($encap instanceof \ast\Node) { if (var_taint_check($file, $encap, $current_scope)) { $taint = true; } } } return "string"; } else { if ($node->kind == \ast\AST_CONST) { if ($node->children[0]->kind == \ast\AST_NAME) { if (defined($node->children[0]->children[0])) { return type_map(gettype(constant($node->children[0]->children[0]))); } else { // Todo: user-defined constant } } } else { if ($node->kind == \ast\AST_PROP) { if ($node->children[0]->kind == \ast\AST_VAR) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); if ($class_name && !$node->children[1] instanceof \ast\Node) { if (empty($classes[strtolower($class_name)]['properties'][$node->children[1]])) { return ''; } return $classes[strtolower($class_name)]['properties'][$node->children[1]]['value']; } } } else { if ($node->kind == \ast\AST_CALL) { if ($node->children[0]->kind == \ast\AST_NAME) { $func_name = $node->children[0]->children[0]; if ($node->children[0]->flags & \ast\flags\NAME_NOT_FQ) { $func = $namespace_map[T_FUNCTION][$file][strtolower($namespace . $func_name)] ?? $namespace_map[T_FUNCTION][$file][strtolower($func_name)] ?? $functions[strtolower($namespace . $func_name)] ?? $functions[strtolower($func_name)] ?? null; } else { $func = $functions[strtolower($func_name)] ?? null; } if ($func['file'] == 'internal' && empty($func['ret'])) { if (!empty($internal_arginfo[$func_name])) { return $internal_arginfo[$func_name][0] ?? ''; } } else { return $func['ret'] ?? ''; } } else { // TODO: Handle $func() and other cases that get here } } else { if ($node->kind == \ast\AST_STATIC_CALL) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); $method = find_method($class_name, $node->children[1]); if ($method) { return $method['ret'] ?? ''; } } else { if ($node->kind == \ast\AST_METHOD_CALL) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); if ($class_name) { $method_name = $node->children[1]; $method = find_method($class_name, $method_name); if ($method === false) { Log::err(Log::EUNDEF, "call to undeclared method {$class_name}->{$method_name}()", $file, $node->lineno); } else { if ($method != 'dynamic') { return $method['ret']; } } } } } } } } } } } } } } } } return ''; }
function node_func($file, $conditional, $node, $current_scope, $current_class, $namespace = '') { global $scope; if ($node instanceof \ast\Node) { $req = $opt = 0; $dc = ['return' => '', 'params' => []]; if (!empty($node->docComment)) { $dc = parse_doc_comment($node->docComment); } $result = ['file' => $file, 'namespace' => $namespace, 'scope' => $current_scope, 'conditional' => $conditional, 'flags' => $node->flags, 'lineno' => $node->lineno, 'endLineno' => $node->endLineno, 'name' => strpos($current_scope, '::') === false ? $namespace . $node->name : $node->name, 'docComment' => $node->docComment, 'params' => node_paramlist($file, $node->children[0], $req, $opt, $dc, $namespace), 'required' => $req, 'optional' => $opt, 'ret' => '', 'oret' => '', 'ast' => $node->children[2]]; if ($node->children[3] !== null) { $result['oret'] = ast_node_type($file, $node->children[3], $namespace); // Original return type $result['ret'] = ast_node_type($file, $node->children[3], $namespace); // This one changes as we walk the tree } else { // Check if the docComment has a return value specified if (!empty($dc['return'])) { if ($dc['return'] == 'static' || $dc['return'] == 'self' || $dc['return'] == '$this') { if (strpos($current_scope, '::') !== false) { list($dc['return'], ) = explode('::', $current_scope); } } $result['oret'] = $dc['return']; $result['ret'] = $dc['return']; } } // Add params to local scope for user functions if ($file != 'internal') { $i = 1; foreach ($result['params'] as $k => $v) { if (empty($v['type'])) { // If there is no type specified in PHP, check for a docComment // We assume order in the docComment matches the parameter order in the code if (!empty($dc['params'][$k]['type'])) { $scope[$current_scope]['vars'][$v['name']] = ['type' => $dc['params'][$k]['type'], 'tainted' => false, 'tainted_by' => '', 'param' => $i]; } else { $scope[$current_scope]['vars'][$v['name']] = ['type' => '', 'tainted' => false, 'tainted_by' => '', 'param' => $i]; } } else { $scope[$current_scope]['vars'][$v['name']] = ['type' => $v['type'], 'tainted' => false, 'tainted_by' => '', 'param' => $i]; } if (array_key_exists('def', $v)) { $type = node_type($file, $namespace, $v['def'], $current_scope, $current_class); if ($type === "NULL") { add_type($current_scope, $v['name'], $type); if (!empty($result['params'][$k]['type'])) { $result['params'][$k]['type'] .= '|NULL'; } } else { if ($scope[$current_scope]['vars'][$v['name']]['type'] !== '') { // Does the default value match the declared type? if (!type_check($type, $scope[$current_scope]['vars'][$v['name']]['type'])) { Log::err(Log::ETYPE, "Default value for {$scope[$current_scope]['vars'][$v['name']]['type']} \${$v['name']} can't be {$type}", $file, $node->lineno); } } } } $i++; } } return $result; } assert(false, "{$node} was not an \\ast\\Node"); }
public function renderSubmit() { if (!empty($this->context->params['last_content']) && !empty($this->context->params['content']) && $this->context->params['last_content'] === $this->context->params['content']) { $this->render(); return; } if (empty($this->context->params['destinataire_id'])) { Log::err('destinataire vide'); $this->redirect('mailbox', array('msg' => ERR_DEFAULT)); } $isLinked = $this->get('link')->isLinked($this->context->params['destinataire_id']); if (!$isLinked) { Log::err('destinataire sans link'); $this->redirect('mailbox', array('msg' => ERR_DEFAULT)); } $from = $this->context->get('user_id'); $to = $this->context->params['destinataire_id']; if (empty($this->context->params['content'])) { $this->view->growler('Message vide.', GROWLER_INFO); $this->render(); return; } if ($this->get('message')->send($from, $to, $this->context->params['content'])) { $message = $this->context->get('user_login') . ' vous a envoyé un nouveau message ! <a href="http://metallink.fr/message/' . $this->context->get('user_id') . '">Cliquez ici</a> pour le lire.'; $this->redirect('message', array($this->context->params['value'], 'msg' => MSG_SENT_OK)); } else { Log::err('impossible d\'enregistrer le message.'); $this->redirect('mailbox', array('msg' => ERR_MAIL)); } return; }
private static function prepareNetworkmapEntry($sourceKey, $networkName, $address, $prefix) { $addressValue = inet_pton($address); if ($addressValue === false) { throw new Exception(Log::err("Unexpected address '{$address}' while preparing network map for network '{$networkName}'")); } if (!isset(self::$sNetworkmapIndex[$sourceKey])) { self::$sNetworkmapIndex[$sourceKey] = array(); } if (!isset(self::$sNetworkmapIndex[$sourceKey][$prefix])) { self::$sNetworkmapIndex[$sourceKey][$prefix] = array(); } $addressKey = self::address2Key($addressValue, $prefix); self::$sNetworkmapIndex[$sourceKey][$prefix][$addressKey] = $networkName; }
function node_type($file, $namespace, $node, $current_scope, $current_class, &$taint = null, $check_var_exists = true) { global $classes, $functions, $scope, $namespace_map, $internal_arginfo; if (!$node instanceof \ast\Node) { if ($node === null) { return ''; } return type_map(gettype($node)); } else { if ($node->kind == \ast\AST_ARRAY) { if (!empty($node->children) && $node->children[0] instanceof \ast\Node && $node->children[0]->kind == \ast\AST_ARRAY_ELEM) { // Check the first 5 (completely arbitrary) elements and assume the rest are the same type $etypes = []; for ($i = 0; $i < 5; $i++) { if (empty($node->children[$i])) { break; } if ($node->children[$i]->children[0] instanceof \ast\Node) { $etypes[] = node_type($file, $namespace, $node->children[$i]->children[0], $current_scope, $current_class, $temp_taint); } else { $etypes[] = type_map(gettype($node->children[$i]->children[0])); } } $types = array_unique($etypes); if (count($types) == 1 && !empty($types[0])) { return mkgenerics($types[0]); } } return 'array'; } else { if ($node->kind == \ast\AST_BINARY_OP || $node->kind == \ast\AST_GREATER || $node->kind == \ast\AST_GREATER_EQUAL) { if ($node->kind == \ast\AST_BINARY_OP) { $node_flags = $node->flags; } else { $node_flags = $node->kind; } $taint = var_taint_check($file, $node, $current_scope); switch ($node_flags) { // Always a string from a concat case \ast\flags\BINARY_CONCAT: $temp_taint = false; node_type($file, $namespace, $node->children[0], $current_scope, $current_class, $temp_taint); if ($temp_taint) { $taint = true; return 'string'; } node_type($file, $namespace, $node->children[1], $current_scope, $current_class, $temp_taint); if ($temp_taint) { $taint = true; } return 'string'; break; // Boolean unless invalid operands // Boolean unless invalid operands case \ast\flags\BINARY_IS_IDENTICAL: case \ast\flags\BINARY_IS_NOT_IDENTICAL: case \ast\flags\BINARY_IS_EQUAL: case \ast\flags\BINARY_IS_NOT_EQUAL: case \ast\flags\BINARY_IS_SMALLER: case \ast\flags\BINARY_IS_SMALLER_OR_EQUAL: case \ast\AST_GREATER: case \ast\AST_GREATER_EQUAL: $temp = node_type($file, $namespace, $node->children[0], $current_scope, $current_class); if (!$temp) { $left = ''; } else { $left = type_map($temp); } $temp = node_type($file, $namespace, $node->children[1], $current_scope, $current_class); if (!$temp) { $right = ''; } else { $right = type_map($temp); } $taint = false; // If we have generics and no non-generics on the left and the right is not array-like ... if (!empty(generics($left)) && empty(nongenerics($left)) && !type_check($right, 'array')) { Log::err(Log::ETYPE, "array to {$right} comparison", $file, $node->lineno); } else { // and the same for the right side if (!empty(generics($right)) && empty(nongenerics($right)) && !type_check($left, 'array')) { Log::err(Log::ETYPE, "{$left} to array comparison", $file, $node->lineno); } } return 'bool'; break; // Add is special because you can add arrays // Add is special because you can add arrays case \ast\flags\BINARY_ADD: $temp = node_type($file, $namespace, $node->children[0], $current_scope, $current_class); if (!$temp) { $left = ''; } else { $left = type_map($temp); } $temp = node_type($file, $namespace, $node->children[1], $current_scope, $current_class); if (!$temp) { $right = ''; } else { $right = type_map($temp); } // fast-track common cases if ($left == 'int' && $right == 'int') { return 'int'; } if (($left == 'int' || $left == 'float') && ($right == 'int' || $right == 'float')) { return 'float'; } $left_is_array = !empty(generics($left)) && empty(nongenerics($left)); $right_is_array = !empty(generics($right)) && empty(nongenerics($right)); if ($left_is_array && !type_check($right, 'array')) { Log::err(Log::ETYPE, "invalid operator: left operand is array and right is not", $file, $node->lineno); return ''; } else { if ($right_is_array && !type_check($left, 'array')) { Log::err(Log::ETYPE, "invalid operator: right operand is array and left is not", $file, $node->lineno); return ''; } else { if ($left_is_array || $right_is_array) { // If it is a '+' and we know one side is an array and the other is unknown, assume array return 'array'; } } } return 'int|float'; $taint = false; break; // Everything else should be an int/float // Everything else should be an int/float default: $temp = node_type($file, $namespace, $node->children[0], $current_scope, $current_class); if (!$temp) { $left = ''; } else { $left = type_map($temp); } $temp = node_type($file, $namespace, $node->children[1], $current_scope, $current_class); if (!$temp) { $right = ''; } else { $right = type_map($temp); } if ($left == 'array' || $right == 'array') { Log::err(Log::ETYPE, "invalid array operator", $file, $node->lineno); return ''; } else { if ($left == 'int' && $right == 'int') { return 'int'; } else { if ($left == 'float' || $right == 'float') { return 'float'; } } } return 'int|float'; $taint = false; break; } } else { if ($node->kind == \ast\AST_CAST) { $taint = var_taint_check($file, $node->children[0], $current_scope); switch ($node->flags) { case \ast\flags\TYPE_NULL: return 'null'; break; case \ast\flags\TYPE_BOOL: $taint = false; return 'bool'; break; case \ast\flags\TYPE_LONG: $taint = false; return 'int'; break; case \ast\flags\TYPE_DOUBLE: $taint = false; return 'float'; break; case \ast\flags\TYPE_STRING: return 'string'; break; case \ast\flags\TYPE_ARRAY: return 'array'; break; case \ast\flags\TYPE_OBJECT: return 'object'; break; default: Log::err(Log::EFATAL, "Unknown type (" . $node->flags . ") in cast"); } } else { if ($node->kind == \ast\AST_NEW) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); if ($class_name) { return $classes[strtolower($class_name)]['type']; } return 'object'; } else { if ($node->kind == \ast\AST_DIM) { $taint = var_taint_check($file, $node->children[0], $current_scope); $type = node_type($file, $namespace, $node->children[0], $current_scope, $current_class); if (!empty($type)) { $gen = generics($type); if (empty($gen)) { if ($type !== 'null' && !type_check($type, 'string|ArrayAccess')) { // array offsets work on strings, unfortunately // Double check that any classes in the type don't have ArrayAccess $ok = false; foreach (explode('|', $type) as $t) { if (!empty($t) && !is_native_type($t)) { if (!empty($classes[strtolower($t)]['type'])) { if (strpos('|' . $classes[strtolower($t)]['type'] . '|', '|ArrayAccess|') !== false) { $ok = true; break; } } } } if (!$ok) { Log::err(Log::ETYPE, "Suspicious array access to {$type}", $file, $node->lineno); } } return ''; } } else { return ''; } return $gen; } else { if ($node->kind == \ast\AST_VAR) { return var_type($file, $node, $current_scope, $taint, $check_var_exists); } else { if ($node->kind == \ast\AST_ENCAPS_LIST) { foreach ($node->children as $encap) { if ($encap instanceof \ast\Node) { if (var_taint_check($file, $encap, $current_scope)) { $taint = true; } } } return "string"; } else { if ($node->kind == \ast\AST_CONST) { if ($node->children[0]->kind == \ast\AST_NAME) { if (defined($node->children[0]->children[0])) { return type_map(gettype(constant($node->children[0]->children[0]))); } else { // Todo: user-defined constant } } } else { if ($node->kind == \ast\AST_CLASS_CONST) { if ($node->children[1] == 'class') { return 'string'; } // class name fetch $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); if (!$class_name) { return ''; } $ltemp = strtolower($class_name); while ($ltemp && !array_key_exists($node->children[1], $classes[$ltemp]['constants'])) { $ltemp = strtolower($classes[$ltemp]['parent']); if (empty($classes[$ltemp])) { return ''; } // undeclared class - will be caught elsewhere } if (!$ltemp || !array_key_exists($node->children[1], $classes[$ltemp]['constants'])) { Log::err(Log::EUNDEF, "can't access undeclared constant {$class_name}::{$node->children[1]}", $file, $node->lineno); return ''; } return $classes[$ltemp]['constants'][$node->children[1]]['type']; } else { if ($node->kind == \ast\AST_PROP) { if ($node->children[0]->kind == \ast\AST_VAR) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); if ($class_name && !$node->children[1] instanceof \ast\Node) { $ltemp = find_property($file, $node, $class_name, $node->children[1], $class_name, false); if (empty($ltemp)) { return ''; } return $classes[$ltemp]['properties'][$node->children[1]]['type']; } } } else { if ($node->kind == \ast\AST_STATIC_PROP) { if ($node->children[0]->kind == \ast\AST_NAME) { $class_name = qualified_name($file, $node->children[0], $namespace); if ($class_name && !$node->children[1] instanceof \ast\Node) { $ltemp = find_property($file, $node, $class_name, $node->children[1], $class_name, false); if (empty($ltemp)) { return ''; } return $classes[$ltemp]['properties'][$node->children[1]]['type']; } } } else { if ($node->kind == \ast\AST_CALL) { if ($node->children[0]->kind == \ast\AST_NAME) { $func_name = $node->children[0]->children[0]; if ($node->children[0]->flags & \ast\flags\NAME_NOT_FQ) { $func = $namespace_map[T_FUNCTION][$file][strtolower($namespace . $func_name)] ?? $namespace_map[T_FUNCTION][$file][strtolower($func_name)] ?? $functions[strtolower($namespace . $func_name)] ?? $functions[strtolower($func_name)] ?? null; } else { $func = $functions[strtolower($func_name)] ?? null; } if ($func['file'] == 'internal' && empty($func['ret'])) { if (!empty($internal_arginfo[$func_name])) { return $internal_arginfo[$func_name][0] ?? ''; } } else { return $func['ret'] ?? ''; } } else { // TODO: Handle $func() and other cases that get here } } else { if ($node->kind == \ast\AST_STATIC_CALL) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); $method = find_method($class_name, $node->children[1]); if ($method) { return $method['ret'] ?? ''; } } else { if ($node->kind == \ast\AST_METHOD_CALL) { $class_name = find_class_name($file, $node, $namespace, $current_class, $current_scope); if ($class_name) { $method_name = $node->children[1]; $method = find_method($class_name, $method_name); if ($method === false) { Log::err(Log::EUNDEF, "call to undeclared method {$class_name}->{$method_name}()", $file, $node->lineno); } else { if ($method != 'dynamic') { return $method['ret']; } } } } } } } } } } } } } } } } } } return ''; }
die('Forbidden'); } isset($argv) && isset($argv[1]) && ($argv[1] == '-q' || $argv[1] == '--quiet') && ($quiet = true) or $quiet = false; Log::info(sprintf('pull.php: verbosity %s', $quiet ? ' disabled' : 'enabled')); !$quiet && (print "=== Update process started ===\r\n"); Log::info('pull.php: update process started '); $h = Habrometr_Model::getInstance(); $list = $h->getUserList(); $users = $list['list']; $errorCounter = 0; foreach ($users as $key => $user) { try { $h->pullValues($user); system('rm -f ' . __DIR__ . '/image_cache/habrometr_*_' . escapeshellcmd($user['user_code']) . '.png'); $errorCounter = 0; Log::debug(sprintf('pull.php: user [%s] %s updated', $key, $user['user_code'])); } catch (Exception $e) { $errorCounter++; !$quiet && (print "Error updating user [{$key}] {$user['user_code']}"); Log::err(sprintf('pull.php: error updating user [%s] %s)', $key, $user['user_code'])); if ($errorCounter > 20) { Log::crit('pull.php: consecutive errors counter exceed 20 - break update process)'); break; } } !$quiet && (print "." . (($key + 1) % 50 == 0 ? "\r\n" : '')); } $updated = $key + 1; !$quiet && (print "\r\nUsers updated: {$updated}\r\n"); !$quiet && (print "=== Update process finished ===\r\n"); Log::info(sprintf('pull.php: update process finished (users updated: %d) ', $updated));
function dump_gv($node) { global $classes; $root = []; $interfaces = []; $traits = []; $namespaces = []; $all = []; if ($node) { if (empty($classes[strtolower($node)])) { Log::err(Log::EFATAL, "{$node} not found"); } $nodes = []; $nodes = walk_up($nodes, $node); $nodes = walk_down($nodes, $node); foreach ($nodes as $cn) { $all[] = $classes[strtolower($cn)]; } } else { $all = $classes; } foreach ($all as $key => $entry) { $ns = empty($entry['namespace']) ? '' : $entry['namespace']; // Classify the entries first so we can colour them appropriately later if ($entry['flags'] & \ast\flags\CLASS_INTERFACE) { $interfaces[$ns][$key] = $entry['name']; $namespaces[$ns] = true; } else { if ($entry['flags'] & \ast\flags\CLASS_TRAIT) { $traits[$ns][$key] = $entry['name']; $namespaces[$ns] = true; } else { if (empty($entry['parent'])) { $root[$ns][$key] = $entry['name']; $namespaces[$ns] = true; } else { $nodes[$ns][$key] = $entry['name']; $namespaces[$ns] = true; } } } // Then work out the connections foreach ($entry['interfaces'] as $v) { if (empty($classes[strtolower($v)])) { continue; } $fe = $classes[strtolower($v)]; if ($entry['file'] != 'internal' || $fe['file'] != 'internal') { $conns[$fe['namespace']][$fe['name']][] = $entry['name']; $seen[$fe['name']] = true; $seen[$entry['name']] = true; } } foreach ($entry['traits'] as $v) { if (empty($classes[strtolower($v)])) { continue; } $fe = $classes[strtolower($v)]; if ($entry['file'] != 'internal' || $fe['file'] != 'internal') { $conns[$fe['namespace']][$fe['name']][] = $entry['name']; $seen[$fe['name']] = true; $seen[$entry['name']] = true; } } if (!empty($entry['parent'])) { if (empty($classes[strtolower($entry['parent'])])) { continue; } $fe = $classes[strtolower($entry['parent'])]; if ($entry['file'] != 'internal' || $fe['file'] != 'internal') { $conns[$fe['namespace']][$fe['name']][] = $entry['name']; $seen[$fe['name']] = true; $seen[$entry['name']] = true; } } } // Now get rid of anything internal that doesn't have a direct connection to something in user-space $temp = $interfaces; foreach ($temp as $ns => $vv) { foreach ($vv as $k => $vv) { $entry = $classes[strtolower($vv)]; if ($entry['file'] == 'internal' && empty($seen[$vv])) { unset($interfaces[$ns][$k]); } } } $temp = $traits; foreach ($temp as $ns => $vv) { foreach ($vv as $k => $vv) { $entry = $classes[strtolower($vv)]; if ($entry['file'] == 'internal' && empty($seen[$vv])) { unset($traits[$ns][$k]); } } } $temp = $root; foreach ($temp as $ns => $vv) { foreach ($vv as $k => $vv) { $entry = $classes[strtolower($vv)]; if ($entry['file'] == 'internal' && empty($seen[$vv])) { unset($root[$ns][$k]); } } } echo "digraph class_graph {\n\tgraph [ overlap=false, fontsize=6, size=\"80,60\"]\n\tnode [ shape=box, style=filled, color=SandyBrown, fontcolor=Black, fontname=Utopia]\n\n"; foreach (array_keys($namespaces) as $i => $ns) { if ($ns != '') { // Each namespace is a subgraph echo "subgraph cluster_{$i} {\n"; echo "label=\"" . trim(str_replace('\\', '\\\\', $ns), '\\') . "\";\n"; echo "style=filled;\n"; echo "color=lightgrey;\n"; } if (!empty($interfaces[$ns])) { foreach ($interfaces[$ns] as $v) { echo $v === $node ? gv($v, "shape=doubleoctagon, color=Gold") : gv($v); } } echo "\n"; echo "node [ shape=box, color=YellowGreen, fontcolor=Black, fontname=Utopia]\n"; if (!empty($traits[$ns])) { foreach ($traits[$ns] as $v) { echo $v === $node ? gv($v, "shape=doubleoctagon, color=Gold") : gv($v); } } echo "\n"; echo "node [ shape=box, color=Wheat, fontcolor=Black, fontname=\"Utopia-Bold\"]\n"; if (!empty($root[$ns])) { foreach ($root[$ns] as $v) { echo $v === $node ? gv($v, "shape=doubleoctagon, color=Gold") : gv($v); } } echo "\n"; echo "node [ shape=box, color=Wheat, fontcolor=Black, fontname=Utopia]\n"; if (!empty($nodes[$ns])) { foreach ($nodes[$ns] as $key => $v) { echo $v === $node ? gv($v, "shape=doubleoctagon, color=Gold") : gv($v); } } echo "\n"; if (!empty($conns[$ns])) { foreach ($conns[$ns] as $key => $nns) { foreach ($nns as $n) { if ($classes[strtolower($key)]['flags'] & \ast\flags\CLASS_INTERFACE) { $style = 'dotted'; } else { if ($classes[strtolower($key)]['flags'] & \ast\flags\CLASS_TRAIT) { $style = 'dashed'; } else { $style = 'solid'; } } echo gvline($key, $n, $style); } } } if ($ns != '') { echo "}\n"; } } echo "}\n"; }
$fileName = "./lib/Habrometr/Informer/{$width}x{$height}.php"; if (file_exists($fileName)) { require_once $fileName; } else { Habrometr_Informer::showError("Informer of size {$width}x{$height} is not exists", $width, $height); } $informer = new $className($user); /* @var $informer Habrometr_Informer */ // Is user's habrometr cached? if ($informer->existsInCache()) { Log::info(sprintf('informer.php: informer `%s` loaded from cache', $className)); $informer->printFromCache(); exit; } if (!$informer->prepare()) { Log::err('Informer preparing failed'); throw new Exception('Informer preparing failed'); } if (!$informer->build()) { Log::err('Informer building failed'); throw new Exception('Informer building failed'); } $informer->printCanvas(); try { $informer->saveToCache(); } catch (Exception $e) { Log::warn(sprintf('informer.php: exception thrown while trying to save informer to cache: `%s`', $e->getMessage())); } $informer->destroyCanvas(); $timeFull = microtime(true) - $timeStart; Log::info(sprintf('informer.php: informer `%s` created, generated in %f seconds', $className, $timeFull));
public function getSourceUserdb($source) { $userdbs = array(); $sourceName = $source->getName(); foreach ($this->tReadUserdbs as $userdb) { foreach ($userdb->getSourceNames() as $userdbSourceName) { if ($sourceName == $userdbSourceName) { $userdbs[] = $userdb; break; } } } $userdbCount = count($userdbs); if ($userdbCount == 0) { $userdbs[] = new MonitorUserdb(Userdb::TYPE_NONE); } elseif ($userdbCount > 1) { throw new Exception(Log::err("Unexpected number ({$userdbCount}) of user db references to {$source}")); } $userdb = $userdbs[0]; return Userdb::create($userdb->getType(), $userdb->getProperties()); }
public function read($xml) { Log::debug("Reading monitor configuration from file '{$xml}'..."); $this->resetParser(); $xmlData = file_get_contents($xml); if ($xmlData === false) { throw new Exception(Log::err("Failed to read file '{$xml}'")); } $readSucceeded = xml_parse($this->tParser, $xmlData, true) == 1 && count($this->tParseErrors) == 0; if (!$readSucceeded) { Log::err("Failed to parse file '{$xml}'"); $errorCode = xml_get_error_code($this->tParser); if ($errorCode != XML_ERROR_NONE) { $error = xml_error_string($errorCode); Log::err(" {$error}"); } foreach ($this->tParseErrors as $error) { Log::err(" {$error}"); } } return $readSucceeded; }
function node_paramlist($file, $node, &$req, &$opt, $dc) { if ($node instanceof \ast\Node) { $result = []; $i = 0; foreach ($node->children as $param_node) { $result[] = node_param($file, $param_node, $dc, $i); if ($param_node->children[2] === null) { if ($opt) { Log::err(Log::EPARAM, "required arg follows optional", $file, $node->lineno); } $req++; } else { $opt++; } $i++; } return $result; } assert(false, ast_dump($node) . " was not an \\ast\\Node"); }
/** * Save new user Habravalues to database * * @param $userId * @param $values * @throws Exception */ public function pushValues($userId, $values) { $values = array('user_id' => $userId, 'karma_value' => (double) $values['karma']['value'], 'habraforce' => (double) $values['habraforce']['value'], 'rate_position' => (int) $values['rate']['value']); try { $sth = $this->_pdo->prepare("INSERT `karmalog` (user_id, karma_value, habraforce, rate_position) VALUES (:uid, :k, :hf, :r)"); /* @var PDOStatement $sth */ $sth->bindValue(':uid', $values['user_id']); $sth->bindValue(':k', $values['karma_value']); $sth->bindValue(':hf', $values['habraforce']); $sth->bindValue(':r', $values['rate_position']); if (!$sth->execute()) { throw new Exception('Update values — DB query failed: ' . $this->_pdo->errorInfo(), $this->_pdo->errorCode()); } } catch (Exception $e) { $message = "Saving data — DB query failed: {$e->getMessage()}"; Log::err($message); throw new Exception($message, 202); } Log::debug(sprintf("Habrometr_Model: values updated in database for User ID `%d`", $userId)); }
/** * A failure occurred. * * @param PHPUnit_Framework_Test $test * @param PHPUnit_Framework_AssertionFailedError $e * @param float $time */ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) { $this->log->err(sprintf('Test "%s" failed: %s', $test->getName(), $e->getMessage())); }
/** * @inheritdoc */ public function lock($key, $iteration = 15) { $i = 0; while (!$this->add($this->prepareKey($key, self::LOCK_PREFIX), 1, $this->lockExpire)) { $i++; if ($i > $iteration) { if (class_exists('\\rock\\log\\Log')) { $message = BaseException::convertExceptionToString(new CacheException(CacheException::INVALID_SAVE, ['key' => $key])); Log::err($message); } return false; } usleep(rand(10, 1000)); } return true; }
function node_func($file, $conditional, $node, $current_scope, $current_class, $namespace = '') { global $scope, $classes; if ($node instanceof \ast\Node) { $req = $opt = 0; $dc = ['return' => '', 'params' => []]; if (!empty($node->docComment)) { $dc = parse_doc_comment($node->docComment); } $result = ['file' => $file, 'namespace' => $namespace, 'scope' => $current_scope, 'conditional' => $conditional, 'flags' => $node->flags, 'lineno' => $node->lineno, 'endLineno' => $node->endLineno, 'name' => strpos($current_scope, '::') === false ? $namespace . $node->name : $node->name, 'docComment' => $node->docComment, 'params' => node_paramlist($file, $node->children[0], $req, $opt, $dc, $namespace), 'required' => $req, 'optional' => $opt, 'ret' => '', 'oret' => '', 'ast' => $node->children[2]]; if (!empty($dc['deprecated'])) { $result['deprecated'] = true; } if ($node->children[3] !== null) { $result['oret'] = ast_node_type($file, $node->children[3], $namespace); // Original return type $result['ret'] = ast_node_type($file, $node->children[3], $namespace); // This one changes as we walk the tree } else { // Check if the docComment has a return value specified if (!empty($dc['return'])) { // We can't actually figure out 'static' at this point, but fill it in regardless. It will be partially correct if ($dc['return'] == 'static' || $dc['return'] == 'self' || $dc['return'] == '$this') { if (strpos($current_scope, '::') !== false) { list($dc['return'], ) = explode('::', $current_scope); } } $result['oret'] = $dc['return']; $result['ret'] = $dc['return']; } } // Add params to local scope for user functions if ($file != 'internal') { $i = 1; foreach ($result['params'] as $k => $v) { if (empty($v['type'])) { // If there is no type specified in PHP, check for a docComment // We assume order in the docComment matches the parameter order in the code if (!empty($dc['params'][$k]['type'])) { $scope[$current_scope]['vars'][$v['name']] = ['type' => $dc['params'][$k]['type'], 'tainted' => false, 'tainted_by' => '', 'param' => $i]; } else { $scope[$current_scope]['vars'][$v['name']] = ['type' => '', 'tainted' => false, 'tainted_by' => '', 'param' => $i]; } } else { $scope[$current_scope]['vars'][$v['name']] = ['type' => $v['type'], 'tainted' => false, 'tainted_by' => '', 'param' => $i]; } if (array_key_exists('def', $v)) { $type = node_type($file, $namespace, $v['def'], $current_scope, empty($current_class) ? null : $classes[strtolower($current_class)]); if ($scope[$current_scope]['vars'][$v['name']]['type'] !== '') { // Does the default value match the declared type? if ($type !== 'null' && !type_check($type, $scope[$current_scope]['vars'][$v['name']]['type'])) { Log::err(Log::ETYPE, "Default value for {$scope[$current_scope]['vars'][$v['name']]['type']} \${$v['name']} can't be {$type}", $file, $node->lineno); } } add_type($current_scope, $v['name'], strtolower($type)); // If we have no other type info about a parameter, just because it has a default value of null // doesn't mean that is its type. Any type can default to null if ($type === 'null' && !empty($result['params'][$k]['type'])) { $result['params'][$k]['type'] = merge_type($result['params'][$k]['type'], strtolower($type)); } } $i++; } if (!empty($dc['vars'])) { foreach ($dc['vars'] as $var) { if (empty($scope[$current_scope]['vars'][$var['name']])) { $scope[$current_scope]['vars'][$var['name']] = ['type' => $var['type'], 'tainted' => false, 'tainted_by' => '']; } else { add_type($current_scope, $var['name'], $var['type']); } } } } return $result; } assert(false, "{$node} was not an \\ast\\Node"); }
CheckConfig::extensions($requiredExtensions); mb_internal_encoding("UTF-8"); Options::setDebug(DEBUG || array_search("--debug", $argv)); Options::setPretend(array_search("--pretend", $argv)); Options::setVerbose(Options::debug() || Options::pretend() || array_search("--verbose", $argv)); Log::open(__FILE__, true, Options::verbose(), Options::debug()); Log::notice(sprintf("Running '%s'...", implode(" ", $argv))); $monitor = Monitor::create(dirname(__FILE__) . "/monitor"); if ($monitor !== false) { $sources = $monitor->getEnabledSources(); $dbh = new DBH(DBDSN, DBUSER, DBPASS); $processor = new Processor($dbh); foreach ($sources as $source) { $processor->process($monitor, $source); } $processor->discard(EVENT_DISCARD_THRESHOLD); $status = 0; } else { $status = 1; } } catch (Exception $e) { Log::err(sprintf("Log file processing failed with exception: %s\nDetails: %s", $e->getMessage(), $e)); $status = 1; } if (isset($dbh)) { $dbh->close(); } $elapsed = round(microtime(true) - $elapsed, 3); Log::notice(sprintf("Log file processing finished with status '%d' (Total processing time: %f s)", $status, $elapsed)); Log::close(); exit($status);
function check_functions($functions) { foreach ($functions as $name => $func) { if (strpos($name, ':') !== false) { list(, $func_name) = explode(':', $name, 2); $orig = $functions[strtolower($func_name)]; if ($orig['file'] == 'internal') { if ($func['conditional'] == true) { continue; } Log::err(Log::EREDEF, "Function {$func_name} defined at {$func['file']}:{$func['lineno']} was previously defined internally", $func['file'], $func['lineno']); } else { Log::err(Log::EREDEF, "Function {$func_name} defined at {$func['file']}:{$func['lineno']} was previously defined at {$orig['file']}:{$orig['lineno']}", $func['file'], $func['lineno']); } } } }
break; } } foreach ($opts as $opt => $value) { foreach ($argv as $key => $chunk) { $regex = '/^' . (isset($opt[1]) ? '--' : '-') . $opt . '/'; if ($chunk == $value && $argv[$key - 1][0] == '-' || preg_match($regex, $chunk)) { array_push($pruneargv, $key); } } } while ($key = array_pop($pruneargv)) { unset($argv[$key]); } if (empty($files) && count($argv) < 2) { Log::err(Log::EFATAL, "No files to analyze"); } foreach ($argv as $arg) { if ($arg[0] == '-') { usage("Unknown option '{$arg}'"); } } $files = array_merge($files, array_slice($argv, 1)); function usage($msg = '') { global $argv; if (!empty($msg)) { echo "{$msg}\n"; } echo <<<EOB Usage: {$argv[0]} [options] [files...]