From f18e06171009bdb1be99f7cfa4b2c859be08a9c9 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sun, 15 Dec 2013 07:39:35 -0500 Subject: [PATCH 1/5] Bug #4023 Requires wildcard EXECUTE/ALTER ROUTINE on DB to allow Procedures to be executed by user Signed-off-by: Marc Delisle --- ChangeLog | 2 ++ libraries/rte/rte_list.lib.php | 65 ++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4ee3f45d9..95fc12bb4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,8 @@ phpMyAdmin - ChangeLog - bug #4149 Js freezes in the management of replication - bug #3903 Query fails when using aliases after ordering result - bug #4181 Adding columns in table creation clears existing columns +- bug #4023 Requires wildcard EXECUTE/ALTER ROUTINE on DB to allow +Procedures to be executed by user 4.1.0.0 (2013-12-11) + rfe #499 On user creation, warn if the user already exists diff --git a/libraries/rte/rte_list.lib.php b/libraries/rte/rte_list.lib.php index 30d0a56595..7cc0c1c6d3 100644 --- a/libraries/rte/rte_list.lib.php +++ b/libraries/rte/rte_list.lib.php @@ -164,40 +164,43 @@ function PMA_RTN_getRowForList($routine, $rowclass = '') } $retval .= " \n"; $retval .= " \n"; - if ($routine['ROUTINE_DEFINITION'] !== null - && PMA_Util::currentUserHasPrivilege('EXECUTE', $db) - ) { - // Check if he routine has any input parameters. If it does, - // we will show a dialog to get values for these parameters, - // otherwise we can execute it directly. - $routine_details = PMA_RTN_getDataFromName( - $routine['SPECIFIC_NAME'], - $routine['ROUTINE_TYPE'], - false - ); - if ($routine !== false) { - $execute_action = 'execute_routine'; - for ($i=0; $i<$routine_details['item_num_params']; $i++) { - if ($routine_details['item_type'] == 'PROCEDURE' - && $routine_details['item_param_dir'][$i] == 'OUT' - ) { - continue; - } - $execute_action = 'execute_dialog'; - break; + + // There is a problem with PMA_Util::currentUserHasPrivilege(): + // it does not detect all kinds of privileges, for example + // a direct privilege on a specific routine. So, at this point, + // we show the Execute link, hoping that the user has the correct rights. + // Also, information_schema might be hiding the ROUTINE_DEFINITION + // but a routine with no input parameters can be nonetheless executed. + + // Check if he routine has any input parameters. If it does, + // we will show a dialog to get values for these parameters, + // otherwise we can execute it directly. + $routine_details = PMA_RTN_getDataFromName( + $routine['SPECIFIC_NAME'], + $routine['ROUTINE_TYPE'], + false + ); + if ($routine !== false) { + $execute_action = 'execute_routine'; + for ($i=0; $i<$routine_details['item_num_params']; $i++) { + if ($routine_details['item_type'] == 'PROCEDURE' + && $routine_details['item_param_dir'][$i] == 'OUT' + ) { + continue; } - $retval .= ' ' . $titles['Execute'] . "\n"; + $execute_action = 'execute_dialog'; + break; } - } else { - $retval .= " {$titles['NoExecute']}\n"; + $retval .= ' ' . $titles['Execute'] . "\n"; } + $retval .= " \n"; $retval .= " \n"; $retval .= ' Date: Sun, 15 Dec 2013 18:24:20 +0100 Subject: [PATCH 2/5] PHPCS update. Signed-off-by: Hugues Peccatte --- libraries/StorageEngine.class.php | 3 ++- libraries/import.lib.php | 12 ++++++--- libraries/replication_gui.lib.php | 42 +++++++++++++++++-------------- libraries/select_lang.lib.php | 10 +++++--- setup/lib/form_processing.lib.php | 2 +- user_password.php | 6 ++--- 6 files changed, 45 insertions(+), 30 deletions(-) diff --git a/libraries/StorageEngine.class.php b/libraries/StorageEngine.class.php index 5e535a0473..729f19684d 100644 --- a/libraries/StorageEngine.class.php +++ b/libraries/StorageEngine.class.php @@ -262,7 +262,8 @@ class PMA_StorageEngine $res = $GLOBALS['dbi']->query($sql_query); while ($row = $GLOBALS['dbi']->fetchAssoc($res)) { if (isset($variables[$row['Variable_name']])) { - $mysql_vars[$row['Variable_name']] = $variables[$row['Variable_name']]; + $mysql_vars[$row['Variable_name']] + = $variables[$row['Variable_name']]; } elseif (! $like && strpos(strtolower($row['Variable_name']), strtolower($this->engine)) !== 0 ) { diff --git a/libraries/import.lib.php b/libraries/import.lib.php index b57124236a..7e0584f300 100644 --- a/libraries/import.lib.php +++ b/libraries/import.lib.php @@ -111,9 +111,12 @@ function PMA_importRunQuery($sql = '', $full = '', $controluser = false, if (! $sql_query_disabled) { $sql_query .= $import_run_buffer['full']; } + + $pattern = '@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?' + . 'DATABASE @i'; if (! $cfg['AllowUserDropDatabase'] && ! $is_superuser - && preg_match('@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql']) + && preg_match($pattern, $import_run_buffer['sql']) ) { $GLOBALS['message'] = PMA_Message::error(__('"DROP DATABASE" statements are disabled.')); $error = true; @@ -121,12 +124,13 @@ function PMA_importRunQuery($sql = '', $full = '', $controluser = false, $executed_queries++; + $pattern = '/^[\s]*(SELECT|SHOW|HANDLER)/i'; if ($run_query && $GLOBALS['finished'] && empty($sql) && ! $error && ((! empty($import_run_buffer['sql']) - && preg_match('/^[\s]*(SELECT|SHOW|HANDLER)/i', $import_run_buffer['sql'])) + && preg_match($pattern, $import_run_buffer['sql'])) || ($executed_queries == 1)) ) { $go_sql = true; @@ -219,8 +223,10 @@ function PMA_importRunQuery($sql = '', $full = '', $controluser = false, ); } + $pattern = '@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)' + . '?(TABLE|DATABASE)[[:space:]]+(.+)@im'; if ($result != false - && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql']) + && preg_match($pattern, $import_run_buffer['sql']) ) { $reload = true; } diff --git a/libraries/replication_gui.lib.php b/libraries/replication_gui.lib.php index 4f06afbe3e..0a558af3fe 100644 --- a/libraries/replication_gui.lib.php +++ b/libraries/replication_gui.lib.php @@ -1,7 +1,7 @@ isSuccess($result); $response->addJSON( 'message', - $result ? PMA_Message::success($messageSuccess) : PMA_Message::error($messageError) + $result + ? PMA_Message::success($messageSuccess) + : PMA_Message::error($messageError) ); } else { PMA_sendHeaderLocation( @@ -1060,7 +1062,9 @@ function PMA_handleRequestForSlaveSkipError() } $qStop = PMA_Replication_Slave_control("STOP"); - $qSkip = $GLOBALS['dbi']->tryQuery("SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ".$count.";"); + $qSkip = $GLOBALS['dbi']->tryQuery( + "SET GLOBAL SQL_SLAVE_SKIP_COUNTER = ".$count.";" + ); $qStart = PMA_Replication_Slave_control("START"); $result = ($qStop !== false && $qStop !== -1 && diff --git a/libraries/select_lang.lib.php b/libraries/select_lang.lib.php index ce0dcd93b4..c8e0095bb8 100644 --- a/libraries/select_lang.lib.php +++ b/libraries/select_lang.lib.php @@ -156,8 +156,11 @@ function PMA_langDetect($str, $envType) if (strpos($expr, '[-_]') === false) { $expr = str_replace('|', '([-_][[:alpha:]]{2,3})?|', $expr); } - if (($envType == 1 && preg_match('/^(' . addcslashes($expr, '/') . ')(;q=[0-9]\\.[0-9])?$/i', $str)) - || ($envType == 2 && preg_match('/(\(|\[|;[[:space:]])(' . addcslashes($expr, '/') . ')(;|\]|\))/i', $str)) + $pattern1 = '/^(' . addcslashes($expr, '/') . ')(;q=[0-9]\\.[0-9])?$/i'; + $pattern2 = '/(\(|\[|;[[:space:]])(' . addcslashes($expr, '/') + . ')(;|\]|\))/i'; + if (($envType == 1 && preg_match($pattern1, $str)) + || ($envType == 2 && preg_match($pattern2, $str)) ) { if (PMA_langSet($lang)) { return true; @@ -430,9 +433,10 @@ function PMA_langList() /* Process all files */ while (false !== ($file = readdir($handle))) { + $path = $GLOBALS['lang_path'] . '/' . $file . '/LC_MESSAGES/phpmyadmin.mo'; if ($file != "." && $file != ".." - && file_exists($GLOBALS['lang_path'] . '/' . $file . '/LC_MESSAGES/phpmyadmin.mo') + && file_exists($path) ) { $result[$file] = PMA_langDetails($file); } diff --git a/setup/lib/form_processing.lib.php b/setup/lib/form_processing.lib.php index 9ca3b5317a..74b53e96a0 100644 --- a/setup/lib/form_processing.lib.php +++ b/setup/lib/form_processing.lib.php @@ -9,7 +9,7 @@ /** * Processes forms registered in $form_display, handles error correction * - * @param FormDisplay $form_display + * @param FormDisplay $form_display Form * * @return void */ diff --git a/user_password.php b/user_password.php index d74885fcba..00792db443 100644 --- a/user_password.php +++ b/user_password.php @@ -222,9 +222,9 @@ function PMA_changePassAuthType($_url_params, $password) /** * Display the page * - * @param string $message Message - * @param string $sql_query SQL query - * @param array $_url_params Parameters of URL + * @param string $message Message + * @param string $sql_query SQL query + * @param array $_url_params Parameters of URL * * @return void */ From cc58ebe7d1ba52fd42f8cbe66df5a407aee5cf86 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sun, 15 Dec 2013 13:29:49 -0500 Subject: [PATCH 3/5] bug #4186 Adding a column when creating a table does not propagate index info Signed-off-by: Marc Delisle --- ChangeLog | 1 + libraries/tbl_columns_definition_form.lib.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 95fc12bb4d..82532cf069 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ phpMyAdmin - ChangeLog - bug #4181 Adding columns in table creation clears existing columns - bug #4023 Requires wildcard EXECUTE/ALTER ROUTINE on DB to allow Procedures to be executed by user +- bug #4186 Adding a column when creating a table does not propagate index info 4.1.0.0 (2013-12-11) + rfe #499 On user creation, warn if the user already exists diff --git a/libraries/tbl_columns_definition_form.lib.php b/libraries/tbl_columns_definition_form.lib.php index 746290e8fd..b598be7bf0 100644 --- a/libraries/tbl_columns_definition_form.lib.php +++ b/libraries/tbl_columns_definition_form.lib.php @@ -378,7 +378,7 @@ function PMA_getRowDataForRegeneration($columnNumber, $submit_fulltext) $columnMeta['Key'] = ''; if (isset($_REQUEST['field_key'][$columnNumber])) { - $parts = explode($_REQUEST['field_key'][$columnNumber], '_', 2); + $parts = explode('_', $_REQUEST['field_key'][$columnNumber], 2); if (count($parts) == 2 && $parts[1] == $columnNumber) { switch ($parts[0]) { case 'primary': From 887cd2b6e967494df8c0f6ad8d75925da24cd3c2 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sun, 15 Dec 2013 13:43:08 -0500 Subject: [PATCH 4/5] Fix test Signed-off-by: Marc Delisle --- test/libraries/PMA_tbl_columns_definition_form_test.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/libraries/PMA_tbl_columns_definition_form_test.php b/test/libraries/PMA_tbl_columns_definition_form_test.php index 7ad9802f38..1550549e91 100644 --- a/test/libraries/PMA_tbl_columns_definition_form_test.php +++ b/test/libraries/PMA_tbl_columns_definition_form_test.php @@ -408,7 +408,7 @@ class PMA_TblColumnsDefinitionFormTest extends PHPUnit_Framework_TestCase { $_REQUEST = array( 'field_name' => array(1 => 'name'), - 'field_type' => array(0 => 'type'), + 'field_type' => array(1 => 'type'), 'field_collation' => array(1 => 'colltn'), 'field_null' => array(1 => true), 'field_key' => array(1 => "fulltext_1"), @@ -424,10 +424,10 @@ class PMA_TblColumnsDefinitionFormTest extends PHPUnit_Framework_TestCase $this->assertEquals( array( 'Field' => 'name', - 'Type' => '', + 'Type' => 'type', 'Collation' => 'colltn', - 'Null' => '1', - 'Key' => '', + 'Null' => true, + 'Key' => 'FULLTEXT', 'DefaultType' => 'USER_DEFINED', 'DefaultValue' => 'DEF', 'Default' => 'DEF', From 6d101aa0252971104f3107b9ef44cc43299ca782 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sun, 15 Dec 2013 14:12:35 -0500 Subject: [PATCH 5/5] Fix typo Signed-off-by: Marc Delisle --- libraries/Error_Handler.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Error_Handler.class.php b/libraries/Error_Handler.class.php index ebb6fa103a..7cd6442a22 100644 --- a/libraries/Error_Handler.class.php +++ b/libraries/Error_Handler.class.php @@ -165,7 +165,7 @@ class PMA_Error_Handler case E_CORE_ERROR: case E_COMPILE_ERROR: default: - // FATAL error, dislay it and exit + // FATAL error, display it and exit $this->dispFatalError($error); exit; break;