diff --git a/ChangeLog b/ChangeLog index 82c0d3e43b..61093ae3e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -76,6 +76,7 @@ explanation - bug #4788 Inline edit of DATE fields with NULL, NULL checkbox is under datepicker - bug #4790 DROP TABLE/VIEW IF EXISTS are not tracked - bug Compatibility with central columns of version 4.4 +- bug #4758 Firefox with auth_type to http with multiple server doesn't work anymore 4.3.11.1 (2015-03-04) - bug [security] Risk of BREACH attack, see PMASA-2015-1 diff --git a/db_central_columns.php b/db_central_columns.php index 696319df2f..453326dd39 100644 --- a/db_central_columns.php +++ b/db_central_columns.php @@ -117,26 +117,6 @@ $result = PMA_getColumnsList($db, $pos, $max_rows); $odd_row = false; $row_num=0; foreach ($result as $row) { - $vals = explode(',', $row['col_extra']); - - if (in_array('BINARY', $vals)) { - $row['col_attribute'] = 'BINARY'; - } elseif (in_array('UNSIGNED', $vals)) { - $row['col_attribute'] = 'UNSIGNED'; - } elseif (in_array('UNSIGNED ZEROFILL', $vals)) { - $row['col_attribute'] = 'UNSIGNED ZEROFILL'; - } elseif (in_array('on update CURRENT_TIMESTAMP', $vals)) { - $row['col_attribute'] = 'on update CURRENT_TIMESTAMP'; - } else { - $row['col_attribute'] = ''; - } - - if (in_array('auto_increment', $vals)) { - $row['col_extra'] = 'auto_increment'; - } else { - $row['col_extra'] = ''; - } - $tableHtmlRow = PMA_getHTMLforCentralColumnsTableRow( $row, $odd_row, $row_num, $db ); diff --git a/js/makegrid.js b/js/makegrid.js index 80c65df6ec..7999b98789 100644 --- a/js/makegrid.js +++ b/js/makegrid.js @@ -1033,11 +1033,13 @@ function PMA_makegrid(t, enableResize, enableReorder, enableVisib, enableGridEdi $input_field.datepicker("show"); - var datepicker_top = parseInt(document.getElementById("ui-datepicker-div").style.getPropertyValue("top"), 10); + //move ui-datepicker-div inside cEdit div + var datepicker_div = $('#ui-datepicker-div'); + datepicker_div.css({'top': 0, 'left': 0, 'position': 'relative'}); + $('.cEdit').append(datepicker_div); - if (datepicker_top > 370 && !is_null) { - document.getElementById("ui-datepicker-div").style.marginTop = "30px"; - } + var edit_area_top = $('#ui-datepicker-div').height()+32; + $('.edit_area').css({'top' : edit_area_top+'px', 'position': 'absolute'}); if (is_null){ $(g.cEdit).find('.edit_area').hide(); diff --git a/libraries/central_columns.lib.php b/libraries/central_columns.lib.php index eed0813816..f400e95182 100644 --- a/libraries/central_columns.lib.php +++ b/libraries/central_columns.lib.php @@ -66,12 +66,13 @@ function PMA_getColumnsList($db, $from=0, $num=25) . 'WHERE db_name = \'' . $db . '\';'; } else { $query = 'SELECT * FROM ' . PMA_Util::backquote($central_list_table) . ' ' - . 'WHERE db_name = \'' . $db . '\'' + . 'WHERE db_name = \'' . $db . '\' ' . 'LIMIT ' . $from . ', ' . $num . ';'; } $has_list = (array) $GLOBALS['dbi']->fetchResult( $query, null, null, $GLOBALS['controllink'] ); + PMA_handleColumnExtra($has_list); return $has_list; } @@ -94,7 +95,9 @@ function PMA_getCentralColumnsCount($db) $query = 'SELECT count(db_name) FROM ' . PMA_Util::backquote($central_list_table) . ' ' . 'WHERE db_name = \'' . $db . '\';'; - $res = $GLOBALS['dbi']->fetchResult($query); + $res = $GLOBALS['dbi']->fetchResult( + $query, null, null, $GLOBALS['controllink'] + ); if (isset($res[0])) { return $res[0]; } else { @@ -123,14 +126,19 @@ function PMA_findExistingColNames($db, $cols, $allFields=false) if ($allFields) { $query = 'SELECT * FROM ' . PMA_Util::backquote($central_list_table) . ' ' . 'WHERE db_name = \'' . $db . '\' AND col_name IN (' . $cols . ');'; + $has_list = (array) $GLOBALS['dbi']->fetchResult( + $query, null, null, $GLOBALS['controllink'] + ); + PMA_handleColumnExtra($has_list); } else { $query = 'SELECT col_name FROM ' . PMA_Util::backquote($central_list_table) . ' ' . 'WHERE db_name = \'' . $db . '\' AND col_name IN (' . $cols . ');'; + $has_list = (array) $GLOBALS['dbi']->fetchResult( + $query, null, null, $GLOBALS['controllink'] + ); } - $has_list = (array) $GLOBALS['dbi']->fetchResult( - $query, null, null, $GLOBALS['controllink'] - ); + return $has_list; } @@ -414,25 +422,6 @@ function PMA_makeConsistentWithList($db, $selected_tables) $query .= '(' . $column['col_length'] . ')'; } - $vals = explode(',', $column['col_extra']); - if (in_array('BINARY', $vals)) { - $column['col_attribute'] = 'BINARY'; - } elseif (in_array('UNSIGNED', $vals)) { - $column['col_attribute'] = 'UNSIGNED'; - } elseif (in_array('UNSIGNED ZEROFILL', $vals)) { - $column['col_attribute'] = 'UNSIGNED ZEROFILL'; - } elseif (in_array('on update CURRENT_TIMESTAMP', $vals)) { - $column['col_attribute'] = 'on update CURRENT_TIMESTAMP'; - } else { - $column['col_attribute'] = ''; - } - - if (in_array('auto_increment', $vals)) { - $column['col_extra'] = 'auto_increment'; - } else { - $column['col_extra'] = ''; - } - $query .= ' ' . $column['col_attribute']; if ($column['col_isNull']) { $query .= ' NULL'; @@ -907,16 +896,51 @@ function PMA_getCentralColumnsListRaw($db, $table) } $cols = trim($cols, ','); $query = 'SELECT * FROM ' . PMA_Util::backquote($centralTable) . ' ' - . 'WHERE db_name = \'' . $db . '\' ' - . 'AND col_name NOT IN (' . $cols . ');'; + . 'WHERE db_name = \'' . $db . '\''; + if ($cols) { + $query .= ' AND col_name NOT IN (' . $cols . ')'; + } + $query .= ';'; } $GLOBALS['dbi']->selectDb($cfgCentralColumns['db'], $GLOBALS['controllink']); $columns_list = (array)$GLOBALS['dbi']->fetchResult( $query, null, null, $GLOBALS['controllink'] ); + PMA_handleColumnExtra($columns_list); return json_encode($columns_list); } +/** + * Column `col_extra` is used to store both extra and attributes for a column. + * This method separates them. + * + * @param array columns_list columns list + */ +function PMA_handleColumnExtra(&$columns_list) +{ + foreach ($columns_list as &$row) { + $vals = explode(',', $row['col_extra']); + + if (in_array('BINARY', $vals)) { + $row['col_attribute'] = 'BINARY'; + } elseif (in_array('UNSIGNED', $vals)) { + $row['col_attribute'] = 'UNSIGNED'; + } elseif (in_array('UNSIGNED ZEROFILL', $vals)) { + $row['col_attribute'] = 'UNSIGNED ZEROFILL'; + } elseif (in_array('on update CURRENT_TIMESTAMP', $vals)) { + $row['col_attribute'] = 'on update CURRENT_TIMESTAMP'; + } else { + $row['col_attribute'] = ''; + } + + if (in_array('auto_increment', $vals)) { + $row['col_extra'] = 'auto_increment'; + } else { + $row['col_extra'] = ''; + } + } +} + /** * build html for adding a new user defined column to central list * diff --git a/libraries/plugins/auth/AuthenticationHttp.class.php b/libraries/plugins/auth/AuthenticationHttp.class.php index df4f71f8be..ab205e9d70 100644 --- a/libraries/plugins/auth/AuthenticationHttp.class.php +++ b/libraries/plugins/auth/AuthenticationHttp.class.php @@ -22,7 +22,7 @@ require_once 'libraries/plugins/AuthenticationPlugin.class.php'; class AuthenticationHttp extends AuthenticationPlugin { /** - * Displays authentication form + * Displays authentication form and redirect as necessary * * @global string the font face to use in case of failure * @global string the default font size to use in case of failure @@ -44,6 +44,16 @@ class AuthenticationHttp extends AuthenticationPlugin } } + return $this->authForm(); + } + + /** + * Displays authentication form + * + * @return boolean + */ + public function authForm() + { /* Perform logout to custom URL */ if (! empty($_REQUEST['old_usr']) && ! empty($GLOBALS['cfg']['Server']['LogoutURL']) @@ -261,7 +271,7 @@ class AuthenticationHttp extends AuthenticationPlugin if ($error && $GLOBALS['errno'] != 1045) { PMA_fatalError($error); } else { - $this->auth(); + $this->authForm(); return true; } } diff --git a/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php b/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php index 036084c42e..1eb699a302 100644 --- a/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php +++ b/test/classes/plugin/auth/PMA_AuthenticationHttp_test.php @@ -452,12 +452,13 @@ class PMA_AuthenticationHttp_Test extends PHPUnit_Framework_TestCase $this->object = $this->getMockBuilder('AuthenticationHttp') ->disableOriginalConstructor() - ->setMethods(array('auth')) + ->setMethods(array('authForm')) ->getMock(); $this->object->expects($this->exactly(2)) - ->method('auth'); + ->method('authForm'); // case 2 + $GLOBALS['cfg']['Server']['host'] = 'host'; $GLOBALS['errno'] = 1045; $this->assertTrue( diff --git a/test/libraries/PMA_central_columns_test.php b/test/libraries/PMA_central_columns_test.php index 2db153bd7f..6c6a4abc46 100644 --- a/test/libraries/PMA_central_columns_test.php +++ b/test/libraries/PMA_central_columns_test.php @@ -31,6 +31,40 @@ require_once 'libraries/sqlparser.lib.php'; */ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase { + private $_columnData = array( + array( + 'col_name' => "id", "col_type" => 'integer', + 'col_length' => 0, 'col_isNull' => 0, 'col_extra' => 'UNSIGNED,auto_increment', + 'col_default' => 1 + ), + array('col_name' => "col1", 'col_type' => 'varchar', + 'col_length' => 100, 'col_isNull' => 1, 'col_extra' => 'BINARY', + 'col_default' => 1 + ), + array( + 'col_name' => "col2", 'col_type' => 'DATETIME', + 'col_length' => 0, 'col_isNull' => 1, 'col_extra' => 'on update CURRENT_TIMESTAMP', + 'col_default' => 'CURRENT_TIMESTAMP' + ) + ); + + private $_modifiedColumnData = array( + array( + 'col_name' => "id", "col_type" => 'integer', + 'col_length' => 0, 'col_isNull' => 0, 'col_extra' => 'auto_increment', + 'col_default' => 1, 'col_attribute' => 'UNSIGNED' + ), + array('col_name' => "col1", 'col_type' => 'varchar', + 'col_length' => 100, 'col_isNull' => 1, 'col_extra' => '', + 'col_default' => 1, 'col_attribute' => 'BINARY' + ), + array( + 'col_name' => "col2", 'col_type' => 'DATETIME', + 'col_length' => 0, 'col_isNull' => 1, 'col_extra' => '', + 'col_default' => 'CURRENT_TIMESTAMP', 'col_attribute' => 'on update CURRENT_TIMESTAMP' + ) + ); + /** * prepares environment for tests * @@ -61,12 +95,14 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase 'relation' => 'relation', 'central_columns' => 'pma_central_columns' ); - //mock DBI + + // mock DBI $dbi = $this->getMockBuilder('PMA_DatabaseInterface') ->disableOriginalConstructor() ->getMock(); $GLOBALS['dbi'] = $dbi; - // set expectations + + // set some common expectations $dbi->expects($this->any()) ->method('selectDb') ->will($this->returnValue(true)); @@ -84,17 +120,9 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase $dbi->expects($this->any()) ->method('getColumnNames') ->will($this->returnValue(array("id", "col1", "col2"))); - $dbi->expects($this->any()) - ->method('fetchResult') - ->will($this->returnValue(array("id", "col1"))); $dbi->expects($this->any()) ->method('tryQuery') ->will($this->returnValue(true)); - $dbi->expects($this->any()) - ->method('fetchValue') - ->will( - $this->returnValue('PMA_table=CREATE table `PMA_table` (id integer)') - ); $dbi->expects($this->any()) ->method('getTables') ->will( @@ -127,13 +155,29 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase */ public function testPMAGetColumnsList() { + $GLOBALS['dbi']->expects($this->at(1)) + ->method('fetchResult') + ->with("SELECT * FROM `pma_central_columns` WHERE db_name = 'phpmyadmin' LIMIT 0, 25;", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue($this->_columnData) + ); + + $GLOBALS['dbi']->expects($this->at(3)) + ->method('fetchResult') + ->with("SELECT * FROM `pma_central_columns` WHERE db_name = 'phpmyadmin' LIMIT 1, 2;", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue( + array_slice($this->_columnData, 1, 2) + ) + ); + $this->assertEquals( - array("id", "col1"), + $this->_modifiedColumnData, PMA_getColumnsList('phpmyadmin') ); $this->assertEquals( - array("id", "col1"), - PMA_getColumnsList('phpmyadmin', 0, 0) + array_slice($this->_modifiedColumnData, 1, 2), + PMA_getColumnsList('phpmyadmin', 1, 2) ); } @@ -144,8 +188,15 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase */ function testPMAGetCentralColumnsCount() { + $GLOBALS['dbi']->expects($this->at(1)) + ->method('fetchResult') + ->with("SELECT count(db_name) FROM `pma_central_columns` WHERE db_name = 'phpmyadmin';", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue(array(3)) + ); + $this->assertEquals( - 'id', + 3, PMA_getCentralColumnsCount('phpmyadmin') ); } @@ -157,15 +208,11 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase */ public function testPMASyncUniqueColumns() { - $field_select = array("col1"); $_REQUEST['db'] = 'PMA_db'; $_REQUEST['table'] = 'PMA_table'; - $this->assertInstanceOf( - 'PMA_Message', PMA_syncUniqueColumns($field_select, false) - ); - $field_select = array("PMA_table"); - $this->assertInstanceOf( - 'PMA_Message', PMA_syncUniqueColumns($field_select) + + $this->assertTrue( + PMA_syncUniqueColumns(array('PMA_table')) ); } @@ -176,15 +223,33 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase */ public function testPMADeleteColumnsFromList() { - $field_select = array("col1"); $_REQUEST['db'] = 'PMA_db'; $_REQUEST['table'] = 'PMA_table'; + + // when column exists in the central column list + $GLOBALS['dbi']->expects($this->at(2)) + ->method('fetchResult') + ->with("SELECT col_name FROM `pma_central_columns` WHERE db_name = 'PMA_db' AND col_name IN ('col1');", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue(array('col1')) + ); + + $GLOBALS['dbi']->expects($this->at(4)) + ->method('tryQuery') + ->with("DELETE FROM `pma_central_columns` WHERE db_name = 'PMA_db' AND col_name IN ('col1');", $GLOBALS['controllink']) + ->will( + $this->returnValue(array('col1')) + ); + $this->assertTrue( - PMA_deleteColumnsFromList($field_select, false) + PMA_deleteColumnsFromList(array("col1"), false) ); + + // when column does not exist in the central column list $this->assertInstanceOf( 'PMA_Message', PMA_deleteColumnsFromList(array('column1'), false) ); + $this->assertInstanceOf( 'PMA_Message', PMA_deleteColumnsFromList(array('PMA_table')) ); @@ -197,43 +262,12 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase */ public function testPMAMakeConsistentWithList() { - $dbi = $GLOBALS['dbi']; - $dbitmp = $this->getMockBuilder('PMA_DatabaseInterface') - ->disableOriginalConstructor() - ->getMock(); - $GLOBALS['dbi'] = $dbitmp; - $dbitmp->expects($this->any()) - ->method('selectDb') - ->will($this->returnValue(true)); - $dbitmp->expects($this->any()) - ->method('getColumnNames') - ->will($this->returnValue(array("id", "col1", "col2"))); - $dbitmp->expects($this->any()) - ->method('tryQuery') - ->will($this->returnValue(true)); - $dbitmp->expects($this->any()) + $GLOBALS['dbi']->expects($this->any()) ->method('fetchResult') ->will( - $this->returnValue( - array( - array( - 'col_name'=>"id", "col_type"=>'integer', - 'col_length'=>0, 'col_isNull'=>0, 'col_extra'=>'', - 'col_default'=>1 - ), - array('col_name'=>"col1", 'col_type'=>'varchar', - 'col_length'=>100, 'col_isNull'=>1, 'col_extra'=>'', - 'col_default'=>1 - ), - array( - 'col_name'=>"col2", 'col_type'=>'DATETIME', - 'col_length'=>0, 'col_isNull'=>1, 'col_extra'=>'', - 'col_default'=>'CURRENT_TIMESTAMP' - ) - ) - ) + $this->returnValue($this->_columnData) ); - $dbitmp->expects($this->any()) + $GLOBALS['dbi']->expects($this->any()) ->method('fetchValue') ->will( $this->returnValue('PMA_table=CREATE table `PMA_table` (id integer)') @@ -241,7 +275,6 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase $this->assertTrue( PMA_makeConsistentWithList("phpmyadmin", array('PMA_table')) ); - $GLOBALS['dbi'] = $dbi; } /** @@ -253,15 +286,41 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase { $db = 'PMA_db'; $table = 'PMA_table'; + + $GLOBALS['dbi']->expects($this->at(3)) + ->method('fetchResult') + ->with("SELECT col_name FROM `pma_central_columns` WHERE db_name = 'PMA_db' AND col_name IN ('id','col1','col2');", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue(array('id','col1')) + ); $this->assertEquals( array("id", "col1"), PMA_getCentralColumnsFromTable($db, $table) ); + } + + /** + * Test for PMA_getCentralColumnsFromTable with $allFields = true + * + * @return void + */ + public function testPMAGetCentralColumnsFromTableWithAllFields() + { + $db = 'PMA_db'; + $table = 'PMA_table'; + + $GLOBALS['dbi']->expects($this->at(3)) + ->method('fetchResult') + ->with("SELECT * FROM `pma_central_columns` WHERE db_name = 'PMA_db' AND col_name IN ('id','col1','col2');", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue(array_slice($this->_columnData, 0, 2)) + ); $this->assertEquals( - array("id", "col1"), + array_slice($this->_modifiedColumnData, 0, 2), PMA_getCentralColumnsFromTable($db, $table, true) ); } + /** * Test for PMA_updateOneColumn * @@ -408,16 +467,38 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase */ public function testPMAGetCentralColumnsListRaw() { + $GLOBALS['dbi']->expects($this->at(1)) + ->method('fetchResult') + ->with("SELECT * FROM `pma_central_columns` WHERE db_name = 'phpmyadmin';", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue($this->_columnData) + ); $this->assertEquals( - json_encode(array("id", "col1")), - PMA_getCentralColumnsListRaw('phpmyadmin', 'pma_central_columns') - ); - $this->assertEquals( - json_encode(array("id", "col1")), + json_encode($this->_modifiedColumnData), PMA_getCentralColumnsListRaw('phpmyadmin', '') ); } + /** + * Test for PMA_getCentralColumnsListRaw with a table name + * + * @return void + */ + public function testPMAGetCentralColumnsListRawWithTable() + { + $GLOBALS['dbi']->expects($this->at(3)) + ->method('fetchResult') + ->with("SELECT * FROM `pma_central_columns` WHERE db_name = 'phpmyadmin' AND col_name NOT IN ('id','col1','col2');", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue($this->_columnData) + ); + $this->assertEquals( + json_encode($this->_modifiedColumnData), + PMA_getCentralColumnsListRaw('phpmyadmin', 'table1') + ); + + } + /** * Test for PMA_getHTMLforAddNewColumn * @@ -459,9 +540,15 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase */ public function testPMAFindExistingColNames() { + $GLOBALS['dbi']->expects($this->at(1)) + ->method('fetchResult') + ->with("SELECT * FROM `pma_central_columns` WHERE db_name = 'phpmyadmin' AND col_name IN ('col1');", null, null, $GLOBALS['controllink']) + ->will( + $this->returnValue(array_slice($this->_columnData, 1, 1)) + ); $this->assertEquals( - array('id', 'col1'), - PMA_findExistingColNames('phpmyadmin', 'col1', true) + array_slice($this->_modifiedColumnData, 1, 1), + PMA_findExistingColNames('phpmyadmin', "'col1'", true) ); } @@ -494,7 +581,7 @@ class PMA_Central_Columns_Test extends PHPUnit_Framework_TestCase $selected_tbl = 'PMA_table'; $result = PMA_getHTMLforColumnDropdown($db, $selected_tbl); $this->assertEquals( - '', + '', $result ); }