Example #1
0
 /**
  * Displays a MySQL error message in the main panel when $exit is true.
  * Returns the error message otherwise.
  *
  * @param string|bool $server_msg     Server's error message.
  * @param string      $sql_query      The SQL query that failed.
  * @param bool        $is_modify_link Whether to show a "modify" link or not.
  * @param string      $back_url       URL for the "back" link (full path is
  *                                    not required).
  * @param bool        $exit           Whether execution should be stopped or
  *                                    the error message should be returned.
  *
  * @return string
  *
  * @global string $table The current table.
  * @global string $db    The current database.
  *
  * @access public
  */
 public static function mysqlDie($server_msg = '', $sql_query = '', $is_modify_link = true, $back_url = '', $exit = true)
 {
     global $table, $db;
     /**
      * Error message to be built.
      * @var string $error_msg
      */
     $error_msg = '';
     // Checking for any server errors.
     if (empty($server_msg)) {
         $server_msg = $GLOBALS['dbi']->getError();
     }
     // Finding the query that failed, if not specified.
     if (empty($sql_query) && !empty($GLOBALS['sql_query'])) {
         $sql_query = $GLOBALS['sql_query'];
     }
     $sql_query = trim($sql_query);
     $errors = array();
     if (!empty($sql_query)) {
         /**
          * The lexer used for analysis.
          * @var SqlParser\Lexer $lexer
          */
         $lexer = new SqlParser\Lexer($sql_query);
         /**
          * The parser used for analysis.
          * @var SqlParser\Parser $parser
          */
         $parser = new SqlParser\Parser($lexer->list);
         /**
          * The errors found by the lexer and the parser.
          * @var array $errors
          */
         $errors = SqlParser\Utils\Error::get(array($lexer, $parser));
     }
     if (empty($sql_query)) {
         $formatted_sql = '';
     } elseif (count($errors)) {
         $formatted_sql = htmlspecialchars($sql_query);
     } else {
         $formatted_sql = self::formatSql($sql_query, true);
     }
     $error_msg .= '<div class="error"><h1>' . __('Error') . '</h1>';
     // For security reasons, if the MySQL refuses the connection, the query
     // is hidden so no details are revealed.
     if (!empty($sql_query) && !mb_strstr($sql_query, 'connect')) {
         // Static analysis errors.
         if (!empty($errors)) {
             $error_msg .= '<p><strong>' . __('Static analysis:') . '</strong></p>';
             $error_msg .= '<p>' . sprintf(__('%d errors were found during analysis.'), count($errors)) . '</p>';
             $error_msg .= '<p><ol>';
             $error_msg .= implode(SqlParser\Utils\Error::format($errors, '<li>%2$s (near "%4$s" at position %5$d)</li>'));
             $error_msg .= '</ol></p>';
         }
         // Display the SQL query and link to MySQL documentation.
         $error_msg .= '<p><strong>' . __('SQL query:') . '</strong>' . "\n";
         $formattedSqlToLower = mb_strtolower($formatted_sql);
         // TODO: Show documentation for all statement types.
         if (mb_strstr($formattedSqlToLower, 'select')) {
             // please show me help to the error on select
             $error_msg .= self::showMySQLDocu('SELECT');
         }
         if ($is_modify_link) {
             $_url_params = array('sql_query' => $sql_query, 'show_query' => 1);
             if (mb_strlen($table)) {
                 $_url_params['db'] = $db;
                 $_url_params['table'] = $table;
                 $doedit_goto = '<a href="tbl_sql.php' . PMA_URL_getCommon($_url_params) . '">';
             } elseif (mb_strlen($db)) {
                 $_url_params['db'] = $db;
                 $doedit_goto = '<a href="db_sql.php' . PMA_URL_getCommon($_url_params) . '">';
             } else {
                 $doedit_goto = '<a href="server_sql.php' . PMA_URL_getCommon($_url_params) . '">';
             }
             $error_msg .= $doedit_goto . self::getIcon('b_edit.png', __('Edit')) . '</a>';
         }
         $error_msg .= '    </p>' . "\n" . '<p>' . "\n" . $formatted_sql . "\n" . '</p>' . "\n";
     }
     // Display server's error.
     if (!empty($server_msg)) {
         $server_msg = preg_replace("@((\r\n)|(\r)|(\n)){3,}@", "\n\n", $server_msg);
         // Adds a link to MySQL documentation.
         $error_msg .= '<p>' . "\n" . '    <strong>' . __('MySQL said: ') . '</strong>' . self::showMySQLDocu('Error-messages-server') . "\n" . '</p>' . "\n";
         // The error message will be displayed within a CODE segment.
         // To preserve original formatting, but allow word-wrapping,
         // a couple of replacements are done.
         // All non-single blanks and  TAB-characters are replaced with their
         // HTML-counterpart
         $server_msg = str_replace(array('  ', "\t"), array('&nbsp;&nbsp;', '&nbsp;&nbsp;&nbsp;&nbsp;'), $server_msg);
         // Replace line breaks
         $server_msg = nl2br($server_msg);
         $error_msg .= '<code>' . $server_msg . '</code><br/>';
     }
     $error_msg .= '</div>';
     $_SESSION['Import_message']['message'] = $error_msg;
     if (!$exit) {
         return $error_msg;
     }
     /**
      * If this is an AJAX request, there is no "Back" link and
      * `PMA_Response()` is used to send the response.
      */
     if (!empty($GLOBALS['is_ajax_request'])) {
         $response = PMA_Response::getInstance();
         $response->isSuccess(false);
         $response->addJSON('message', $error_msg);
         exit;
     }
     if (!empty($back_url)) {
         if (mb_strstr($back_url, '?')) {
             $back_url .= '&amp;no_history=true';
         } else {
             $back_url .= '?no_history=true';
         }
         $_SESSION['Import_message']['go_back_url'] = $back_url;
         $error_msg .= '<fieldset class="tblFooters">' . '[ <a href="' . $back_url . '">' . __('Back') . '</a> ]' . '</fieldset>' . "\n\n";
     }
     exit($error_msg);
 }
Example #2
0
 /**
  * Runs the linting process.
  *
  * @param string $query The query to be checked.
  *
  * @return array
  */
 public static function lint($query)
 {
     // Disabling lint for huge queries to save some resources.
     if (mb_strlen($query) > 10000) {
         return array(array('message' => __('Linting is disabled for this query because it exceeds the ' . 'maximum length.'), 'fromLine' => 0, 'fromColumn' => 0, 'toLine' => 0, 'toColumn' => 0, 'severity' => 'warning'));
     }
     /**
      * Lexer used for tokenizing the query.
      *
      * @var SqlParser\Lexer
      */
     $lexer = new SqlParser\Lexer($query);
     /**
      * Parsed used for analysing the query.
      *
      * @var SqlParser\Parser
      */
     $parser = new SqlParser\Parser($lexer->list);
     /**
      * Array containing all errors.
      *
      * @var array
      */
     $errors = SqlParser\Utils\Error::get(array($lexer, $parser));
     /**
      * The response containing of all errors.
      *
      * @var array
      */
     $response = array();
     /**
      * The starting position for each line.
      *
      * CodeMirror requires relative position to line, but the parser stores
      * only the absolute position of the character in string.
      *
      * @var array
      */
     $lines = static::getLines($query);
     // Building the response.
     foreach ($errors as $idx => $error) {
         // Starting position of the string that caused the error.
         list($fromLine, $fromColumn) = static::findLineNumberAndColumn($lines, $error[3]);
         // Ending position of the string that caused the error.
         list($toLine, $toColumn) = static::findLineNumberAndColumn($lines, $error[3] + mb_strlen($error[2]));
         // Building the response.
         $response[] = array('message' => sprintf(__('%1$s (near <code>%2$s</code>)'), $error[0], $error[2]), 'fromLine' => $fromLine, 'fromColumn' => $fromColumn, 'toLine' => $toLine, 'toColumn' => $toColumn, 'severity' => 'error');
     }
     // Sending back the answer.
     return $response;
 }