bug #2868328 [relations] Adding foreign key when table name contains a dot
This commit is contained in:
@@ -16,6 +16,7 @@ $HeadURL: https://phpmyadmin.svn.sourceforge.net/svnroot/phpmyadmin/trunk/phpMyA
|
|||||||
- bug #2872247 [interface] Failed opening required 'mysql_charsets.lib.php', thanks to CyberLeo Kitsana - cyberleo
|
- bug #2872247 [interface] Failed opening required 'mysql_charsets.lib.php', thanks to CyberLeo Kitsana - cyberleo
|
||||||
- bug [structure] "In use" table incorrectly reported as "view"
|
- bug [structure] "In use" table incorrectly reported as "view"
|
||||||
- bug #2879909 [interface] Removed double htmlspecialchars when editing enum column
|
- bug #2879909 [interface] Removed double htmlspecialchars when editing enum column
|
||||||
|
- bug #2868328 [relations] Adding foreign key when table name contains a dot
|
||||||
|
|
||||||
3.2.2.1 (2009-10-12)
|
3.2.2.1 (2009-10-12)
|
||||||
- [security] XSS and SQL injection, thanks to Herman van Rink
|
- [security] XSS and SQL injection, thanks to Herman van Rink
|
||||||
|
@@ -98,9 +98,9 @@ class PMA_Table
|
|||||||
* @param boolean whether to quote name with backticks ``
|
* @param boolean whether to quote name with backticks ``
|
||||||
* @return string table name
|
* @return string table name
|
||||||
*/
|
*/
|
||||||
function getName($quoted = false)
|
function getName($backquoted = false)
|
||||||
{
|
{
|
||||||
if ($quoted) {
|
if ($backquoted) {
|
||||||
return PMA_backquote($this->name);
|
return PMA_backquote($this->name);
|
||||||
}
|
}
|
||||||
return $this->name;
|
return $this->name;
|
||||||
@@ -124,9 +124,9 @@ class PMA_Table
|
|||||||
* @param boolean whether to quote name with backticks ``
|
* @param boolean whether to quote name with backticks ``
|
||||||
* @return string database name for this table
|
* @return string database name for this table
|
||||||
*/
|
*/
|
||||||
function getDbName($quoted = false)
|
function getDbName($backquoted = false)
|
||||||
{
|
{
|
||||||
if ($quoted) {
|
if ($backquoted) {
|
||||||
return PMA_backquote($this->db_name);
|
return PMA_backquote($this->db_name);
|
||||||
}
|
}
|
||||||
return $this->db_name;
|
return $this->db_name;
|
||||||
@@ -137,9 +137,9 @@ class PMA_Table
|
|||||||
*
|
*
|
||||||
* @param boolean whether to quote name with backticks ``
|
* @param boolean whether to quote name with backticks ``
|
||||||
*/
|
*/
|
||||||
function getFullName($quoted = false)
|
function getFullName($backquoted = false)
|
||||||
{
|
{
|
||||||
return $this->getDbName($quoted) . '.' . $this->getName($quoted);
|
return $this->getDbName($backquoted) . '.' . $this->getName($backquoted);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function isView($db = null, $table = null)
|
static public function isView($db = null, $table = null)
|
||||||
@@ -1122,7 +1122,7 @@ class PMA_Table
|
|||||||
* @param boolean whether to quote name with backticks ``
|
* @param boolean whether to quote name with backticks ``
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getUniqueColumns($quoted = true)
|
public function getUniqueColumns($backquoted = true)
|
||||||
{
|
{
|
||||||
$sql = 'SHOW INDEX FROM ' . $this->getFullName(true) . ' WHERE Non_unique = 0';
|
$sql = 'SHOW INDEX FROM ' . $this->getFullName(true) . ' WHERE Non_unique = 0';
|
||||||
$uniques = PMA_DBI_fetch_result($sql, array('Key_name', null), 'Column_name');
|
$uniques = PMA_DBI_fetch_result($sql, array('Key_name', null), 'Column_name');
|
||||||
@@ -1132,7 +1132,7 @@ class PMA_Table
|
|||||||
if (count($index) > 1) {
|
if (count($index) > 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$return[] = $this->getFullName($quoted) . '.' . ($quoted ? PMA_backquote($index[0]) : $index[0]);
|
$return[] = $this->getFullName($backquoted) . '.' . ($backquoted ? PMA_backquote($index[0]) : $index[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
@@ -1148,14 +1148,14 @@ class PMA_Table
|
|||||||
* @param boolean whether to quote name with backticks ``
|
* @param boolean whether to quote name with backticks ``
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getIndexedColumns($quoted = true)
|
public function getIndexedColumns($backquoted = true)
|
||||||
{
|
{
|
||||||
$sql = 'SHOW INDEX FROM ' . $this->getFullName(true) . ' WHERE Seq_in_index = 1';
|
$sql = 'SHOW INDEX FROM ' . $this->getFullName(true) . ' WHERE Seq_in_index = 1';
|
||||||
$indexed = PMA_DBI_fetch_result($sql, 'Column_name', 'Column_name');
|
$indexed = PMA_DBI_fetch_result($sql, 'Column_name', 'Column_name');
|
||||||
|
|
||||||
$return = array();
|
$return = array();
|
||||||
foreach ($indexed as $column) {
|
foreach ($indexed as $column) {
|
||||||
$return[] = $this->getFullName($quoted) . '.' . ($quoted ? PMA_backquote($column) : $column);
|
$return[] = $this->getFullName($backquoted) . '.' . ($backquoted ? PMA_backquote($column) : $column);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* includes phpMyAdmin relations and InnoDB relations
|
* includes phpMyAdmin relations and InnoDB relations
|
||||||
*
|
*
|
||||||
* @todo fix name handling: currently names with dots (.) are not properly handled
|
* @todo fix name handling: currently names with dots (.) are not properly handled for internal relations (but foreign keys relations are correct)
|
||||||
* @todo foreign key constraints require both fields being of equal type and size
|
* @todo foreign key constraints require both fields being of equal type and size
|
||||||
* @todo check foreign fields to be from same type and size, all other makes no sense
|
* @todo check foreign fields to be from same type and size, all other makes no sense
|
||||||
* @todo add an link to create an index required for constraints, or an option to do automatically
|
* @todo add an link to create an index required for constraints, or an option to do automatically
|
||||||
@@ -73,6 +73,36 @@ function PMA_generate_dropdown($dropdown_question, $select_name, $choices, $sele
|
|||||||
echo '</select>' . "\n";
|
echo '</select>' . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a string on backquote pairs
|
||||||
|
*
|
||||||
|
* @param string original string
|
||||||
|
* @return array containing the elements (and their surrounding backquotes)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function PMA_backquote_split($text)
|
||||||
|
{
|
||||||
|
$elements = array();
|
||||||
|
$final_pos = strlen($text) - 1;
|
||||||
|
$pos = 0;
|
||||||
|
while ($pos <= $final_pos) {
|
||||||
|
$first_backquote = strpos($text, '`', $pos);
|
||||||
|
$second_backquote = strpos($text, '`', $first_backquote + 1);
|
||||||
|
// after the second one, there might be another one which means
|
||||||
|
// this is an escaped backquote
|
||||||
|
if ($second_backquote < $final_pos && '`' == $text[$second_backquote + 1]) {
|
||||||
|
$second_backquote = strpos($text, '`', $second_backquote + 2);
|
||||||
|
}
|
||||||
|
if (false === $first_backquote || false === $second_backquote) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$elements[] = substr($text, $first_backquote, $second_backquote - $first_backquote + 1);
|
||||||
|
$pos = $second_backquote + 1;
|
||||||
|
}
|
||||||
|
return($elements);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the relation settings
|
* Gets the relation settings
|
||||||
*/
|
*/
|
||||||
@@ -157,9 +187,7 @@ if (isset($_REQUEST['destination_foreign'])) {
|
|||||||
$master_field = $me_fields_name[$master_field_md5];
|
$master_field = $me_fields_name[$master_field_md5];
|
||||||
|
|
||||||
if (! empty($foreign_string)) {
|
if (! empty($foreign_string)) {
|
||||||
$foreign_string = trim($foreign_string, '`');
|
list($foreign_db, $foreign_table, $foreign_field) = PMA_backquote_split($foreign_string);
|
||||||
list($foreign_db, $foreign_table, $foreign_field) =
|
|
||||||
explode('.', $foreign_string);
|
|
||||||
if (!isset($existrel_foreign[$master_field])) {
|
if (!isset($existrel_foreign[$master_field])) {
|
||||||
// no key defined for this field
|
// no key defined for this field
|
||||||
|
|
||||||
@@ -173,9 +201,9 @@ if (isset($_REQUEST['destination_foreign'])) {
|
|||||||
. ' ADD FOREIGN KEY ('
|
. ' ADD FOREIGN KEY ('
|
||||||
. PMA_backquote($master_field) . ')'
|
. PMA_backquote($master_field) . ')'
|
||||||
. ' REFERENCES '
|
. ' REFERENCES '
|
||||||
. PMA_backquote($foreign_db) . '.'
|
. $foreign_db . '.'
|
||||||
. PMA_backquote($foreign_table) . '('
|
. $foreign_table . '('
|
||||||
. PMA_backquote($foreign_field) . ')';
|
. $foreign_field . ')';
|
||||||
|
|
||||||
if (! empty($_REQUEST['on_delete'][$master_field_md5])) {
|
if (! empty($_REQUEST['on_delete'][$master_field_md5])) {
|
||||||
$sql_query .= ' ON DELETE ' . $options_array[$_REQUEST['on_delete'][$master_field_md5]];
|
$sql_query .= ' ON DELETE ' . $options_array[$_REQUEST['on_delete'][$master_field_md5]];
|
||||||
@@ -187,7 +215,9 @@ if (isset($_REQUEST['destination_foreign'])) {
|
|||||||
$display_query .= $sql_query . "\n";
|
$display_query .= $sql_query . "\n";
|
||||||
// end repeated code
|
// end repeated code
|
||||||
|
|
||||||
} elseif (($existrel_foreign[$master_field]['foreign_db'] . '.' .$existrel_foreign[$master_field]['foreign_table'] . '.' . $existrel_foreign[$master_field]['foreign_field'] != $foreign_string)
|
} elseif (PMA_backquote($existrel_foreign[$master_field]['foreign_db']) != $foreign_db
|
||||||
|
|| PMA_backquote($existrel_foreign[$master_field]['foreign_table']) != $foreign_table
|
||||||
|
|| PMA_backquote($existrel_foreign[$master_field]['foreign_field']) != $foreign_field
|
||||||
|| ($_REQUEST['on_delete'][$master_field_md5] != (!empty($existrel_foreign[$master_field]['on_delete']) ? $existrel_foreign[$master_field]['on_delete'] : ''))
|
|| ($_REQUEST['on_delete'][$master_field_md5] != (!empty($existrel_foreign[$master_field]['on_delete']) ? $existrel_foreign[$master_field]['on_delete'] : ''))
|
||||||
|| ($_REQUEST['on_update'][$master_field_md5] != (!empty($existrel_foreign[$master_field]['on_update']) ? $existrel_foreign[$master_field]['on_update'] : ''))
|
|| ($_REQUEST['on_update'][$master_field_md5] != (!empty($existrel_foreign[$master_field]['on_update']) ? $existrel_foreign[$master_field]['on_update'] : ''))
|
||||||
) {
|
) {
|
||||||
@@ -209,9 +239,9 @@ if (isset($_REQUEST['destination_foreign'])) {
|
|||||||
. ' ADD FOREIGN KEY ('
|
. ' ADD FOREIGN KEY ('
|
||||||
. PMA_backquote($master_field) . ')'
|
. PMA_backquote($master_field) . ')'
|
||||||
. ' REFERENCES '
|
. ' REFERENCES '
|
||||||
. PMA_backquote($foreign_db) . '.'
|
. $foreign_db . '.'
|
||||||
. PMA_backquote($foreign_table) . '('
|
. $foreign_table . '('
|
||||||
. PMA_backquote($foreign_field) . ')';
|
. $foreign_field . ')';
|
||||||
|
|
||||||
if (! empty($_REQUEST['on_delete'][$master_field_md5])) {
|
if (! empty($_REQUEST['on_delete'][$master_field_md5])) {
|
||||||
$sql_query .= ' ON DELETE '
|
$sql_query .= ' ON DELETE '
|
||||||
@@ -340,15 +370,15 @@ if ($cfgRelation['relwork'] || PMA_foreignkey_supported($tbl_type)) {
|
|||||||
$current_table = new PMA_Table($curr_table[0], $db);
|
$current_table = new PMA_Table($curr_table[0], $db);
|
||||||
|
|
||||||
// explicitely ask for non-quoted list of indexed columns
|
// explicitely ask for non-quoted list of indexed columns
|
||||||
$selectboxall = array_merge($selectboxall, $current_table->getUniqueColumns(false));
|
$selectboxall = array_merge($selectboxall, $current_table->getUniqueColumns($backquoted = false));
|
||||||
|
|
||||||
// if foreign keys are supported, collect all keys from other
|
// if foreign keys are supported, collect all keys from other
|
||||||
// tables of the same engine
|
// tables of the same engine
|
||||||
if (PMA_foreignkey_supported($tbl_type)
|
if (PMA_foreignkey_supported($tbl_type)
|
||||||
&& isset($curr_table[1])
|
&& isset($curr_table[1])
|
||||||
&& strtoupper($curr_table[1]) == $tbl_type) {
|
&& strtoupper($curr_table[1]) == $tbl_type) {
|
||||||
// explicitely ask for non-quoted list of indexed columns
|
// need to obtain backquoted values to support dots inside values
|
||||||
$selectboxall_foreign = array_merge($selectboxall_foreign, $current_table->getIndexedColumns(false));
|
$selectboxall_foreign = array_merge($selectboxall_foreign, $current_table->getIndexedColumns($backquoted = true));
|
||||||
}
|
}
|
||||||
} // end while over tables
|
} // end while over tables
|
||||||
} // end if
|
} // end if
|
||||||
@@ -443,9 +473,11 @@ if ($col_rs && PMA_DBI_num_rows($col_rs) > 0) {
|
|||||||
<select name="destination_foreign[<?php echo $myfield_md5; ?>]">
|
<select name="destination_foreign[<?php echo $myfield_md5; ?>]">
|
||||||
<?php
|
<?php
|
||||||
if (isset($existrel_foreign[$myfield])) {
|
if (isset($existrel_foreign[$myfield])) {
|
||||||
$foreign_field = $existrel_foreign[$myfield]['foreign_db'] . '.'
|
// need to backquote to support a dot character inside
|
||||||
. $existrel_foreign[$myfield]['foreign_table'] . '.'
|
// an element
|
||||||
. $existrel_foreign[$myfield]['foreign_field'];
|
$foreign_field = PMA_backquote($existrel_foreign[$myfield]['foreign_db']) . '.'
|
||||||
|
. PMA_backquote($existrel_foreign[$myfield]['foreign_table']) . '.'
|
||||||
|
. PMA_backquote($existrel_foreign[$myfield]['foreign_field']);
|
||||||
} else {
|
} else {
|
||||||
$foreign_field = FALSE;
|
$foreign_field = FALSE;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user