diff --git a/.gitignore b/.gitignore
index 6841414751..52a98f192f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
# Upload/save dirs
/upload/
/save/
+/tmp/
# For setup script
/config/
# ctags
@@ -22,8 +23,9 @@ phpmyadmin.wpj
.idea
.netbeans
*.sw[op]
-# IIS files
+# Web server files
web.config
+.htaccess
# Locales
/locale/
# Backups
diff --git a/ChangeLog b/ChangeLog
index 843ed25048..5e2f3532e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,13 @@ phpMyAdmin - ChangeLog
- issue #12485 Do not show warning about short blowfish_secret if none is set
- issue #12251 Fixed random logouts due to wrong cookie path
- issue #12480 Fixed editing of ENUM/SET/DECIMAL fields structure
+- issue #12497 Missing escaping of configuration used in SQL (hide_db and only_db)
+- issue #12476 Add error checking in reading advisory rules file
+- issue #12477 Add checking missing elements and confirming element types from json_decode
+- issue #12251 Automatically save SQL query in browser local storage rather than in cookie
+- issue #12292 Unable to edit transformations
+- issue #12502 Remove unused paramenter when connecting to MySQLi
+- issue #12303 Fix number formatting with different settings of precision in PHP
4.6.4 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
diff --git a/js/functions.js b/js/functions.js
index 0304126695..bace1bf56d 100644
--- a/js/functions.js
+++ b/js/functions.js
@@ -1164,7 +1164,9 @@ function insertQuery(queryType)
}
return;
} else if (queryType == "saved") {
- if ($.cookie('auto_saved_sql')) {
+ if (isStorageSupported('localStorage') && typeof window.localStorage.auto_saved_sql != 'undefined') {
+ setQuery(window.localStorage.auto_saved_sql);
+ } else if ($.cookie('auto_saved_sql')) {
setQuery($.cookie('auto_saved_sql'));
} else {
PMA_ajaxShowMessage(PMA_messages.strNoAutoSavedQuery);
diff --git a/js/sql.js b/js/sql.js
index 8a8ee57320..c379420d31 100644
--- a/js/sql.js
+++ b/js/sql.js
@@ -36,6 +36,23 @@ function PMA_urlencode(str)
}
}
+/**
+ * Saves SQL query in local storage or cooie
+ *
+ * @param string SQL query
+ * @return void
+ */
+function PMA_autosaveSQL(query)
+{
+ if (query) {
+ if (isStorageSupported('localStorage')) {
+ window.localStorage.auto_saved_sql = query;
+ } else {
+ $.cookie('auto_saved_sql', query);
+ }
+ }
+}
+
/**
* Get the field name for the current field. Required to construct the query
* for grid editing
@@ -135,17 +152,11 @@ AJAX.registerOnload('sql.js', function () {
$(function () {
if (codemirror_editor) {
codemirror_editor.on('change', function () {
- var query = codemirror_editor.getValue();
- if (query) {
- $.cookie('auto_saved_sql', query);
- }
+ PMA_autosaveSQL(codemirror_editor.getValue());
});
} else {
$('#sqlquery').on('input propertychange', function () {
- var query = $('#sqlquery').val();
- if (query) {
- $.cookie('auto_saved_sql', query);
- }
+ PMA_autosaveSQL($('#sqlquery').val());
});
}
});
diff --git a/libraries/Advisor.php b/libraries/Advisor.php
index 59742b2f6c..cfe4fa65e5 100644
--- a/libraries/Advisor.php
+++ b/libraries/Advisor.php
@@ -455,10 +455,20 @@ class Advisor
*/
public static function parseRulesFile()
{
- $file = file('libraries/advisory_rules.txt', FILE_IGNORE_NEW_LINES);
+ $filename = 'libraries/advisory_rules.txt';
+ $file = file($filename, FILE_IGNORE_NEW_LINES);
+
$errors = array();
$rules = array();
$lines = array();
+
+ if ($file === FALSE) {
+ $errors[] = __(
+ 'Error in reading file: The file \'' . $filename .'\' does not exist or is not readable'
+ );
+ return array('rules' => $rules, 'lines' => $lines, 'errors' => $errors);
+ }
+
$ruleSyntax = array(
'name', 'formula', 'test', 'issue', 'recommendation', 'justification'
);
diff --git a/libraries/Linter.php b/libraries/Linter.php
index 422141e615..ed53ce2187 100644
--- a/libraries/Linter.php
+++ b/libraries/Linter.php
@@ -51,7 +51,7 @@ class Linter
// (which is actually a new line) aren't going to be processed at
// all.
$len = ($str instanceof UtfString) ?
- $str->length() : strlen($len);
+ $str->length() : strlen($str);
$lines = array(0);
for ($i = 0; $i < $len; ++$i) {
diff --git a/libraries/Util.php b/libraries/Util.php
index 7b65f5a770..5e2a4a3c5b 100644
--- a/libraries/Util.php
+++ b/libraries/Util.php
@@ -1604,17 +1604,13 @@ class Util
$value = round($value / (self::pow(1000, $d, 'pow') / $dh)) /$dh;
$unit = $units[$d];
- // If we don't want any zeros after the comma just add the thousand separator
- if ($noTrailingZero) {
- $localizedValue = self::localizeNumber(
- preg_replace('/(?<=\d)(?=(\d{3})+(?!\d))/', ',', $value)
- );
- } else {
- //number_format is not multibyte safe, str_replace is safe
- $localizedValue = self::localizeNumber(
- number_format($value, $digits_right)
- );
+ // number_format is not multibyte safe, str_replace is safe
+ $formattedValue = number_format($value, $digits_right);
+ // If we don't want any zeros, remove them now
+ if ($noTrailingZero && strpos($formattedValue, '.') !== false) {
+ $formattedValue = preg_replace('/\.?0+$/', '', $formattedValue);
}
+ $localizedValue = self::localizeNumber($formattedValue);
if ($originalValue != 0 && floatval($value) == 0) {
return ' <' . self::localizeNumber((1 / self::pow(10, $digits_right)))
@@ -4672,7 +4668,7 @@ class Util
->render(
array(
'pos' => $pos,
- 'unlim_num_rows' => $_REQUEST['unlim_num_rows'],
+ 'unlim_num_rows' => intval($_REQUEST['unlim_num_rows']),
'rows' => $rows,
'sql_query' => $sql_query,
)
diff --git a/libraries/common.inc.php b/libraries/common.inc.php
index 9ec0fc32cd..0a04b5e618 100644
--- a/libraries/common.inc.php
+++ b/libraries/common.inc.php
@@ -107,6 +107,13 @@ PMA_checkExtensions();
ini_set('default_charset', 'utf-8');
mb_internal_encoding('utf-8');
+/**
+ * Set precision to sane value, with higher values
+ * things behave slightly unexpectedly, for example
+ * round(1.2, 2) returns 1.199999999999999956.
+ */
+ini_set('precision', 14);
+
/**
* the relation lib, tracker needs it
*/
@@ -455,9 +462,15 @@ PMA_setGlobalDbOrTable('table');
*/
if (PMA_isValid($_REQUEST['selected_recent_table'])) {
$recent_table = json_decode($_REQUEST['selected_recent_table'], true);
- $GLOBALS['db'] = $recent_table['db'];
+
+ $GLOBALS['db']
+ = (array_key_exists('db', $recent_table) && is_string($recent_table['db'])) ?
+ $recent_table['db'] : '';
$GLOBALS['url_params']['db'] = $GLOBALS['db'];
- $GLOBALS['table'] = $recent_table['table'];
+
+ $GLOBALS['table']
+ = (array_key_exists('table', $recent_table) && is_string($recent_table['table'])) ?
+ $recent_table['table'] : '';
$GLOBALS['url_params']['table'] = $GLOBALS['table'];
}
diff --git a/libraries/dbi/DBIMysqli.php b/libraries/dbi/DBIMysqli.php
index 0b98c85218..f310d9c85b 100644
--- a/libraries/dbi/DBIMysqli.php
+++ b/libraries/dbi/DBIMysqli.php
@@ -64,7 +64,6 @@ class DBIMysqli implements DBIExtension
* @param string $host mysql hostname
* @param string $user mysql user name
* @param string $password mysql user password
- * @param string $dbname database name
* @param int $server_port server port
* @param string $server_socket server socket
* @param int $client_flags client flags of connection
@@ -73,7 +72,7 @@ class DBIMysqli implements DBIExtension
* @return bool
*/
private function _realConnect(
- $link, $host, $user, $password, $dbname, $server_port,
+ $link, $host, $user, $password, $server_port,
$server_socket, $client_flags = null, $persistent = false
) {
global $cfg;
@@ -89,7 +88,7 @@ class DBIMysqli implements DBIExtension
$host,
$user,
$password,
- $dbname,
+ '',
$server_port,
$server_socket
);
@@ -99,7 +98,7 @@ class DBIMysqli implements DBIExtension
$host,
$user,
$password,
- $dbname,
+ '',
$server_port,
$server_socket,
$client_flags
@@ -185,7 +184,6 @@ class DBIMysqli implements DBIExtension
$cfg['Server']['host'],
$user,
$password,
- false,
$server_port,
$server_socket,
$client_flags
@@ -201,7 +199,6 @@ class DBIMysqli implements DBIExtension
$cfg['Server']['host'],
$user,
'',
- false,
$server_port,
$server_socket,
$client_flags
@@ -213,7 +210,6 @@ class DBIMysqli implements DBIExtension
$server['host'],
$user,
$password,
- false,
$server_port,
$server_socket
);
diff --git a/libraries/navigation/nodes/Node.php b/libraries/navigation/nodes/Node.php
index 0e186c6498..de6b1d2d62 100644
--- a/libraries/navigation/nodes/Node.php
+++ b/libraries/navigation/nodes/Node.php
@@ -721,7 +721,9 @@ class Node
if (!empty($GLOBALS['cfg']['Server']['hide_db'])) {
$whereClause .= "AND " . Util::backquote($columnName)
- . " NOT REGEXP '" . $GLOBALS['cfg']['Server']['hide_db'] . "' ";
+ . " NOT REGEXP '"
+ . Util::sqlAddSlashes($GLOBALS['cfg']['Server']['hide_db'], true)
+ . "' ";
}
if (!empty($GLOBALS['cfg']['Server']['only_db'])) {
@@ -735,7 +737,7 @@ class Node
foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) {
$subClauses[] = " " . Util::backquote($columnName)
. " LIKE '"
- . $each_only_db . "' ";
+ . Util::sqlAddSlashes($each_only_db, true) . "' ";
}
$whereClause .= implode("OR", $subClauses) . ") ";
}
diff --git a/libraries/sanitizing.lib.php b/libraries/sanitizing.lib.php
index c906eeee9e..4591bf3da2 100644
--- a/libraries/sanitizing.lib.php
+++ b/libraries/sanitizing.lib.php
@@ -166,7 +166,7 @@ function PMA_sanitize($message, $escape = false, $safe = false)
'[sup]' => '',
'[/sup]' => '',
// used in common.inc.php:
- '[conferr]' => '',
+ '[conferr]' => '',
// used in libraries/Util.php
'[dochelpicon]' => PMA\libraries\Util::getImage('b_help.png', __('Documentation')),
);
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 983d9e5522..5d0df4e01c 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -4,8 +4,8 @@ msgstr ""
"Project-Id-Version: phpMyAdmin 4.6.5-dev\n"
"Report-Msgid-Bugs-To: translators@phpmyadmin.net\n"
"POT-Creation-Date: 2016-08-17 11:29+0200\n"
-"PO-Revision-Date: 2016-08-22 02:16+0000\n"
-"Last-Translator: Lucius Gaitán \n"
+"PO-Revision-Date: 2016-08-29 00:24+0000\n"
+"Last-Translator: Diego Bemquerer Castro \n"
"Language-Team: Portuguese (Brazil) "
"\n"
"Language: pt_BR\n"
@@ -3694,8 +3694,9 @@ msgid "Unknown error in file upload."
msgstr "Erro desconhecido no carregamento do arquivo."
#: libraries/File.php:424
+#, fuzzy
msgid "File is a symbolic link"
-msgstr ""
+msgstr "O arquivo é um link simbólico"
#: libraries/File.php:470
msgid "Error moving the uploaded file, see [doc@faq1-11]FAQ 1.11[/doc]."
diff --git a/templates/columns_definitions/transformation_option.phtml b/templates/columns_definitions/transformation_option.phtml
index 91d97ca1a0..bb19e3f0b9 100644
--- a/templates/columns_definitions/transformation_option.phtml
+++ b/templates/columns_definitions/transformation_option.phtml
@@ -5,5 +5,5 @@
size="16"
class="textfield"
value="= (isset($columnMeta['Field']) && isset($mime_map[$columnMeta['Field']][$options_key])) ?
- htmlspecialchars($mime_map[$columnMeta['Field']], [$options_key])
- : '' ?>" />
\ No newline at end of file
+ htmlspecialchars($mime_map[$columnMeta['Field']][$options_key])
+ : '' ?>" />
diff --git a/test/bootstrap-dist.php b/test/bootstrap-dist.php
index 1b2e45059f..0188e49b05 100644
--- a/test/bootstrap-dist.php
+++ b/test/bootstrap-dist.php
@@ -6,6 +6,13 @@
* @package PhpMyAdmin-test
*/
+/**
+ * Set precision to sane value, with higher values
+ * things behave slightly unexpectedly, for example
+ * round(1.2, 2) returns 1.199999999999999956.
+ */
+ini_set('precision', 14);
+
// Let PHP complain about all errors
error_reporting(E_ALL);
diff --git a/test/libraries/common/PMA_formatNumberByteDown_test.php b/test/libraries/common/PMA_formatNumberByteDown_test.php
index 138db8c49d..604e59b3e3 100644
--- a/test/libraries/common/PMA_formatNumberByteDown_test.php
+++ b/test/libraries/common/PMA_formatNumberByteDown_test.php
@@ -70,6 +70,30 @@ class PMA_FormatNumberByteDown_Test extends PHPUnit_Framework_TestCase
array(0.003, 3, 3, '3 m'),
array(-0.003, 6, 0, '-3,000 µ'),
array(100.98, 0, 2, '100.98'),
+ array(21010101, 0, 2, '21,010,101.00'),
+ array(20000, 2, 2, '20 k'),
+ array(20011, 2, 2, '20.01 k'),
+ );
+ }
+
+ /**
+ * Core test for formatNumber
+ *
+ *
+ * @param float $a Value to format
+ * @param int $b Sensitiveness
+ * @param int $c Number of decimals to retain
+ * @param array $d Expected value
+ *
+ * @return void
+ */
+ private function assertFormatNumber($a, $b, $c, $d)
+ {
+ $this->assertEquals(
+ $d,
+ (string) PMA\libraries\Util::formatNumber(
+ $a, $b, $c, false
+ )
);
}
@@ -87,12 +111,21 @@ class PMA_FormatNumberByteDown_Test extends PHPUnit_Framework_TestCase
*/
public function testFormatNumber($a, $b, $c, $d)
{
- $this->assertEquals(
- $d,
- (string) PMA\libraries\Util::formatNumber(
- $a, $b, $c, false
- )
- );
+ $this->assertFormatNumber($a, $b, $c, $d);
+
+ // Test with various precisions
+ $old_precision = ini_get('precision');
+ ini_set('precision', 20);
+ $this->assertFormatNumber($a, $b, $c, $d);
+ ini_set('precision', 14);
+ $this->assertFormatNumber($a, $b, $c, $d);
+ ini_set('precision', 10);
+ $this->assertFormatNumber($a, $b, $c, $d);
+ ini_set('precision', 5);
+ $this->assertFormatNumber($a, $b, $c, $d);
+ ini_set('precision', -1);
+ $this->assertFormatNumber($a, $b, $c, $d);
+ ini_set('precision', $old_precision);
}
/**