/** * Does the actual work of each specific transformations plugin. * * @param string $buffer text to be transformed * @param array $options transformation options * @param string $meta meta information * * @return string */ public function applyTransformation($buffer, $options = array(), $meta = '') { $url = (isset($options[0]) ? $options[0] : '') . (isset($options[2]) && $options[2] ? '' : $buffer); /* Do not allow javascript links */ if (!Sanitize::checkLink($url, true, true)) { return htmlspecialchars($url); } return '<a href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars(isset($options[1]) ? $options[1] : '') . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars(isset($options[1]) ? $options[1] : $buffer) . '</a>'; }
/** * Does the actual work of each specific transformations plugin. * * @param string $buffer text to be transformed * @param array $options transformation options * @param string $meta meta information * * @return string */ public function applyTransformation($buffer, $options = array(), $meta = '') { $url = (isset($options[0]) ? $options[0] : '') . $buffer; /* Do not allow javascript links */ if (!Sanitize::checkLink($url, true, true)) { return htmlspecialchars($url); } return '<a href="' . htmlspecialchars($url) . '" rel="noopener noreferrer" target="_blank"><img src="' . htmlspecialchars($url) . '" border="0" width="' . (isset($options[1]) ? intval($options[1]) : 100) . '" height="' . (isset($options[2]) ? intval($options[2]) : 50) . '" />' . htmlspecialchars($buffer) . '</a>'; }
/** * Returns sanitized language string, taking into account our special codes * for formatting. Takes variable number of arguments. * Based on Sanitize::sanitize from sanitize.lib.php. * * @param string $lang_key key in $GLOBALS WITHOUT 'strSetup' prefix * * @return string */ function PMA_lang($lang_key) { $message = isset($GLOBALS["strConfig{$lang_key}"]) ? $GLOBALS["strConfig{$lang_key}"] : $lang_key; $message = Sanitize::sanitize($message); if (func_num_args() == 1) { return $message; } else { $args = func_get_args(); array_shift($args); return vsprintf($message, $args); } }
/** * Returns error message for failed authentication. * * @return string */ public function getErrorMessage() { if (!empty($GLOBALS['login_without_password_is_forbidden'])) { return __('Login without a password is forbidden by configuration' . ' (see AllowNoPassword)'); } elseif (!empty($GLOBALS['allowDeny_forbidden'])) { return __('Access denied!'); } elseif (!empty($GLOBALS['no_activity'])) { return sprintf(__('No activity within %s seconds; please log in again.'), $GLOBALS['cfg']['LoginCookieValidity']); } else { $dbi_error = $GLOBALS['dbi']->getError(); if (!empty($dbi_error)) { return Sanitize::sanitize($dbi_error); } elseif (isset($GLOBALS['errno'])) { return '#' . $GLOBALS['errno'] . ' ' . __('Cannot log in to the MySQL server'); } else { return __('Cannot log in to the MySQL server'); } } }
/** * Create the code for displaying the phpMyAdmin * logo based on configuration settings * * @return string HTML code for the logo */ private function _logo() { // display Logo, depending on $GLOBALS['cfg']['NavigationDisplayLogo'] if (!$GLOBALS['cfg']['NavigationDisplayLogo']) { return Template::get('navigation/logo')->render(array('displayLogo' => false)); } $logo = 'phpMyAdmin'; if (@file_exists($GLOBALS['pmaThemeImage'] . 'logo_left.png')) { $logo = '<img src="' . $GLOBALS['pmaThemeImage'] . 'logo_left.png" ' . 'alt="' . $logo . '" id="imgpmalogo" />'; } elseif (@file_exists($GLOBALS['pmaThemeImage'] . 'pma_logo2.png')) { $logo = '<img src="' . $GLOBALS['pmaThemeImage'] . 'pma_logo2.png" ' . 'alt="' . $logo . '" id="imgpmalogo" />'; } if (!$GLOBALS['cfg']['NavigationLogoLink']) { return Template::get('navigation/logo')->render(array('displayLogo' => true, 'useLogoLink' => false, 'logo' => $logo)); } $useLogoLink = true; $linkAttriks = null; $logoLink = trim(htmlspecialchars($GLOBALS['cfg']['NavigationLogoLink'])); // prevent XSS, see PMASA-2013-9 // if link has protocol, allow only http and https if (!Sanitize::checkLink($logoLink, true)) { $logoLink = 'index.php'; } switch ($GLOBALS['cfg']['NavigationLogoLinkWindow']) { case 'new': $linkAttriks = 'target="_blank" rel="noopener noreferrer"'; break; case 'main': // do not add our parameters for an external link $host = parse_url($GLOBALS['cfg']['NavigationLogoLink'], PHP_URL_HOST); if (empty($host)) { $logoLink .= URL::getCommon(); } else { $linkAttriks = 'target="_blank" rel="noopener noreferrer"'; } } return Template::get('navigation/logo')->render(array('displayLogo' => true, 'useLogoLink' => $useLogoLink, 'logoLink' => $logoLink, 'linkAttribs' => $linkAttriks, 'logo' => $logo)); }
/** * Returns whether the row count is approximated * * @param array $current_table array containing details about the table * @param boolean $table_is_view whether the table is a view * * @return array */ protected function isRowCountApproximated($current_table, $table_is_view) { $approx_rows = false; $show_superscript = ''; // there is a null value in the ENGINE // - when the table needs to be repaired, or // - when it's a view // so ensure that we'll display "in use" below for a table // that needs to be repaired if (isset($current_table['TABLE_ROWS']) && ($current_table['ENGINE'] != null || $table_is_view)) { // InnoDB table: we did not get an accurate row count $approx_rows = !$table_is_view && $current_table['ENGINE'] == 'InnoDB' && !$current_table['COUNTED']; if ($table_is_view && $current_table['TABLE_ROWS'] >= $GLOBALS['cfg']['MaxExactCountViews']) { $approx_rows = true; $show_superscript = Util::showHint(Sanitize::sanitize(sprintf(__('This view has at least this number of ' . 'rows. Please refer to %sdocumentation%s.'), '[doc@cfg_MaxExactCountViews]', '[/doc]'))); } } return array($approx_rows, $show_superscript); }
/** * Displays a link, or a button if the link's URL is too large, to * accommodate some browsers' limitations * * @param string $url the URL * @param string $message the link message * @param mixed $tag_params string: js confirmation * array: additional tag params (f.e. style="") * @param boolean $new_form we set this to false when we are already in * a form, to avoid generating nested forms * @param boolean $strip_img whether to strip the image * @param string $target target * @param boolean $force_button use a button even when the URL is not too long * * @return string the results to be echoed or saved in an array */ public static function linkOrButton( $url, $message, $tag_params = array(), $new_form = true, $strip_img = false, $target = '', $force_button = false ) { $url_length = mb_strlen($url); // with this we should be able to catch case of image upload // into a (MEDIUM) BLOB; not worth generating even a form for these if ($url_length > $GLOBALS['cfg']['LinkLengthLimit'] * 100) { return ''; } if (! is_array($tag_params)) { $tmp = $tag_params; $tag_params = array(); if (! empty($tmp)) { $tag_params['onclick'] = 'return confirmLink(this, \'' . Sanitize::escapeJsString($tmp) . '\')'; } unset($tmp); } if (! empty($target)) { $tag_params['target'] = htmlentities($target); if ($target === '_blank' && strncmp($url, 'url.php?', 8) == 0) { $tag_params['rel'] = 'noopener noreferrer'; } } $displayed_message = ''; // Add text if not already added if (stristr($message, '<img') && (! $strip_img || ($GLOBALS['cfg']['ActionLinksMode'] == 'icons')) && (strip_tags($message) == $message) ) { $displayed_message = '<span>' . htmlspecialchars( preg_replace('/^.*\salt="([^"]*)".*$/si', '\1', $message) ) . '</span>'; } // Suhosin: Check that each query parameter is not above maximum $in_suhosin_limits = true; if ($url_length <= $GLOBALS['cfg']['LinkLengthLimit']) { $suhosin_get_MaxValueLength = ini_get('suhosin.get.max_value_length'); if ($suhosin_get_MaxValueLength) { $query_parts = self::splitURLQuery($url); foreach ($query_parts as $query_pair) { if (strpos($query_pair, '=') === false) { continue; } list(, $eachval) = explode('=', $query_pair); if (mb_strlen($eachval) > $suhosin_get_MaxValueLength ) { $in_suhosin_limits = false; break; } } } } if (($url_length <= $GLOBALS['cfg']['LinkLengthLimit']) && $in_suhosin_limits && ! $force_button ) { $tag_params_strings = array(); foreach ($tag_params as $par_name => $par_value) { // htmlspecialchars() only on non javascript $par_value = mb_substr($par_name, 0, 2) == 'on' ? $par_value : htmlspecialchars($par_value); $tag_params_strings[] = $par_name . '="' . $par_value . '"'; } // no whitespace within an <a> else Safari will make it part of the link $ret = "\n" . '<a href="' . $url . '" ' . implode(' ', $tag_params_strings) . '>' . $message . $displayed_message . '</a>' . "\n"; } else { // no spaces (line breaks) at all // or after the hidden fields // IE will display them all if (! isset($query_parts)) { $query_parts = self::splitURLQuery($url); } $url_parts = parse_url($url); if ($new_form) { if ($target) { $target = ' target="' . $target . '"'; } $ret = '<form action="' . $url_parts['path'] . '" class="link"' . ' method="post"' . $target . ' style="display: inline;">'; $subname_open = ''; $subname_close = ''; $submit_link = '#'; } else { $query_parts[] = 'redirect=' . $url_parts['path']; if (empty($GLOBALS['subform_counter'])) { $GLOBALS['subform_counter'] = 0; } $GLOBALS['subform_counter']++; $ret = ''; $subname_open = 'subform[' . $GLOBALS['subform_counter'] . ']['; $subname_close = ']'; $submit_link = '#usesubform[' . $GLOBALS['subform_counter'] . ']=1'; } foreach ($query_parts as $query_pair) { list($eachvar, $eachval) = explode('=', $query_pair); $ret .= '<input type="hidden" name="' . $subname_open . $eachvar . $subname_close . '" value="' . htmlspecialchars(urldecode($eachval)) . '" />'; } // end while if (empty($tag_params['class'])) { $tag_params['class'] = 'formLinkSubmit'; } else { $tag_params['class'] .= ' formLinkSubmit'; } $tag_params_strings = array(); foreach ($tag_params as $par_name => $par_value) { // htmlspecialchars() only on non javascript $par_value = mb_substr($par_name, 0, 2) == 'on' ? $par_value : htmlspecialchars($par_value); $tag_params_strings[] = $par_name . '="' . $par_value . '"'; } $ret .= "\n" . '<a href="' . $submit_link . '" ' . implode(' ', $tag_params_strings) . '>' . $message . ' ' . $displayed_message . '</a>' . "\n"; if ($new_form) { $ret .= '</form>'; } } // end if... else... return $ret; } // end of the 'linkOrButton()' function
/** * Generate HTML for export form * * @param array $url_params Parameters * @param string $str1 HTML for logtype select * @param string $str2 HTML for "from date" * @param string $str3 HTML for "to date" * @param string $str4 HTML for user * @param string $str5 HTML for "list report" * * @return string HTML for form */ function PMA_getHtmlForTrackingReportExportForm2($url_params, $str1, $str2, $str3, $str4, $str5) { $html = '<form method="post" action="tbl_tracking.php' . URL::getCommon($url_params + array('report' => 'true', 'version' => $_REQUEST['version'])) . '">'; $html .= sprintf(__('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'), $str1, $str2, $str3, $str4, $str5); $html .= '</form>'; $html .= '<form class="disableAjax" method="post" action="tbl_tracking.php' . URL::getCommon($url_params + array('report' => 'true', 'version' => $_REQUEST['version'])) . '">'; $html .= '<input type="hidden" name="logtype" value="' . htmlspecialchars($_REQUEST['logtype']) . '" />'; $html .= '<input type="hidden" name="date_from" value="' . htmlspecialchars($_REQUEST['date_from']) . '" />'; $html .= '<input type="hidden" name="date_to" value="' . htmlspecialchars($_REQUEST['date_to']) . '" />'; $html .= '<input type="hidden" name="users" value="' . htmlspecialchars($_REQUEST['users']) . '" />'; $str_export1 = '<select name="export_type">' . '<option value="sqldumpfile">' . __('SQL dump (file download)') . '</option>' . '<option value="sqldump">' . __('SQL dump') . '</option>' . '<option value="execution" onclick="alert(\'' . Sanitize::escapeJsString(__('This option will replace your table and contained data.')) . '\')">' . __('SQL execution') . '</option>' . '</select>'; $str_export2 = '<input type="hidden" name="report_export" value="1" />' . '<input type="submit" value="' . __('Go') . '" />'; $html .= "<br/>" . sprintf(__('Export as %s'), $str_export1) . $str_export2 . "<br/>"; $html .= '</form>'; return $html; }
/** * Appends JS validation code to $js_array * * @param string $field_id ID of field to validate * @param string|array $validators validators callback * @param array &$js_array will be updated with javascript code * * @return void */ function PMA_addJsValidate($field_id, $validators, &$js_array) { foreach ((array) $validators as $validator) { $validator = (array) $validator; $v_name = array_shift($validator); $v_name = "PMA_" . $v_name; $v_args = array(); foreach ($validator as $arg) { $v_args[] = Sanitize::escapeJsString($arg); } $v_args = $v_args ? ", ['" . implode("', '", $v_args) . "']" : ''; $js_array[] = "validateField('{$field_id}', '{$v_name}', true{$v_args})"; } }
list($save_filename, $message, $file_handle) = PMA_openExportFile($filename, $quick_export); // problem opening export file on server? if (!empty($message)) { PMA_showExportPage($db, $table, $export_type); } } else { /** * Send headers depending on whether the user chose to download a dump file * or not */ if ($asfile) { // Download // (avoid rewriting data containing HTML with anchors and forms; // this was reported to happen under Plesk) @ini_set('url_rewriter.tags', ''); $filename = Sanitize::sanitizeFilename($filename); PMA_downloadHeader($filename, $mime_type); } else { // HTML if ($export_type == 'database') { $num_tables = count($tables); if ($num_tables == 0) { $message = PMA\libraries\Message::error(__('No tables found in database.')); $active_page = 'db_export.php'; include 'db_export.php'; exit; } } list($html, $back_button) = PMA_getHtmlForDisplayedExportHeader($export_type, $db, $table); echo $html; unset($html);
/** * Show index data * * @param string $table The table name * @param string $schema The schema name * @param boolean $print_mode Whether the output is for the print mode * * @return string HTML for showing index * * @access public */ public static function getHtmlForIndexes($table, $schema, $print_mode = false) { $indexes = Index::getFromTable($table, $schema); $no_indexes_class = count($indexes) > 0 ? ' hide' : ''; $no_indexes = "<div class='no_indexes_defined{$no_indexes_class}'>"; $no_indexes .= Message::notice(__('No index defined!'))->getDisplay(); $no_indexes .= '</div>'; if (!$print_mode) { $r = '<fieldset class="index_info">'; $r .= '<legend id="index_header">' . __('Indexes'); $r .= Util::showMySQLDocu('optimizing-database-structure'); $r .= '</legend>'; $r .= $no_indexes; if (count($indexes) < 1) { $r .= '</fieldset>'; return $r; } $r .= Index::findDuplicates($table, $schema); } else { $r = '<h3>' . __('Indexes') . '</h3>'; $r .= $no_indexes; if (count($indexes) < 1) { return $r; } } $r .= '<table id="table_index">'; $r .= '<thead>'; $r .= '<tr>'; if (!$print_mode) { $r .= '<th colspan="2" class="print_ignore">' . __('Action') . '</th>'; } $r .= '<th>' . __('Keyname') . '</th>'; $r .= '<th>' . __('Type') . '</th>'; $r .= '<th>' . __('Unique') . '</th>'; $r .= '<th>' . __('Packed') . '</th>'; $r .= '<th>' . __('Column') . '</th>'; $r .= '<th>' . __('Cardinality') . '</th>'; $r .= '<th>' . __('Collation') . '</th>'; $r .= '<th>' . __('Null') . '</th>'; $r .= '<th>' . __('Comment') . '</th>'; $r .= '</tr>'; $r .= '</thead>'; $r .= '<tbody>'; foreach ($indexes as $index) { $row_span = ' rowspan="' . $index->getColumnCount() . '" '; $r .= '<tr class="noclick" >'; if (!$print_mode) { $this_params = $GLOBALS['url_params']; $this_params['index'] = $index->getName(); $r .= '<td class="edit_index print_ignore'; $r .= ' ajax'; $r .= '" ' . $row_span . '>' . ' <a class="'; $r .= 'ajax'; $r .= '" href="tbl_indexes.php' . URL::getCommon($this_params) . '">' . Util::getIcon('b_edit.png', __('Edit')) . '</a>' . '</td>' . "\n"; $this_params = $GLOBALS['url_params']; if ($index->getName() == 'PRIMARY') { $this_params['sql_query'] = 'ALTER TABLE ' . Util::backquote($table) . ' DROP PRIMARY KEY;'; $this_params['message_to_show'] = __('The primary key has been dropped.'); $js_msg = Sanitize::jsFormat('ALTER TABLE ' . $table . ' DROP PRIMARY KEY'); } else { $this_params['sql_query'] = 'ALTER TABLE ' . Util::backquote($table) . ' DROP INDEX ' . Util::backquote($index->getName()) . ';'; $this_params['message_to_show'] = sprintf(__('Index %s has been dropped.'), htmlspecialchars($index->getName())); $js_msg = Sanitize::jsFormat('ALTER TABLE ' . $table . ' DROP INDEX ' . $index->getName() . ';'); } $r .= '<td ' . $row_span . ' class="print_ignore">'; $r .= '<input type="hidden" class="drop_primary_key_index_msg"' . ' value="' . $js_msg . '" />'; $r .= ' <a class="drop_primary_key_index_anchor'; $r .= ' ajax'; $r .= '" href="sql.php' . URL::getCommon($this_params) . '" >' . Util::getIcon('b_drop.png', __('Drop')) . '</a>' . '</td>' . "\n"; } if (!$print_mode) { $r .= '<th ' . $row_span . '>' . htmlspecialchars($index->getName()) . '</th>'; } else { $r .= '<td ' . $row_span . '>' . htmlspecialchars($index->getName()) . '</td>'; } $r .= '<td ' . $row_span . '>'; $type = $index->getType(); if (!empty($type)) { $r .= htmlspecialchars($type); } else { $r .= htmlspecialchars($index->getChoice()); } $r .= '</td>'; $r .= '<td ' . $row_span . '>' . $index->isUnique(true) . '</td>'; $r .= '<td ' . $row_span . '>' . $index->isPacked() . '</td>'; foreach ($index->getColumns() as $column) { if ($column->getSeqInIndex() > 1) { $r .= '<tr class="noclick" >'; } $r .= '<td>' . htmlspecialchars($column->getName()); if ($column->getSubPart()) { $r .= ' (' . htmlspecialchars($column->getSubPart()) . ')'; } $r .= '</td>'; $r .= '<td>' . htmlspecialchars($column->getCardinality()) . '</td>'; $r .= '<td>' . htmlspecialchars($column->getCollation()) . '</td>'; $r .= '<td>' . htmlspecialchars($column->getNull(true)) . '</td>'; if ($column->getSeqInIndex() == 1) { $r .= '<td ' . $row_span . '>' . htmlspecialchars($index->getComments()) . '</td>'; } $r .= '</tr>'; } // end foreach $index['Sequences'] } // end while $r .= '</tbody>'; $r .= '</table>'; if (!$print_mode) { $r .= '</fieldset>'; } return $r; }
/** * Test for PMA_sendHeaderLocation * * @return void */ public function testSendHeaderLocationIisLongUri() { $GLOBALS['PMA_Config']->set('PMA_IS_IIS', true); // over 600 chars $testUri = 'http://testurl.com/test.php?testlonguri=over600chars&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test&test=test&test=test&test=test&test=test' . '&test=test&test=test'; $testUri_html = htmlspecialchars($testUri); $testUri_js = Sanitize::escapeJsString($testUri); $header = "<html><head><title>- - -</title>\n <meta http-equiv=\"expires\" content=\"0\">" . "<meta http-equiv=\"Pragma\" content=\"no-cache\">" . "<meta http-equiv=\"Cache-Control\" content=\"no-cache\">" . "<meta http-equiv=\"Refresh\" content=\"0;url=" . $testUri_html . "\">" . "<script type=\"text/javascript\">//<![CDATA[\n setTimeout(\"window.location = decodeURI('" . $testUri_js . "')\", 2000);\n //]]></script></head>\n<body><script type=\"text/javascript\">//<![CDATA[\n document.write('<p><a href=\"" . $testUri_html . "\">" . __('Go') . "</a></p>');\n //]]></script></body></html>\n"; $this->expectOutputString($header); $restoreInstance = PMA\libraries\Response::getInstance(); $mockResponse = $this->getMockBuilder('PMA\\libraries\\Response')->disableOriginalConstructor()->setMethods(array('disable', 'header', 'headersSent'))->getMock(); $mockResponse->expects($this->once())->method('disable'); $mockResponse->expects($this->any())->method('headersSent')->with()->will($this->returnValue(false)); $attrInstance = new ReflectionProperty('PMA\\libraries\\Response', '_instance'); $attrInstance->setAccessible(true); $attrInstance->setValue($mockResponse); PMA_sendHeaderLocation($testUri); $attrInstance->setValue($restoreInstance); }
/** * Sanitize::escapeJsString tests * * @param string $target expected output * @param string $source string to be escaped * * @return void * * @dataProvider escapeDataProvider */ public function testEscapeJsString($target, $source) { $this->assertEquals($target, Sanitize::escapeJsString($source)); }
/** * Sanitizes the file name. * * @param string $file_name file name * @param string $ext extension of the file * * @return string the sanitized file name * @access private */ private function _sanitizeName($file_name, $ext) { $file_name = Sanitize::sanitizeFilename($file_name); // Check if the user already added extension; // get the substring where the extension would be if it was included $extension_start_pos = mb_strlen($file_name) - mb_strlen($ext) - 1; $user_extension = mb_substr($file_name, $extension_start_pos, mb_strlen($file_name)); $required_extension = "." . $ext; if (mb_strtolower($user_extension) != $required_extension) { $file_name .= $required_extension; } return $file_name; }
/** * Prepare a table of results returned by a SQL query. * * @param integer &$dt_result the link id associated to the query * which results have to be displayed * @param array &$displayParts the parts to display * @param array $analyzed_sql_results analyzed sql results * @param boolean $is_limited_display With limited operations or not * * @return string $table_html Generated HTML content for resulted table * * @access public * * @see sql.php file */ public function getTable(&$dt_result, &$displayParts, $analyzed_sql_results, $is_limited_display = false) { /** * The statement this table is built for. * @var \SqlParser\Statements\SelectStatement */ $statement = $analyzed_sql_results['statement']; $table_html = ''; // Following variable are needed for use in isset/empty or // use with array indexes/safe use in foreach $fields_meta = $this->__get('fields_meta'); $showtable = $this->__get('showtable'); $printview = $this->__get('printview'); // why was this called here? (already called from sql.php) //$this->setConfigParamsForDisplayTable(); /** * @todo move this to a central place * @todo for other future table types */ $is_innodb = isset($showtable['Type']) && $showtable['Type'] == self::TABLE_TYPE_INNO_DB; if ($is_innodb && PMA_isJustBrowsing($analyzed_sql_results, true)) { // "j u s t b r o w s i n g" $pre_count = '~'; $after_count = Util::showHint(Sanitize::sanitize(__('May be approximate. See [doc@faq3-11]FAQ 3.11[/doc].'))); } else { $pre_count = ''; $after_count = ''; } // 1. ----- Prepares the work ----- // 1.1 Gets the information about which functionalities should be // displayed list($displayParts, $total) = $this->_setDisplayPartsAndTotal($displayParts); // 1.2 Defines offsets for the next and previous pages if ($displayParts['nav_bar'] == '1') { list($pos_next, $pos_prev) = $this->_getOffsets(); } // end if // 1.3 Extract sorting expressions. // we need $sort_expression and $sort_expression_nodirection // even if there are many table references $sort_expression = array(); $sort_expression_nodirection = array(); $sort_direction = array(); if (!empty($statement->order)) { foreach ($statement->order as $o) { $sort_expression[] = $o->expr->expr . ' ' . $o->type; $sort_expression_nodirection[] = $o->expr->expr; $sort_direction[] = $o->type; } } else { $sort_expression[] = ''; $sort_expression_nodirection[] = ''; $sort_direction[] = ''; } $number_of_columns = count($sort_expression_nodirection); // 1.4 Prepares display of first and last value of the sorted column $sorted_column_message = ''; for ($i = 0; $i < $number_of_columns; $i++) { $sorted_column_message .= $this->_getSortedColumnMessage($dt_result, $sort_expression_nodirection[$i]); } // 2. ----- Prepare to display the top of the page ----- // 2.1 Prepares a messages with position information if ($displayParts['nav_bar'] == '1' && isset($pos_next)) { $message = $this->_setMessageInformation($sorted_column_message, $analyzed_sql_results, $total, $pos_next, $pre_count, $after_count); $table_html .= Util::getMessage($message, $this->__get('sql_query'), 'success'); } elseif ((!isset($printview) || $printview != '1') && !$is_limited_display) { $table_html .= Util::getMessage(__('Your SQL query has been executed successfully.'), $this->__get('sql_query'), 'success'); } // 2.3 Prepare the navigation bars if (!mb_strlen($this->__get('table'))) { if ($analyzed_sql_results['querytype'] == 'SELECT') { // table does not always contain a real table name, // for example in MySQL 5.0.x, the query SHOW STATUS // returns STATUS as a table name $this->__set('table', $fields_meta[0]->table); } else { $this->__set('table', ''); } } // can the result be sorted? if ($displayParts['sort_lnk'] == '1') { // At this point, $sort_expression is an array but we only verify // the first element in case we could find that the table is // sorted by one of the choices listed in the // "Sort by key" drop-down list($unsorted_sql_query, $sort_by_key_html) = $this->_getUnsortedSqlAndSortByKeyDropDown($analyzed_sql_results, $sort_expression[0]); } else { $sort_by_key_html = $unsorted_sql_query = ''; } if ($displayParts['nav_bar'] == '1' && empty($statement->limit)) { $table_html .= $this->_getPlacedTableNavigations($pos_next, $pos_prev, self::PLACE_TOP_DIRECTION_DROPDOWN, $is_innodb, $sort_by_key_html); } // 2b ----- Get field references from Database ----- // (see the 'relation' configuration variable) // initialize map $map = array(); $target = array(); if (!empty($statement->from)) { foreach ($statement->from as $field) { if (!empty($field->table)) { $target[] = $field->table; } } } if (mb_strlen($this->__get('table'))) { // This method set the values for $map array $this->_setParamForLinkForeignKeyRelatedTables($map); // Coming from 'Distinct values' action of structure page // We manipulate relations mechanism to show a link to related rows. if ($this->__get('is_browse_distinct')) { $map[$fields_meta[1]->name] = array($this->__get('table'), $fields_meta[1]->name, '', $this->__get('db')); } } // end if // end 2b // 3. ----- Prepare the results table ----- if ($is_limited_display) { $table_html .= "<br>"; } $table_html .= $this->_getTableHeaders($displayParts, $analyzed_sql_results, $unsorted_sql_query, $sort_expression, $sort_expression_nodirection, $sort_direction, $is_limited_display); $table_html .= '<tbody>' . "\n"; $table_html .= $this->_getTableBody($dt_result, $displayParts, $map, $analyzed_sql_results, $is_limited_display); $this->__set('display_params', null); $table_html .= '</tbody>' . "\n" . '</table>'; // 4. ----- Prepares the link for multi-fields edit and delete if ($displayParts['del_lnk'] == self::DELETE_ROW && $displayParts['del_lnk'] != self::KILL_PROCESS) { $table_html .= $this->_getMultiRowOperationLinks($dt_result, $analyzed_sql_results, $displayParts['del_lnk']); } // 5. ----- Get the navigation bar at the bottom if required ----- if ($displayParts['nav_bar'] == '1' && empty($statement->limit)) { $table_html .= $this->_getPlacedTableNavigations($pos_next, $pos_prev, self::PLACE_BOTTOM_DIRECTION_DROPDOWN, $is_innodb, $sort_by_key_html); } elseif (!isset($printview) || $printview != '1') { $table_html .= "\n" . '<br /><br />' . "\n"; } // 6. ----- Prepare "Query results operations" if ((!isset($printview) || $printview != '1') && !$is_limited_display) { $table_html .= $this->_getResultsOperations($displayParts, $analyzed_sql_results); } return $table_html; }
/** * Return the filename and MIME type for export file * * @param string $export_type type of export * @param string $remember_template whether to remember template * @param ExportPlugin $export_plugin the export plugin * @param string $compression compression asked * @param string $filename_template the filename template * * @return array the filename template and mime type */ function PMA_getExportFilenameAndMimetype($export_type, $remember_template, $export_plugin, $compression, $filename_template) { if ($export_type == 'server') { if (!empty($remember_template)) { $GLOBALS['PMA_Config']->setUserValue('pma_server_filename_template', 'Export/file_template_server', $filename_template); } } elseif ($export_type == 'database') { if (!empty($remember_template)) { $GLOBALS['PMA_Config']->setUserValue('pma_db_filename_template', 'Export/file_template_database', $filename_template); } } else { if (!empty($remember_template)) { $GLOBALS['PMA_Config']->setUserValue('pma_table_filename_template', 'Export/file_template_table', $filename_template); } } $filename = PMA\libraries\Util::expandUserString($filename_template); // remove dots in filename (coming from either the template or already // part of the filename) to avoid a remote code execution vulnerability $filename = Sanitize::sanitizeFilename($filename, $replaceDots = true); // Grab basic dump extension and mime type // Check if the user already added extension; // get the substring where the extension would be if it was included $extension_start_pos = mb_strlen($filename) - mb_strlen($export_plugin->getProperties()->getExtension()) - 1; $user_extension = mb_substr($filename, $extension_start_pos, mb_strlen($filename)); $required_extension = "." . $export_plugin->getProperties()->getExtension(); if (mb_strtolower($user_extension) != $required_extension) { $filename .= $required_extension; } $mime_type = $export_plugin->getProperties()->getMimeType(); // If dump is going to be compressed, set correct mime_type and add // compression to extension if ($compression == 'gzip') { $filename .= '.gz'; $mime_type = 'application/x-gzip'; } elseif ($compression == 'zip') { $filename .= '.zip'; $mime_type = 'application/zip'; } return array($filename, $mime_type); }
} // end if } /** * Warning about different MySQL library and server version * (a difference on the third digit does not count). * If someday there is a constant that we can check about mysqlnd, * we can use it instead of strpos(). * If no default server is set, $GLOBALS['dbi'] is not defined yet. * We also do not warn if MariaDB is detected, as it has its own version * numbering. */ if (isset($GLOBALS['dbi']) && $cfg['ServerLibraryDifference_DisableWarning'] == false) { $_client_info = $GLOBALS['dbi']->getClientInfo(); if ($server > 0 && mb_strpos($_client_info, 'mysqlnd') === false && mb_strpos(PMA_MYSQL_STR_VERSION, 'MariaDB') === false && substr(PMA_MYSQL_CLIENT_API, 0, 3) != substr(PMA_MYSQL_INT_VERSION, 0, 3)) { trigger_error(Sanitize::sanitize(sprintf(__('Your PHP MySQL library version %s differs from your ' . 'MySQL server version %s. This may cause unpredictable ' . 'behavior.'), $_client_info, substr(PMA_MYSQL_STR_VERSION, 0, strpos(PMA_MYSQL_STR_VERSION . '-', '-')))), E_USER_NOTICE); } unset($_client_info); } /** * Warning about Suhosin only if its simulation mode is not enabled */ if ($cfg['SuhosinDisableWarning'] == false && @ini_get('suhosin.request.max_value_length') && @ini_get('suhosin.simulation') == '0') { trigger_error(sprintf(__('Server running with Suhosin. Please refer to %sdocumentation%s ' . 'for possible issues.'), '[doc@faq1-38]', '[/doc]'), E_USER_WARNING); } /** * Warning about incomplete translations. * * The data file is created while creating release by ./scripts/remove-incomplete-mo */ if (@file_exists('libraries/language_stats.inc.php')) {
/** * Provides search results row with browse/delete links. * (for a table) * * @param string $each_table One of the tables on which search was performed * @param array $newsearchsqls Contains SQL queries * @param bool $odd_row For displaying contrasting table rows * @param integer $res_cnt Number of results found * * @return string HTML row */ private function _getResultsRow($each_table, $newsearchsqls, $odd_row, $res_cnt) { $this_url_params = array('db' => $GLOBALS['db'], 'table' => $each_table, 'goto' => 'db_sql.php', 'pos' => 0, 'is_js_confirmed' => 0); // Start forming search results row $html_output = '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">'; // Displays results count for a table $html_output .= '<td>'; $html_output .= sprintf(_ngettext('%1$s match in <strong>%2$s</strong>', '%1$s matches in <strong>%2$s</strong>', $res_cnt), $res_cnt, htmlspecialchars($each_table)); $html_output .= '</td>'; // Displays browse/delete link if result count > 0 if ($res_cnt > 0) { $this_url_params['sql_query'] = $newsearchsqls['select_columns']; $browse_result_path = 'sql.php' . URL::getCommon($this_url_params); $html_output .= '<td><a name="browse_search" class="ajax" href="' . $browse_result_path . '" onclick="loadResult(\'' . $browse_result_path . '\',\'' . Sanitize::escapeJsString(htmlspecialchars($each_table)) . '\',\'' . URL::getCommon(array('db' => $GLOBALS['db'], 'table' => $each_table)) . '\'' . ');return false;" >' . __('Browse') . '</a></td>'; $this_url_params['sql_query'] = $newsearchsqls['delete']; $delete_result_path = 'sql.php' . URL::getCommon($this_url_params); $html_output .= '<td><a name="delete_search" class="ajax" href="' . $delete_result_path . '" onclick="deleteResult(\'' . $delete_result_path . '\' , \'' . sprintf(__('Delete the matches for the %s table?'), htmlspecialchars($each_table)) . '\');return false;">' . __('Delete') . '</a></td>'; } else { $html_output .= '<td> </td>' . '<td> </td>'; } // end if else $html_output .= '</tr>'; return $html_output; }
foreach ($all_languages as $each_lang) { //Is current one active? $selected = $each_lang->isActive() ? ' selected="selected"' : ''; echo '<option value="', $each_lang->getCode(), '"', $selected, '>', $each_lang->getName(), '</option>', "\n"; } echo '</select>'; echo '</form>'; // Check for done action info and set notice message if present switch ($action_done) { case 'config_saved': /* Use uniqid to display this message every time configuration is saved */ PMA_messagesSet('notice', uniqid('config_saved'), __('Configuration saved.'), Sanitize::sanitize(__('Configuration saved to file config/config.inc.php in phpMyAdmin ' . 'top level directory, copy it to top level one and delete ' . 'directory config to use it.'))); break; case 'config_not_saved': /* Use uniqid to display this message every time configuration is saved */ PMA_messagesSet('notice', uniqid('config_not_saved'), __('Configuration not saved!'), Sanitize::sanitize(__('Please create web server writable folder [em]config[/em] in ' . 'phpMyAdmin top level directory as described in ' . '[doc@setup_script]documentation[/doc]. Otherwise you will be ' . 'only able to download or display it.'))); break; default: break; } echo '<h2>', __('Overview'), '</h2>'; // message handling PMA_messagesEnd(); PMA_messagesShowHtml(); echo '<a href="#" id="show_hidden_messages" style="display:none">'; echo __('Show hidden messages (#MSG_COUNT)'); echo '</a>'; echo '<fieldset class="simple"><legend>'; echo __('Servers'); echo '</legend>'; //
/** * Renders the footer * * @return string */ public function getDisplay() { $retval = ''; $this->_setHistory(); if ($this->_isEnabled) { if (!$this->_isAjax) { $retval .= "</div>"; } if (!$this->_isAjax && !$this->_isMinimal) { if (PMA_getenv('SCRIPT_NAME') && empty($_POST) && empty($GLOBALS['checked_special']) && !$this->_isAjax) { $url = $this->getSelfUrl(); $header = Response::getInstance()->getHeader(); $scripts = $header->getScripts()->getFiles(); $menuHash = $header->getMenu()->getHash(); // prime the client-side cache $this->_scripts->addCode(sprintf('if (! (history && history.pushState)) ' . 'PMA_MicroHistory.primer = {' . ' url: "%s",' . ' scripts: %s,' . ' menuHash: "%s"' . '};', Sanitize::escapeJsString($url), json_encode($scripts), Sanitize::escapeJsString($menuHash))); } if (PMA_getenv('SCRIPT_NAME') && !$this->_isAjax) { $url = $this->getSelfUrl(); $retval .= $this->_getSelfLink($url); } $this->_scripts->addCode('var debugSQLInfo = ' . $this->getDebugMessage() . ';'); $retval .= '<div class="clearfloat" id="pma_errors">'; $retval .= $this->getErrorMessages(); $retval .= '</div>'; $retval .= $this->_scripts->getDisplay(); if ($GLOBALS['cfg']['DBG']['demo']) { $retval .= '<div id="pma_demo">'; $retval .= $this->_getDemoMessage(); $retval .= '</div>'; } // Include possible custom footers if (file_exists(CUSTOM_FOOTER_FILE)) { $retval .= '<div id="pma_footer">'; ob_start(); include CUSTOM_FOOTER_FILE; $retval .= ob_get_contents(); ob_end_clean(); $retval .= '</div>'; } } if (!$this->_isAjax) { $retval .= "</body></html>"; } } return $retval; }
* Gets core libraries and defines some variables */ define('PMA_MINIMUM_COMMON', true); require_once './libraries/common.inc.php'; // Only output the http headers $response = Response::getInstance(); $response->getHeader()->sendHttpHeaders(); $response->disable(); if (! PMA_isValid($_REQUEST['url']) || ! preg_match('/^https:\/\/[^\n\r]*$/', $_REQUEST['url']) || ! PMA_isAllowedDomain($_REQUEST['url']) ) { PMA_sendHeaderLocation('./'); } else { // JavaScript redirection is necessary. Because if header() is used // then web browser sometimes does not change the HTTP_REFERER // field and so with old URL as Referer, token also goes to // external site. echo "<script type='text/javascript'> window.onload=function(){ window.location='" , Sanitize::escapeJsString($_REQUEST['url']) , "'; } </script>"; // Display redirecting msg on screen. // Do not display the value of $_REQUEST['url'] to avoid showing injected content echo __('Taking you to the target site.'); } die();
/** * Function to get html for each insert/edit column * * @param array $table_columns table columns * @param int $column_number column index in table_columns * @param array $comments_map comments map * @param bool $timestamp_seen whether timestamp seen * @param array $current_result current result * @param string $chg_evt_handler javascript change event handler * @param string $jsvkey javascript validation key * @param string $vkey validation key * @param bool $insert_mode whether insert mode * @param array $current_row current row * @param int &$o_rows row offset * @param int &$tabindex tab index * @param int $columns_cnt columns count * @param bool $is_upload whether upload * @param int $tabindex_for_function tab index offset for function * @param array $foreigners foreigners * @param int $tabindex_for_null tab index offset for null * @param int $tabindex_for_value tab index offset for value * @param string $table table * @param string $db database * @param int $row_id row id * @param array $titles titles * @param int $biggest_max_file_size biggest max file size * @param string $default_char_editing default char editing mode which is stored * in the config.inc.php script * @param string $text_dir text direction * @param array $repopulate the data to be repopulated * @param array $column_mime the mime information of column * @param string $where_clause the where clause * * @return string */ function PMA_getHtmlForInsertEditFormColumn($table_columns, $column_number, $comments_map, $timestamp_seen, $current_result, $chg_evt_handler, $jsvkey, $vkey, $insert_mode, $current_row, &$o_rows, &$tabindex, $columns_cnt, $is_upload, $tabindex_for_function, $foreigners, $tabindex_for_null, $tabindex_for_value, $table, $db, $row_id, $titles, $biggest_max_file_size, $default_char_editing, $text_dir, $repopulate, $column_mime, $where_clause) { $column = $table_columns[$column_number]; $readOnly = false; if (!PMA_userHasColumnPrivileges($column, $insert_mode)) { $readOnly = true; } if (!isset($column['processed'])) { $column = PMA_analyzeTableColumnsArray($column, $comments_map, $timestamp_seen); } $as_is = false; if (!empty($repopulate) && !empty($current_row)) { $current_row[$column['Field']] = $repopulate[$column['Field_md5']]; $as_is = true; } $extracted_columnspec = PMA\libraries\Util::extractColumnSpec($column['Type']); if (-1 === $column['len']) { $column['len'] = $GLOBALS['dbi']->fieldLen($current_result, $column_number); // length is unknown for geometry fields, // make enough space to edit very simple WKTs if (-1 === $column['len']) { $column['len'] = 30; } } //Call validation when the form submitted... $onChangeClause = $chg_evt_handler . "=\"return verificationsAfterFieldChange('" . Sanitize::escapeJsString($column['Field_md5']) . "', '" . Sanitize::escapeJsString($jsvkey) . "','" . $column['pma_type'] . "')\""; // Use an MD5 as an array index to avoid having special characters // in the name attribute (see bug #1746964 ) $column_name_appendix = $vkey . '[' . $column['Field_md5'] . ']'; if ($column['Type'] === 'datetime' && !isset($column['Default']) && !is_null($column['Default']) && $insert_mode) { $column['Default'] = date('Y-m-d H:i:s', time()); } $html_output = PMA_getHtmlForFunctionOption($column, $column_name_appendix); if ($GLOBALS['cfg']['ShowFieldTypesInDataEditView']) { $html_output .= PMA_getHtmlForInsertEditColumnType($column); } //End if // Get a list of GIS data types. $gis_data_types = PMA\libraries\Util::getGISDatatypes(); // Prepares the field value $real_null_value = false; $special_chars_encoded = ''; if (!empty($current_row)) { // (we are editing) list($real_null_value, $special_chars_encoded, $special_chars, $data, $backup_field) = PMA_getSpecialCharsAndBackupFieldForExistingRow($current_row, $column, $extracted_columnspec, $real_null_value, $gis_data_types, $column_name_appendix, $as_is); } else { // (we are inserting) // display default values $tmp = $column; if (isset($repopulate[$column['Field_md5']])) { $tmp['Default'] = $repopulate[$column['Field_md5']]; } list($real_null_value, $data, $special_chars, $backup_field, $special_chars_encoded) = PMA_getSpecialCharsAndBackupFieldForInsertingMode($tmp, $real_null_value); unset($tmp); } $idindex = $o_rows * $columns_cnt + $column_number + 1; $tabindex = $idindex; // Get a list of data types that are not yet supported. $no_support_types = PMA\libraries\Util::unsupportedDatatypes(); // The function column // ------------------- $foreignData = PMA_getForeignData($foreigners, $column['Field'], false, '', ''); if ($GLOBALS['cfg']['ShowFunctionFields']) { $html_output .= PMA_getFunctionColumn($column, $is_upload, $column_name_appendix, $onChangeClause, $no_support_types, $tabindex_for_function, $tabindex, $idindex, $insert_mode, $readOnly, $foreignData); } // The null column // --------------- $html_output .= PMA_getNullColumn($column, $column_name_appendix, $real_null_value, $tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners, $foreignData, $readOnly); // The value column (depends on type) // ---------------- // See bug #1667887 for the reason why we don't use the maxlength // HTML attribute //add data attributes "no of decimals" and "data type" $no_decimals = 0; $type = current(explode("(", $column['pma_type'])); if (preg_match('/\\(([^()]+)\\)/', $column['pma_type'], $match)) { $match[0] = trim($match[0], '()'); $no_decimals = $match[0]; } $html_output .= '<td' . ' data-type="' . $type . '"' . ' data-decimals="' . $no_decimals . '">' . "\n"; // Will be used by js/tbl_change.js to set the default value // for the "Continue insertion" feature $html_output .= '<span class="default_value hide">' . $special_chars . '</span>'; // Check input transformation of column $transformed_html = ''; if (!empty($column_mime['input_transformation'])) { $file = $column_mime['input_transformation']; $include_file = 'libraries/plugins/transformations/' . $file; if (is_file($include_file)) { include_once $include_file; $class_name = PMA_getTransformationClassName($include_file); $transformation_plugin = new $class_name(); $transformation_options = PMA_Transformation_getOptions($column_mime['input_transformation_options']); $_url_params = array('db' => $db, 'table' => $table, 'transform_key' => $column['Field'], 'where_clause' => $where_clause); $transformation_options['wrapper_link'] = URL::getCommon($_url_params); $current_value = ''; if (isset($current_row[$column['Field']])) { $current_value = $current_row[$column['Field']]; } if (method_exists($transformation_plugin, 'getInputHtml')) { $transformed_html = $transformation_plugin->getInputHtml($column, $row_id, $column_name_appendix, $transformation_options, $current_value, $text_dir, $tabindex, $tabindex_for_value, $idindex); } if (method_exists($transformation_plugin, 'getScripts')) { $GLOBALS['plugin_scripts'] = array_merge($GLOBALS['plugin_scripts'], $transformation_plugin->getScripts()); } } } if (!empty($transformed_html)) { $html_output .= $transformed_html; } else { $html_output .= PMA_getValueColumn($column, $backup_field, $column_name_appendix, $onChangeClause, $tabindex, $tabindex_for_value, $idindex, $data, $special_chars, $foreignData, array($table, $db), $row_id, $titles, $text_dir, $special_chars_encoded, $vkey, $is_upload, $biggest_max_file_size, $default_char_editing, $no_support_types, $gis_data_types, $extracted_columnspec, $readOnly); } $html_output .= '</td>' . '</tr>'; return $html_output; }
/** * Returns, as a string, a list of parameters * used on the client side * * @return string */ public function getJsParamsCode() { $params = $this->getJsParams(); foreach ($params as $key => $value) { $params[$key] = $key . ':"' . Sanitize::escapeJsString($value) . '"'; } return 'PMA_commonParams.setAll({' . implode(',', $params) . '});'; }
/** * Adds JS code snippet for variable assignment * to be displayed by the PMA\libraries\Response class. * * @param string $key Name of value to set * @param mixed $value Value to set, can be either string or array of strings * @param bool $escape Whether to escape value or keep it as it is * (for inclusion of js code) * * @return void */ function PMA_addJSVar($key, $value, $escape = true) { PMA_addJSCode(Sanitize::getJsValue($key, $value, $escape)); }
/** * decode $message, taking into account our special codes * for formatting * * @param string $message the message * * @return string the decoded message * @access public * @static */ public static function decodeBB($message) { return Sanitize::sanitize($message, false, true); }
/** * Prints javascript for upload with plugin, upload process bar * * @param int $upload_id The selected upload id * * @return string */ function PMA_getHtmlForImportWithPlugin($upload_id) { //some variable for javascript $ajax_url = "import_status.php?id=" . $upload_id . "&" . URL::getCommonRaw(array('import_status' => 1)); $promot_str = Sanitize::jsFormat(__('The file being uploaded is probably larger than ' . 'the maximum allowed size or this is a known bug in webkit ' . 'based (Safari, Google Chrome, Arora etc.) browsers.'), false); $statustext_str = Sanitize::escapeJsString(__('%s of %s')); $upload_str = Sanitize::jsFormat(__('Uploading your import fileā¦'), false); $second_str = Sanitize::jsFormat(__('%s/sec.'), false); $remaining_min = Sanitize::jsFormat(__('About %MIN min. %SEC sec. remaining.'), false); $remaining_second = Sanitize::jsFormat(__('About %SEC sec. remaining.'), false); $processed_str = Sanitize::jsFormat(__('The file is being processed, please be patient.'), false); $import_url = URL::getCommonRaw(array('import_status' => 1)); //start output $html = 'var finished = false; '; $html .= 'var percent = 0.0; '; $html .= 'var total = 0; '; $html .= 'var complete = 0; '; $html .= 'var original_title = ' . 'parent && parent.document ? parent.document.title : false; '; $html .= 'var import_start; '; $html .= 'var perform_upload = function () { '; $html .= 'new $.getJSON( '; $html .= ' "' . $ajax_url . '", '; $html .= ' {}, '; $html .= ' function(response) { '; $html .= ' finished = response.finished; '; $html .= ' percent = response.percent; '; $html .= ' total = response.total; '; $html .= ' complete = response.complete; '; $html .= ' if (total==0 && complete==0 && percent==0) { '; $img_tag = '<img src="' . $GLOBALS['pmaThemeImage'] . 'ajax_clock_small.gif"'; $html .= ' $("#upload_form_status_info").html(\'' . $img_tag . ' width="16" height="16" alt="ajax clock" /> ' . $promot_str . '\'); '; $html .= ' $("#upload_form_status").css("display", "none"); '; $html .= ' } else { '; $html .= ' var now = new Date(); '; $html .= ' now = Date.UTC( '; $html .= ' now.getFullYear(), '; $html .= ' now.getMonth(), '; $html .= ' now.getDate(), '; $html .= ' now.getHours(), '; $html .= ' now.getMinutes(), '; $html .= ' now.getSeconds()) '; $html .= ' + now.getMilliseconds() - 1000; '; $html .= ' var statustext = PMA_sprintf('; $html .= ' "' . $statustext_str . '", '; $html .= ' formatBytes( '; $html .= ' complete, 1, PMA_messages.strDecimalSeparator'; $html .= ' ), '; $html .= ' formatBytes('; $html .= ' total, 1, PMA_messages.strDecimalSeparator'; $html .= ' ) '; $html .= ' ); '; $html .= ' if ($("#importmain").is(":visible")) { '; // show progress UI $html .= ' $("#importmain").hide(); '; $html .= ' $("#import_form_status") '; $html .= ' .html(\'<div class="upload_progress">' . '<div class="upload_progress_bar_outer"><div class="percentage">' . '</div><div id="status" class="upload_progress_bar_inner">' . '<div class="percentage"></div></div></div><div>' . '<img src="' . $GLOBALS['pmaThemeImage'] . 'ajax_clock_small.gif" width="16" height="16" alt="ajax clock" /> ' . $upload_str . '</div><div id="statustext"></div></div>\') '; $html .= ' .show(); '; $html .= ' import_start = now; '; $html .= ' } '; $html .= ' else if (percent > 9 || complete > 2000000) { '; // calculate estimated time $html .= ' var used_time = now - import_start; '; $html .= ' var seconds = ' . 'parseInt(((total - complete) / complete) * used_time / 1000); '; $html .= ' var speed = PMA_sprintf("' . $second_str . '"'; $html .= ' , formatBytes(complete / used_time * 1000, 1,' . ' PMA_messages.strDecimalSeparator)); '; $html .= ' var minutes = parseInt(seconds / 60); '; $html .= ' seconds %= 60; '; $html .= ' var estimated_time; '; $html .= ' if (minutes > 0) { '; $html .= ' estimated_time = "' . $remaining_min . '"'; $html .= ' .replace("%MIN", minutes)'; $html .= ' .replace("%SEC", seconds); '; $html .= ' } '; $html .= ' else { '; $html .= ' estimated_time = "' . $remaining_second . '"'; $html .= ' .replace("%SEC", seconds); '; $html .= ' } '; $html .= ' statustext += "<br />" + speed + "<br /><br />" ' . '+ estimated_time; '; $html .= ' } '; $html .= ' var percent_str = Math.round(percent) + "%"; '; $html .= ' $("#status").animate({width: percent_str}, 150); '; $html .= ' $(".percentage").text(percent_str); '; // show percent in window title $html .= ' if (original_title !== false) { '; $html .= ' parent.document.title '; $html .= ' = percent_str + " - " + original_title; '; $html .= ' } '; $html .= ' else { '; $html .= ' document.title '; $html .= ' = percent_str + " - " + original_title; '; $html .= ' } '; $html .= ' $("#statustext").html(statustext); '; $html .= ' } '; $html .= ' if (finished == true) { '; $html .= ' if (original_title !== false) { '; $html .= ' parent.document.title = original_title; '; $html .= ' } '; $html .= ' else { '; $html .= ' document.title = original_title; '; $html .= ' } '; $html .= ' $("#importmain").hide(); '; // loads the message, either success or mysql error $html .= ' $("#import_form_status") '; $html .= ' .html(\'<img src="' . $GLOBALS['pmaThemeImage'] . 'ajax_clock_small.gif" width="16" height="16" alt="ajax clock" /> ' . $processed_str . '\')'; $html .= ' .show(); '; $html .= ' $("#import_form_status").load("import_status.php?' . 'message=true&' . $import_url . '"); '; $html .= ' PMA_reloadNavigation(); '; // if finished $html .= ' } '; $html .= ' else { '; $html .= ' setTimeout(perform_upload, 1000); '; $html .= ' } '; $html .= '}); '; $html .= '}; '; $html .= 'setTimeout(perform_upload, 1000); '; return $html; }
/** * Sends header indicating file download. * * @param string $filename Filename to include in headers if empty, * none Content-Disposition header will be sent. * @param string $mimetype MIME type to include in headers. * @param int $length Length of content (optional) * @param bool $no_cache Whether to include no-caching headers. * * @return void */ function PMA_downloadHeader($filename, $mimetype, $length = 0, $no_cache = true) { if ($no_cache) { PMA_noCacheHeader(); } /* Replace all possibly dangerous chars in filename */ $filename = Sanitize::sanitizeFilename($filename); if (!empty($filename)) { header('Content-Description: File Transfer'); header('Content-Disposition: attachment; filename="' . $filename . '"'); } header('Content-Type: ' . $mimetype); // inform the server that compression has been done, // to avoid a double compression (for example with Apache + mod_deflate) $notChromeOrLessThan43 = PMA_USR_BROWSER_AGENT != 'CHROME' || PMA_USR_BROWSER_AGENT == 'CHROME' && PMA_USR_BROWSER_VER < 43; if (strpos($mimetype, 'gzip') !== false && $notChromeOrLessThan43) { header('Content-Encoding: gzip'); } header('Content-Transfer-Encoding: binary'); if ($length > 0) { header('Content-Length: ' . $length); } }
/** * Does the actual work of each specific transformations plugin. * * @param string $buffer text to be transformed * @param array $options transformation options * @param string $meta meta information * * @return string */ public function applyTransformation($buffer, $options = array(), $meta = '') { // possibly use a global transform and feed it with special options // further operations on $buffer using the $options[] array. if (empty($options[0])) { $options[0] = 0; } if (empty($options[2])) { $options[2] = 'local'; } else { $options[2] = mb_strtolower($options[2]); } if (empty($options[1])) { if ($options[2] == 'local') { $options[1] = __('%B %d, %Y at %I:%M %p'); } else { $options[1] = 'Y-m-d H:i:s'; } } $timestamp = -1; // INT columns will be treated as UNIX timestamps // and need to be detected before the verification for // MySQL TIMESTAMP if ($meta->type == 'int') { $timestamp = $buffer; // Detect TIMESTAMP(6 | 8 | 10 | 12 | 14) // TIMESTAMP (2 | 4) not supported here. // (Note: prior to MySQL 4.1, TIMESTAMP has a display size // for example TIMESTAMP(8) means YYYYMMDD) } else { if (preg_match('/^(\\d{2}){3,7}$/', $buffer)) { if (mb_strlen($buffer) == 14 || mb_strlen($buffer) == 8) { $offset = 4; } else { $offset = 2; } $aDate = array(); $aDate['year'] = (int) mb_substr($buffer, 0, $offset); $aDate['month'] = (int) mb_substr($buffer, $offset, 2); $aDate['day'] = (int) mb_substr($buffer, $offset + 2, 2); $aDate['hour'] = (int) mb_substr($buffer, $offset + 4, 2); $aDate['minute'] = (int) mb_substr($buffer, $offset + 6, 2); $aDate['second'] = (int) mb_substr($buffer, $offset + 8, 2); if (checkdate($aDate['month'], $aDate['day'], $aDate['year'])) { $timestamp = mktime($aDate['hour'], $aDate['minute'], $aDate['second'], $aDate['month'], $aDate['day'], $aDate['year']); } // If all fails, assume one of the dozens of valid strtime() syntaxes // (https://www.gnu.org/manual/tar-1.12/html_chapter/tar_7.html) } else { if (preg_match('/^[0-9]\\d{1,9}$/', $buffer)) { $timestamp = (int) $buffer; } else { $timestamp = strtotime($buffer); } } } // If all above failed, maybe it's a Unix timestamp already? if ($timestamp < 0 && preg_match('/^[1-9]\\d{1,9}$/', $buffer)) { $timestamp = $buffer; } // Reformat a valid timestamp if ($timestamp >= 0) { $timestamp -= $options[0] * 60 * 60; $source = $buffer; if ($options[2] == 'local') { $text = PMA\libraries\Util::localisedDate($timestamp, $options[1]); } elseif ($options[2] == 'utc') { $text = gmdate($options[1], $timestamp); } else { $text = 'INVALID DATE TYPE'; } return '<dfn onclick="alert(\'' . Sanitize::jsFormat($source, false) . '\');" title="' . htmlspecialchars($source) . '">' . htmlspecialchars($text) . '</dfn>'; } else { return htmlspecialchars($buffer); } }
/** * Prepares data for input field display and outputs HTML code * * @param Form $form Form object * @param string $field field name as it appears in $form * @param string $system_path field path, eg. Servers/1/verbose * @param string $work_path work path, eg. Servers/4/verbose * @param string $translated_path work path changed so that it can be * used as XHTML id * @param bool $show_restore_default whether show "restore default" button * besides the input field * @param bool|null $userprefs_allow whether user preferences are enabled * for this field (null - no support, * true/false - enabled/disabled) * @param array &$js_default array which stores JavaScript code * to be displayed * * @return string HTML for input field */ private function _displayFieldInput(Form $form, $field, $system_path, $work_path, $translated_path, $show_restore_default, $userprefs_allow, array &$js_default) { $name = PMA_langName($system_path); $description = PMA_langName($system_path, 'desc', ''); $value = $this->_configFile->get($work_path); $value_default = $this->_configFile->getDefault($system_path); $value_is_default = false; if ($value === null || $value === $value_default) { $value = $value_default; $value_is_default = true; } $opts = array('doc' => $this->getDocLink($system_path), 'show_restore_default' => $show_restore_default, 'userprefs_allow' => $userprefs_allow, 'userprefs_comment' => PMA_langName($system_path, 'cmt', '')); if (isset($form->default[$system_path])) { $opts['setvalue'] = $form->default[$system_path]; } if (isset($this->_errors[$work_path])) { $opts['errors'] = $this->_errors[$work_path]; } $type = ''; switch ($form->getOptionType($field)) { case 'string': $type = 'text'; break; case 'short_string': $type = 'short_text'; break; case 'double': case 'integer': $type = 'number_text'; break; case 'boolean': $type = 'checkbox'; break; case 'select': $type = 'select'; $opts['values'] = $form->getOptionValueList($form->fields[$field]); break; case 'array': $type = 'list'; $value = (array) $value; $value_default = (array) $value_default; break; case 'group': // :group:end is changed to :group:end:{unique id} in Form class $htmlOutput = ''; if (mb_substr($field, 7, 4) != 'end:') { $htmlOutput .= PMA_displayGroupHeader(mb_substr($field, 7)); } else { PMA_displayGroupFooter(); } return $htmlOutput; case 'NULL': trigger_error("Field {$system_path} has no type", E_USER_WARNING); return null; } // detect password fields if ($type === 'text' && mb_substr($translated_path, -9) === '-password') { $type = 'password'; } // TrustedProxies requires changes before displaying if ($system_path == 'TrustedProxies') { foreach ($value as $ip => &$v) { if (!preg_match('/^-\\d+$/', $ip)) { $v = $ip . ': ' . $v; } } } $this->_setComments($system_path, $opts); // send default value to form's JS $js_line = '\'' . $translated_path . '\': '; switch ($type) { case 'text': case 'short_text': case 'number_text': case 'password': $js_line .= '\'' . Sanitize::escapeJsString($value_default) . '\''; break; case 'checkbox': $js_line .= $value_default ? 'true' : 'false'; break; case 'select': $value_default_js = is_bool($value_default) ? (int) $value_default : $value_default; $js_line .= '[\'' . Sanitize::escapeJsString($value_default_js) . '\']'; break; case 'list': $js_line .= '\'' . Sanitize::escapeJsString(implode("\n", $value_default)) . '\''; break; } $js_default[] = $js_line; return PMA_displayInput($translated_path, $name, $type, $value, $description, $value_is_default, $opts); }
} $response = Response::getInstance(); $header = $response->getHeader(); $scripts = $header->getScripts(); $scripts->addFile('config.js'); require 'libraries/user_preferences.inc.php'; if ($error) { if (!$error instanceof Message) { $error = Message::error($error); } $error->display(); } ?> <script type="text/javascript"> <?php Sanitize::printJsValue("PMA_messages['strSavedOn']", __('Saved on: @DATE@')); ?> </script> <div id="maincontainer"> <div id="main_pane_left"> <div class="group"> <?php echo '<h2>', __('Import'), '</h2>', '<form class="group-cnt prefs-form disableAjax" name="prefs_import"', ' action="prefs_manage.php" method="post" enctype="multipart/form-data">', Util::generateHiddenMaxFileSize($GLOBALS['max_upload_size']), URL::getHiddenInputs(), '<input type="hidden" name="json" value="" />', '<input type="radio" id="import_text_file" name="import_type"', ' value="text_file" checked="checked" />', '<label for="import_text_file">' . __('Import from file') . '</label>', '<div id="opts_import_text_file" class="prefsmanage_opts">', '<label for="input_import_file">', __('Browse your computer:'), '</label>', '<input type="file" name="import_file" id="input_import_file" />', '</div>', '<input type="radio" id="import_local_storage" name="import_type"', ' value="local_storage" disabled="disabled" />', '<label for="import_local_storage">', __('Import from browser\'s storage'), '</label>', '<div id="opts_import_local_storage" class="prefsmanage_opts disabled">', '<div class="localStorage-supported">', __('Settings will be imported from your browser\'s local storage.'), '<br />', '<div class="localStorage-exists">', __('Saved on: @DATE@'), '</div>', '<div class="localStorage-empty">'; Message::notice(__('You have no saved settings!'))->display(); echo '</div>', '</div>', '<div class="localStorage-unsupported">'; Message::notice(__('This feature is not supported by your web browser'))->display(); echo '</div>', '</div>', '<input type="checkbox" id="import_merge" name="import_merge" />', '<label for="import_merge">', __('Merge with current configuration') . '</label>', '<br /><br />', '<input type="submit" name="submit_import" value="', __('Go') . '" />', '</form>', '</div>'; if (file_exists('setup/index.php')) { // show only if setup script is available, allows to disable this message // by simply removing setup directory ?>