diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-01-09 10:55:03 +0100 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-01-09 13:09:38 +0100 |
| commit | 04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa (patch) | |
| tree | 5c691241355c943a3c68ddb06b8cf8c60aa11319 /srcs/phpmyadmin/libraries/classes/ErrorReport.php | |
| parent | 7e0d85db834d6351ed85d01e5126ac31dc510b86 (diff) | |
| download | ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.gz ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.bz2 ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.zip | |
phpmyadmin working
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/ErrorReport.php')
| -rw-r--r-- | srcs/phpmyadmin/libraries/classes/ErrorReport.php | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/ErrorReport.php b/srcs/phpmyadmin/libraries/classes/ErrorReport.php new file mode 100644 index 0000000..b7044f2 --- /dev/null +++ b/srcs/phpmyadmin/libraries/classes/ErrorReport.php @@ -0,0 +1,294 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Holds the PhpMyAdmin\ErrorReport class + * + * @package PhpMyAdmin + */ +declare(strict_types=1); + +namespace PhpMyAdmin; + +use PhpMyAdmin\Error; +use PhpMyAdmin\Utils\HttpRequest; + +/** + * Error reporting functions used to generate and submit error reports + * + * @package PhpMyAdmin + */ +class ErrorReport +{ + /** + * The URL where to submit reports to + * + * @var string + */ + private $submissionUrl = 'https://reports.phpmyadmin.net/incidents/create'; + + /** + * @var HttpRequest + */ + private $httpRequest; + + /** + * @var Relation + */ + private $relation; + + /** + * @var Template + */ + public $template; + + /** + * Constructor + * + * @param HttpRequest $httpRequest HttpRequest instance + * @param Relation $relation Relation instance + * @param Template $template Template instance + */ + public function __construct(HttpRequest $httpRequest, Relation $relation, Template $template) + { + $this->httpRequest = $httpRequest; + $this->relation = $relation; + $this->template = $template; + } + + /** + * Set the URL where to submit reports to + * + * @param string $submissionUrl Submission URL + * @return void + */ + public function setSubmissionUrl(string $submissionUrl): void + { + $this->submissionUrl = $submissionUrl; + } + + /** + * Returns the pretty printed error report data collected from the + * current configuration or from the request parameters sent by the + * error reporting js code. + * + * @return string the report + */ + private function getPrettyData(): string + { + $report = $this->getData(); + + return json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + } + + /** + * Returns the error report data collected from the current configuration or + * from the request parameters sent by the error reporting js code. + * + * @param string $exceptionType whether exception is 'js' or 'php' + * + * @return array error report if success, Empty Array otherwise + */ + public function getData(string $exceptionType = 'js'): array + { + /** @var Config $PMA_Config */ + global $PMA_Config; + + $relParams = $this->relation->getRelationsParam(); + // common params for both, php & js exceptions + $report = [ + "pma_version" => PMA_VERSION, + "browser_name" => PMA_USR_BROWSER_AGENT, + "browser_version" => PMA_USR_BROWSER_VER, + "user_os" => PMA_USR_OS, + "server_software" => $_SERVER['SERVER_SOFTWARE'], + "user_agent_string" => $_SERVER['HTTP_USER_AGENT'], + "locale" => $PMA_Config->getCookie('pma_lang'), + "configuration_storage" => + $relParams['db'] === null ? "disabled" : "enabled", + "php_version" => PHP_VERSION, + ]; + + if ($exceptionType == 'js') { + if (empty($_POST['exception'])) { + return []; + } + $exception = $_POST['exception']; + $exception["stack"] = $this->translateStacktrace($exception["stack"]); + + if (isset($exception["url"])) { + list($uri, $scriptName) = $this->sanitizeUrl($exception["url"]); + $exception["uri"] = $uri; + $report["script_name"] = $scriptName; + unset($exception["url"]); + } elseif (isset($_POST["url"])) { + list($uri, $scriptName) = $this->sanitizeUrl($_POST["url"]); + $exception["uri"] = $uri; + $report["script_name"] = $scriptName; + unset($_POST["url"]); + } else { + $report["script_name"] = null; + } + + $report["exception_type"] = 'js'; + $report["exception"] = $exception; + if (isset($_POST['microhistory'])) { + $report["microhistory"] = $_POST['microhistory']; + } + + if (! empty($_POST['description'])) { + $report['steps'] = $_POST['description']; + } + } elseif ($exceptionType == 'php') { + $errors = []; + // create php error report + $i = 0; + if (! isset($_SESSION['prev_errors']) + || $_SESSION['prev_errors'] == '' + ) { + return []; + } + foreach ($_SESSION['prev_errors'] as $errorObj) { + /** @var Error $errorObj */ + if ($errorObj->getLine() + && $errorObj->getType() + && $errorObj->getNumber() != E_USER_WARNING + ) { + $errors[$i++] = [ + "lineNum" => $errorObj->getLine(), + "file" => $errorObj->getFile(), + "type" => $errorObj->getType(), + "msg" => $errorObj->getOnlyMessage(), + "stackTrace" => $errorObj->getBacktrace(5), + "stackhash" => $errorObj->getHash(), + ]; + } + } + + // if there were no 'actual' errors to be submitted. + if ($i == 0) { + return []; // then return empty array + } + $report["exception_type"] = 'php'; + $report["errors"] = $errors; + } else { + return []; + } + + return $report; + } + + /** + * Sanitize a url to remove the identifiable host name and extract the + * current script name from the url fragment + * + * It returns two things in an array. The first is the uri without the + * hostname and identifying query params. The second is the name of the + * php script in the url + * + * @param string $url the url to sanitize + * + * @return array the uri and script name + */ + private function sanitizeUrl(string $url): array + { + $components = parse_url($url); + if (isset($components["fragment"]) + && preg_match("<PMAURL-\d+:>", $components["fragment"], $matches) + ) { + $uri = str_replace($matches[0], "", $components["fragment"]); + $url = "https://example.com/" . $uri; + $components = parse_url($url); + } + + // get script name + preg_match("<([a-zA-Z\-_\d\.]*\.php|js\/[a-zA-Z\-_\d\/\.]*\.js)$>", $components["path"], $matches); + if (count($matches) < 2) { + $scriptName = 'index.php'; + } else { + $scriptName = $matches[1]; + } + + // remove deployment specific details to make uri more generic + if (isset($components["query"])) { + parse_str($components["query"], $queryArray); + unset($queryArray["db"]); + unset($queryArray["table"]); + unset($queryArray["token"]); + unset($queryArray["server"]); + $query = http_build_query($queryArray); + } else { + $query = ''; + } + + $uri = $scriptName . "?" . $query; + return [ + $uri, + $scriptName, + ]; + } + + /** + * Sends report data to the error reporting server + * + * @param array $report the report info to be sent + * + * @return string|null|bool the reply of the server + */ + public function send(array $report) + { + return $this->httpRequest->create( + $this->submissionUrl, + "POST", + false, + json_encode($report), + "Content-Type: application/json" + ); + } + + /** + * Translates the cumulative line numbers in the stack trace as well as sanitize + * urls and trim long lines in the context + * + * @param array $stack the stack trace + * + * @return array the modified stack trace + */ + private function translateStacktrace(array $stack): array + { + foreach ($stack as &$level) { + foreach ($level["context"] as &$line) { + if (mb_strlen($line) > 80) { + $line = mb_substr($line, 0, 75) . "//..."; + } + } + list($uri, $scriptName) = $this->sanitizeUrl($level["url"]); + $level["uri"] = $uri; + $level["scriptname"] = $scriptName; + unset($level["url"]); + } + unset($level); + return $stack; + } + + /** + * Generates the error report form to collect user description and preview the + * report before being sent + * + * @return string the form + */ + public function getForm(): string + { + $datas = [ + 'report_data' => $this->getPrettyData(), + 'hidden_inputs' => Url::getHiddenInputs(), + 'hidden_fields' => null, + ]; + + $reportData = $this->getData(); + if (! empty($reportData)) { + $datas['hidden_fields'] = Url::getHiddenFields($reportData, '', true); + } + + return $this->template->render('error/report_form', $datas); + } +} |
