aboutsummaryrefslogtreecommitdiff
path: root/srcs/phpmyadmin/libraries/classes/ErrorReport.php
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-01-09 10:55:03 +0100
committerCharles <sircharlesaze@gmail.com>2020-01-09 13:09:38 +0100
commit04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa (patch)
tree5c691241355c943a3c68ddb06b8cf8c60aa11319 /srcs/phpmyadmin/libraries/classes/ErrorReport.php
parent7e0d85db834d6351ed85d01e5126ac31dc510b86 (diff)
downloadft_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.php294
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);
+ }
+}