bug #2893221 [core] Statement may not be safe to log in statement format

This commit is contained in:
Marc Delisle
2009-11-21 13:22:08 +00:00
parent 58d880b6ab
commit 182c02c5e8
7 changed files with 52 additions and 33 deletions

View File

@@ -58,6 +58,7 @@ $HeadURL: https://phpmyadmin.svn.sourceforge.net/svnroot/phpmyadmin/trunk/phpMyA
- bug #2823599 [edit] UUID Primary Key wrongly updated
- bug #2895894 [structure] Empty default value not set properly
- bug #2897536 [parser] Copying table with bit field with default
- bug #2893221 [core] Statement may not be safe to log in statement format
3.2.3.0 (2009-10-30)
- patch #2856664 [export] Date, time, and datetime column types now export correctly to

View File

@@ -1925,7 +1925,7 @@ function PMA_checkParameters($params, $die = true, $request = true)
*
* @access public
* @author Michal Cihar (michal@cihar.com) and others...
* @return string calculated condition
* @return string the calculated condition and whether condition is unique
*/
function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force_unique=false)
{
@@ -2023,15 +2023,18 @@ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force
// Correction University of Virginia 19991216:
// prefer primary or unique keys for condition,
// but use conjunction of all values if no primary key
$clause_is_unique = true;
if ($primary_key) {
$preferred_condition = $primary_key;
} elseif ($unique_key) {
$preferred_condition = $unique_key;
} elseif (! $force_unique) {
$preferred_condition = $nonprimary_condition;
$clause_is_unique = false;
}
return trim(preg_replace('|\s?AND$|', '', $preferred_condition));
$where_clause = trim(preg_replace('|\s?AND$|', '', $preferred_condition));
return(array($where_clause, $clause_is_unique));
} // end function
/**

View File

@@ -442,7 +442,7 @@ onsubmit="return (checkFormElementInRange(this, 'session_max_rows', '<?php echo
* @param integer the total number of fields returned by the SQL query
* @param array the analyzed query
*
* @return boolean always true
* @return boolean $clause_is_unique
*
* @global string $db the database name
* @global string $table the table name
@@ -1076,14 +1076,14 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
// 1. Prepares the row (gets primary keys to use)
// 1.1 Results from a "SELECT" statement -> builds the
// "primary" key to use in links
// WHERE clause to use in links (a unique key if possible)
/**
* @todo $unique_condition could be empty, for example a table
* @todo $where_clause could be empty, for example a table
* with only one field and it's a BLOB; in this case,
* avoid to display the delete and edit links
*/
$unique_condition = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row);
$unique_condition_html = urlencode($unique_condition);
list($where_clause, $clause_is_unique) = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row);
$where_clause_html = urlencode($where_clause);
// 1.2 Defines the URLs for the modify/delete link(s)
@@ -1099,11 +1099,12 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
// 1.2.1 Modify link(s)
if ($is_display['edit_lnk'] == 'ur') { // update row case
$_url_params = array(
'db' => $db,
'table' => $table,
'primary_key' => $unique_condition,
'sql_query' => $url_sql_query,
'goto' => 'sql.php',
'db' => $db,
'table' => $table,
'primary_key' => $where_clause,
'clause_is_unique' => $clause_is_unique,
'sql_query' => $url_sql_query,
'goto' => 'sql.php',
);
$edit_url = 'tbl_change.php' . PMA_generate_common_url($_url_params);
@@ -1141,7 +1142,7 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
$lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text');
$del_query = 'DELETE FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table)
. ' WHERE ' . $unique_condition . ' LIMIT 1';
. ' WHERE ' . $where_clause . ($clause_is_unique ? '' : ' LIMIT 1');
$_url_params = array(
'db' => $db,
@@ -1153,8 +1154,8 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
$del_url = 'sql.php' . PMA_generate_common_url($_url_params);
$js_conf = 'DELETE FROM ' . PMA_jsFormat($db) . '.' . PMA_jsFormat($table)
. ' WHERE ' . PMA_jsFormat($unique_condition, false)
. ' LIMIT 1';
. ' WHERE ' . PMA_jsFormat($where_clause, false)
. ($clause_is_unique ? '' : ' LIMIT 1');
$del_str = PMA_getIcon('b_drop.png', $GLOBALS['strDelete'], true);
} elseif ($is_display['del_lnk'] == 'kp') { // kill process case
@@ -1238,7 +1239,7 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
$_url_params = array(
'db' => $db,
'table' => $table,
'primary_key' => $unique_condition,
'primary_key' => $where_clause,
'transform_key' => $meta->name,
);
@@ -1441,7 +1442,7 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
if (!empty($del_url) && $is_display['del_lnk'] != 'kp') {
$vertical_display['row_delete'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n"
. ' <input type="checkbox" id="id_rows_to_delete' . $row_no . '[%_PMA_CHECKBOX_DIR_%]" name="rows_to_delete[' . $unique_condition_html . ']"'
. ' <input type="checkbox" id="id_rows_to_delete' . $row_no . '[%_PMA_CHECKBOX_DIR_%]" name="rows_to_delete[' . $where_clause_html . ']"'
. ' onclick="' . $column_marker_vertical . 'copyCheckboxesRange(\'rowsDeleteForm\', \'id_rows_to_delete' . $row_no . '\',\'[%_PMA_CHECKBOX_DIR_%]\');"'
. ' value="' . htmlspecialchars($del_query) . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />' . "\n"
. ' </td>' . "\n";
@@ -1470,7 +1471,9 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
$row_no++;
} // end while
return true;
// this is needed by PMA_displayTable() to generate the proper param
// in the multi-edit and multi-delete form
return $clause_is_unique;
} // end of the 'PMA_displayTableBody()' function
@@ -2012,7 +2015,7 @@ function PMA_displayTable(&$dt_result, &$the_disp_mode, $analyzed_sql)
PMA_displayTableHeaders($is_display, $fields_meta, $fields_cnt, $analyzed_sql, $sort_expression, $sort_expression_nodirection, $sort_direction);
$url_query = '';
echo '<tbody>' . "\n";
PMA_displayTableBody($dt_result, $is_display, $map, $analyzed_sql);
$clause_is_unique = PMA_displayTableBody($dt_result, $is_display, $map, $analyzed_sql);
// vertical output case
if ($_SESSION['tmp_user_values']['disp_direction'] == 'vertical') {
PMA_displayVerticalTable();
@@ -2023,7 +2026,7 @@ function PMA_displayTable(&$dt_result, &$the_disp_mode, $analyzed_sql)
</table>
<?php
// 4. ----- Displays the link for multi-fields delete
// 4. ----- Displays the link for multi-fields edit and delete
if ($is_display['del_lnk'] == 'dr' && $is_display['del_lnk'] != 'kp') {
@@ -2074,6 +2077,10 @@ function PMA_displayTable(&$dt_result, &$the_disp_mode, $analyzed_sql)
.' value="' . htmlspecialchars($sql_query) . '" />' . "\n";
echo '<input type="hidden" name="url_query"'
.' value="' . $GLOBALS['url_query'] . '" />' . "\n";
echo '<input type="hidden" name="clause_is_unique"'
.' value="' . $clause_is_unique . '" />' . "\n";
echo '</form>' . "\n";
}

View File

@@ -21,7 +21,7 @@ if ($doWriteModifyAt == 'left') {
if (!empty($del_url) && $is_display['del_lnk'] != 'kp') {
echo ' <td align="center">' . "\n"
. ' <input type="checkbox" id="id_rows_to_delete' . $row_no . '" name="rows_to_delete[' . $unique_condition_html . ']"'
. ' <input type="checkbox" id="id_rows_to_delete' . $row_no . '" name="rows_to_delete[' . $where_clause_html . ']"'
. ' onclick="copyCheckboxesRange(\'rowsDeleteForm\', \'id_rows_to_delete' . $row_no . '\',\'l\');"'
. ' value="' . htmlspecialchars($del_query) . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />' . "\n"
. ' </td>' . "\n";
@@ -51,7 +51,7 @@ if ($doWriteModifyAt == 'left') {
}
if (!empty($del_url) && $is_display['del_lnk'] != 'kp') {
echo ' <td align="center">' . "\n"
. ' <input type="checkbox" id="id_rows_to_delete' . $row_no . 'r" name="rows_to_delete[' . $unique_condition_html . ']"'
. ' <input type="checkbox" id="id_rows_to_delete' . $row_no . 'r" name="rows_to_delete[' . $where_clause_html . ']"'
. ' onclick="copyCheckboxesRange(\'rowsDeleteForm\', \'id_rows_to_delete' . $row_no . '\',\'r\');"'
. ' value="' . htmlspecialchars($del_query) . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />' . "\n"
. ' </td>' . "\n";

View File

@@ -1004,7 +1004,9 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
$insert_line .= $field_set[$i] . ' = ' . $values[$i];
}
$insert_line .= ' WHERE ' . PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $row);
list($tmp_unique_condition, $tmp_clause_is_unique) = PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $row);
$insert_line .= ' WHERE ' . $tmp_unique_condition;
unset($tmp_unique_condition, $tmp_clause_is_unique);
} else {

View File

@@ -19,7 +19,6 @@ require_once './libraries/common.inc.php';
*/
require_once './libraries/db_table_exists.lib.php';
/**
* Sets global variables.
* Here it's better to use a if, instead of the '?' operator
@@ -32,6 +31,9 @@ require_once './libraries/db_table_exists.lib.php';
if (isset($_REQUEST['primary_key'])) {
$primary_key = $_REQUEST['primary_key'];
}
if (isset($_REQUEST['clause_is_unique'])) {
$clause_is_unique = $_REQUEST['clause_is_unique'];
}
if (isset($_SESSION['edit_next'])) {
$primary_key = $_SESSION['edit_next'];
unset($_SESSION['edit_next']);
@@ -177,16 +179,17 @@ if (isset($primary_key)) {
PMA_showMessage($strEmptyResultSet, $local_query);
echo "\n";
require_once './libraries/footer.inc.php';
} else { // end if (no record returned)
} else { // end if (no row returned)
$meta = PMA_DBI_get_fields_meta($result[$key_id]);
if ($tmp = PMA_getUniqueCondition($result[$key_id], count($meta), $meta, $rows[$key_id], true)) {
list($unique_condition, $tmp_clause_is_unique) = PMA_getUniqueCondition($result[$key_id], count($meta), $meta, $rows[$key_id], true);
if (! empty($unique_condition)) {
$found_unique_key = true;
}
unset($tmp);
unset($unique_condition, $tmp_clause_is_unique);
}
}
} else {
// no primary key given, just load first row - but what happens if tbale is empty?
// no primary key given, just load first row - but what happens if table is empty?
$insert_mode = true;
$result = PMA_DBI_query('SELECT * FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . ' LIMIT 1;', null, PMA_DBI_QUERY_STORE);
$rows = array_fill(0, $cfg['InsertRows'], false);
@@ -233,6 +236,9 @@ if (isset($primary_keys)) {
$_form_params['primary_key[' . $key_id . ']'] = trim($primary_key);
}
}
if (isset($clause_is_unique)) {
$_form_params['clause_is_unique'] = $clause_is_unique;
}
?>
<!-- Insert/Edit form -->

View File

@@ -95,11 +95,11 @@ if (isset($_REQUEST['after_insert'])
$meta = PMA_DBI_get_fields_meta($res);
// must find a unique condition based on unique key,
// not a combination of all fields
// (the following is a real assignment)
if ($tmp = PMA_getUniqueCondition($res, count($meta), $meta, $row, true)) {
$_SESSION['edit_next'] = $tmp;
list($unique_condition, $clause_is_unique) = PMA_getUniqueCondition($res, count($meta), $meta, $row, true);
if (! empty($unique_condition)) {
$_SESSION['edit_next'] = $unique_condition;
}
unset($tmp);
unset($unique_condition, $clause_is_unique);
}
}
}
@@ -298,7 +298,7 @@ foreach ($loop_array as $rowcount => $primary_key) {
} else {
// build update query
$query[] = 'UPDATE ' . PMA_backquote($GLOBALS['db']) . '.' . PMA_backquote($GLOBALS['table'])
. ' SET ' . implode(', ', $query_values) . ' WHERE ' . $primary_key . ' LIMIT 1';
. ' SET ' . implode(', ', $query_values) . ' WHERE ' . $primary_key . ($_REQUEST['clause_is_unique'] ? '' : ' LIMIT 1');
}
}