Merge branch 'QA_4_6'
This commit is contained in:
commit
7fc28626fd
@ -64,6 +64,9 @@ phpMyAdmin - ChangeLog
|
||||
- issue #12320 Copying a user does not copy usergroup
|
||||
- issue #12272 Adding a new row with default enum goes to no selection when you want to add more then 2 rows
|
||||
- issue #12487 Drag and drop import prevents file dropping to blob column file selector on the insert tab
|
||||
- issue #12554 Absence of scrolling makes it impossible to read longer text values in grid editing
|
||||
- issue #12530 "Edit routine" crashes when the current user is not the definer, even if privileges are adequate
|
||||
- issue #12300 Export selective tables by-default dumps Events also
|
||||
|
||||
4.6.4 (2016-08-16)
|
||||
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
|
||||
|
||||
17
js/export.js
17
js/export.js
@ -545,6 +545,16 @@ function toggle_table_select(row) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleAddProcCheckbox() {
|
||||
if ($('#table_structure_all').is(':checked') === true
|
||||
&& $('#table_data_all').is(':checked') === true
|
||||
) {
|
||||
$('#checkbox_sql_procedure_function').prop('checked', true);
|
||||
} else {
|
||||
$('#checkbox_sql_procedure_function').prop('checked', false);
|
||||
}
|
||||
}
|
||||
|
||||
AJAX.registerOnload('export.js', function () {
|
||||
/**
|
||||
* For SQL plugin, if "CREATE TABLE options" is checked/unchecked, check/uncheck each of its sub-options
|
||||
@ -584,26 +594,31 @@ AJAX.registerOnload('export.js', function () {
|
||||
$('input[name="table_select[]"]').on('change', function() {
|
||||
toggle_table_select($(this).closest('tr'));
|
||||
check_table_select_all();
|
||||
handleAddProcCheckbox();
|
||||
});
|
||||
|
||||
$('input[name="table_structure[]"]').on('change', function() {
|
||||
check_table_selected($(this).closest('tr'));
|
||||
check_table_select_all();
|
||||
handleAddProcCheckbox();
|
||||
});
|
||||
|
||||
$('input[name="table_data[]"]').on('change', function() {
|
||||
check_table_selected($(this).closest('tr'));
|
||||
check_table_select_all();
|
||||
handleAddProcCheckbox();
|
||||
});
|
||||
|
||||
$('#table_structure_all').on('change', function() {
|
||||
toggle_table_select_all_str();
|
||||
check_selected_tables();
|
||||
handleAddProcCheckbox();
|
||||
});
|
||||
|
||||
$('#table_data_all').on('change', function() {
|
||||
toggle_table_select_all_data();
|
||||
check_selected_tables();
|
||||
handleAddProcCheckbox();
|
||||
});
|
||||
|
||||
if ($("input[name='export_type']").val() == 'database') {
|
||||
@ -810,6 +825,8 @@ AJAX.registerOnload('export.js', function () {
|
||||
toggle_quick_or_custom();
|
||||
toggle_structure_data_opts();
|
||||
toggle_sql_include_comments();
|
||||
check_table_select_all();
|
||||
handleAddProcCheckbox();
|
||||
|
||||
/**
|
||||
* Initially disables the "Dump some row(s)" sub-options
|
||||
|
||||
@ -390,6 +390,8 @@ $js_messages['strDeleting'] = __('Deleting');
|
||||
$js_messages['MissingReturn']
|
||||
= __('The definition of a stored function must contain a RETURN statement!');
|
||||
$js_messages['strExport'] = __('Export');
|
||||
$js_messages['NoExportable']
|
||||
= __('No routine is exportable. Required privileges may be lacking.');
|
||||
|
||||
/* For ENUM/SET editor*/
|
||||
$js_messages['enum_editor'] = __('ENUM/SET editor');
|
||||
|
||||
@ -128,6 +128,11 @@ RTE.COMMON = {
|
||||
var count = export_anchors.length;
|
||||
var returnCount = 0;
|
||||
|
||||
// No routine is exportable (due to privilege issues)
|
||||
if (count === 0) {
|
||||
PMA_ajaxShowMessage(PMA_messages.NoExportable);
|
||||
}
|
||||
|
||||
export_anchors.each(function () {
|
||||
$.get($(this).attr('href'), {'ajax_request': true}, function (data) {
|
||||
returnCount++;
|
||||
@ -149,6 +154,7 @@ RTE.COMMON = {
|
||||
} else {
|
||||
$.get($this.attr('href'), {'ajax_request': true}, showExport);
|
||||
}
|
||||
PMA_ajaxRemoveMessage($msg);
|
||||
|
||||
function showExport(data) {
|
||||
if (data.success === true) {
|
||||
|
||||
@ -1748,10 +1748,11 @@ class DatabaseInterface
|
||||
* @param string $db db name
|
||||
* @param string $which PROCEDURE | FUNCTION | EVENT | VIEW
|
||||
* @param string $name the procedure|function|event|view name
|
||||
* @param object $link MySQL link
|
||||
*
|
||||
* @return string the definition
|
||||
*/
|
||||
public function getDefinition($db, $which, $name)
|
||||
public function getDefinition($db, $which, $name, $link = null)
|
||||
{
|
||||
$returned_field = array(
|
||||
'PROCEDURE' => 'Create Procedure',
|
||||
@ -1762,7 +1763,7 @@ class DatabaseInterface
|
||||
$query = 'SHOW CREATE ' . $which . ' '
|
||||
. Util::backquote($db) . '.'
|
||||
. Util::backquote($name);
|
||||
return($this->fetchValue($query, 0, $returned_field[$which]));
|
||||
return($this->fetchValue($query, 0, $returned_field[$which], $link));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -44,15 +44,16 @@ function PMA_RTE_handleExport($export_data)
|
||||
} else {
|
||||
$_db = htmlspecialchars(PMA\libraries\Util::backquote($db));
|
||||
$message = __('Error in processing request:') . ' '
|
||||
. sprintf(PMA_RTE_getWord('not_found'), $item_name, $_db);
|
||||
$response = Message::error($message);
|
||||
. sprintf(PMA_RTE_getWord('no_view'), $item_name, $_db);
|
||||
$message = Message::error($message);
|
||||
|
||||
if ($GLOBALS['is_ajax_request'] == true) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->setRequestStatus(false);
|
||||
$response->addJSON('message', $message);
|
||||
exit;
|
||||
} else {
|
||||
$response->display();
|
||||
$message->display();
|
||||
}
|
||||
}
|
||||
} // end PMA_RTE_handleExport()
|
||||
@ -70,6 +71,9 @@ function PMA_EVN_handleExport()
|
||||
if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) {
|
||||
$item_name = $_GET['item_name'];
|
||||
$export_data = $GLOBALS['dbi']->getDefinition($db, 'EVENT', $item_name);
|
||||
if (! $export_data) {
|
||||
$export_data = false;
|
||||
}
|
||||
PMA_RTE_handleExport($export_data);
|
||||
}
|
||||
} // end PMA_EVN_handleExport()
|
||||
@ -89,13 +93,20 @@ function PMA_RTN_handleExport()
|
||||
&& ! empty($_GET['item_type'])
|
||||
) {
|
||||
if ($_GET['item_type'] == 'FUNCTION' || $_GET['item_type'] == 'PROCEDURE') {
|
||||
$export_data = "DELIMITER $$\n"
|
||||
. $GLOBALS['dbi']->getDefinition(
|
||||
$rtn_definition
|
||||
= $GLOBALS['dbi']->getDefinition(
|
||||
$db,
|
||||
$_GET['item_type'],
|
||||
$_GET['item_name']
|
||||
)
|
||||
. "$$\nDELIMITER ;\n";
|
||||
);
|
||||
if (! $rtn_definition) {
|
||||
$export_data = false;
|
||||
} else {
|
||||
$export_data = "DELIMITER $$\n"
|
||||
. $rtn_definition
|
||||
. "$$\nDELIMITER ;\n";
|
||||
}
|
||||
|
||||
PMA_RTE_handleExport($export_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,9 +204,24 @@ function PMA_RTN_getRowForList($routine, $rowclass = '')
|
||||
$retval .= " </strong>\n";
|
||||
$retval .= " </td>\n";
|
||||
$retval .= " <td>\n";
|
||||
|
||||
// this is for our purpose to decide whether to
|
||||
// show the edit link or not, so we need the DEFINER for the routine
|
||||
$where = "ROUTINE_SCHEMA " . PMA\libraries\Util::getCollateForIS() . "="
|
||||
. "'" . PMA\libraries\Util::sqlAddSlashes($db) . "' "
|
||||
. "AND SPECIFIC_NAME='" . PMA\libraries\Util::sqlAddSlashes($routine['name']) . "'"
|
||||
. "AND ROUTINE_TYPE='" . PMA\libraries\Util::sqlAddSlashes($routine['type']) . "'";
|
||||
$query = "SELECT `DEFINER` FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;";
|
||||
$routine_definer = $GLOBALS['dbi']->fetchValue($query, 0, 0, $GLOBALS['controllink']);
|
||||
|
||||
$curr_user = $GLOBALS['dbi']->getCurrentUser();
|
||||
|
||||
// Since editing a procedure involved dropping and recreating, check also for
|
||||
// CREATE ROUTINE privilege to avoid lost procedures.
|
||||
if (PMA\libraries\Util::currentUserHasPrivilege('CREATE ROUTINE', $db)) {
|
||||
if ((PMA\libraries\Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
|
||||
&& $curr_user == $routine_definer)
|
||||
|| $GLOBALS['is_superuser']
|
||||
) {
|
||||
$retval .= ' <a ' . $ajax_class['edit']
|
||||
. ' href="db_routines.php'
|
||||
. $url_query
|
||||
@ -233,7 +248,7 @@ function PMA_RTN_getRowForList($routine, $rowclass = '')
|
||||
// otherwise we can execute it directly.
|
||||
|
||||
$definition = $GLOBALS['dbi']->getDefinition(
|
||||
$db, $routine['type'], $routine['name']
|
||||
$db, $routine['type'], $routine['name'], $GLOBALS['controllink']
|
||||
);
|
||||
if ($definition !== false) {
|
||||
$parser = new SqlParser\Parser($definition);
|
||||
@ -271,14 +286,21 @@ function PMA_RTN_getRowForList($routine, $rowclass = '')
|
||||
|
||||
$retval .= " </td>\n";
|
||||
$retval .= " <td>\n";
|
||||
$retval .= ' <a ' . $ajax_class['export']
|
||||
. ' href="db_routines.php'
|
||||
. $url_query
|
||||
. '&export_item=1'
|
||||
. '&item_name='
|
||||
. urlencode($routine['name'])
|
||||
. '&' . $type_link
|
||||
. '">' . $titles['Export'] . "</a>\n";
|
||||
if ((PMA\libraries\Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
|
||||
&& $curr_user == $routine_definer)
|
||||
|| $GLOBALS['is_superuser']
|
||||
) {
|
||||
$retval .= ' <a ' . $ajax_class['export']
|
||||
. ' href="db_routines.php'
|
||||
. $url_query
|
||||
. '&export_item=1'
|
||||
. '&item_name='
|
||||
. urlencode($routine['name'])
|
||||
. '&' . $type_link
|
||||
. '">' . $titles['Export'] . "</a>\n";
|
||||
} else {
|
||||
$retval .= " {$titles['NoExport']}\n";
|
||||
}
|
||||
$retval .= " </td>\n";
|
||||
$retval .= " <td>\n";
|
||||
$retval .= ' <a ' . $ajax_class['drop']
|
||||
|
||||
@ -157,12 +157,13 @@ function PMA_RTN_handleEditor()
|
||||
} else {
|
||||
$message = __('Error in processing request:') . ' ';
|
||||
$message .= sprintf(
|
||||
PMA_RTE_getWord('not_found'),
|
||||
PMA_RTE_getWord('no_edit'),
|
||||
htmlspecialchars(
|
||||
PMA\libraries\Util::backquote($_REQUEST['item_name'])
|
||||
),
|
||||
htmlspecialchars(PMA\libraries\Util::backquote($db))
|
||||
);
|
||||
|
||||
$message = Message::error($message);
|
||||
if ($GLOBALS['is_ajax_request']) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
@ -564,16 +565,23 @@ function PMA_RTN_getDataFromRequest()
|
||||
* This function will generate the values that are required to complete
|
||||
* the "Edit routine" form given the name of a routine.
|
||||
*
|
||||
* @param string $name The name of the routine.
|
||||
* @param string $type Type of routine (ROUTINE|PROCEDURE)
|
||||
* @param bool $all Whether to return all data or just
|
||||
* the info about parameters.
|
||||
* @param string $name The name of the routine.
|
||||
* @param string $type Type of routine (ROUTINE|PROCEDURE)
|
||||
* @param bool $all Whether to return all data or just
|
||||
* the info about parameters.
|
||||
* @param bool $control Where to use Controllink to query for
|
||||
* routine information
|
||||
*
|
||||
* @return array Data necessary to create the routine editor.
|
||||
*/
|
||||
function PMA_RTN_getDataFromName($name, $type, $all = true)
|
||||
function PMA_RTN_getDataFromName($name, $type, $all = true, $control = false)
|
||||
{
|
||||
global $db;
|
||||
$link = null;
|
||||
|
||||
if ($control) {
|
||||
$link = $GLOBALS['controllink'];
|
||||
}
|
||||
|
||||
$retval = array();
|
||||
|
||||
@ -587,7 +595,7 @@ function PMA_RTN_getDataFromName($name, $type, $all = true)
|
||||
. "AND ROUTINE_TYPE='" . PMA\libraries\Util::sqlAddSlashes($type) . "'";
|
||||
$query = "SELECT $fields FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;";
|
||||
|
||||
$routine = $GLOBALS['dbi']->fetchSingleRow($query);
|
||||
$routine = $GLOBALS['dbi']->fetchSingleRow($query, 'ASSOC', $link);
|
||||
|
||||
if (! $routine) {
|
||||
return false;
|
||||
@ -597,13 +605,19 @@ function PMA_RTN_getDataFromName($name, $type, $all = true)
|
||||
$retval['item_name'] = $routine['SPECIFIC_NAME'];
|
||||
$retval['item_type'] = $routine['ROUTINE_TYPE'];
|
||||
|
||||
$parser = new SqlParser\Parser(
|
||||
$GLOBALS['dbi']->getDefinition(
|
||||
$definition
|
||||
= $GLOBALS['dbi']->getDefinition(
|
||||
$db,
|
||||
$routine['ROUTINE_TYPE'],
|
||||
$routine['SPECIFIC_NAME']
|
||||
)
|
||||
);
|
||||
$routine['SPECIFIC_NAME'],
|
||||
$link
|
||||
);
|
||||
|
||||
if ($definition == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parser = new SqlParser\Parser($definition);
|
||||
|
||||
/**
|
||||
* @var CreateStatement $stmt
|
||||
@ -1283,7 +1297,7 @@ function PMA_RTN_handleExecute()
|
||||
if (! empty($_REQUEST['execute_routine']) && ! empty($_REQUEST['item_name'])) {
|
||||
// Build the queries
|
||||
$routine = PMA_RTN_getDataFromName(
|
||||
$_REQUEST['item_name'], $_REQUEST['item_type'], false
|
||||
$_REQUEST['item_name'], $_REQUEST['item_type'], false, true
|
||||
);
|
||||
if ($routine === false) {
|
||||
$message = __('Error in processing request:') . ' ';
|
||||
@ -1481,7 +1495,7 @@ function PMA_RTN_handleExecute()
|
||||
* Display the execute form for a routine.
|
||||
*/
|
||||
$routine = PMA_RTN_getDataFromName(
|
||||
$_GET['item_name'], $_GET['item_type'], true
|
||||
$_GET['item_name'], $_GET['item_type'], true, true
|
||||
);
|
||||
if ($routine !== false) {
|
||||
$form = PMA_RTN_getExecuteForm($routine);
|
||||
|
||||
@ -31,6 +31,14 @@ function PMA_RTE_getWord($index)
|
||||
'no_create' => __(
|
||||
'You do not have the necessary privileges to create a routine'
|
||||
),
|
||||
'no_edit' => __(
|
||||
'No routine with name %1$s found in database %2$s. '
|
||||
. 'You might be lacking the necessary privileges to edit this routine'
|
||||
),
|
||||
'no_view' => __(
|
||||
'No routine with name %1$s found in database %2$s. '
|
||||
. 'You might be lacking the necessary privileges to view/export this routine'
|
||||
),
|
||||
'not_found' => __('No routine with name %1$s found in database %2$s'),
|
||||
'nothing' => __('There are no routines to display.'),
|
||||
'title' => __('Routines'),
|
||||
|
||||
@ -2325,7 +2325,8 @@ fieldset .disabled-field td {
|
||||
}
|
||||
|
||||
.cEdit .edit_box {
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
@ -2875,7 +2875,8 @@ fieldset .disabled-field td {
|
||||
}
|
||||
|
||||
.cEdit .edit_box {
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user