Merge branch 'master' of https://github.com/phpmyadmin/phpmyadmin into UT_plu_parse
This commit is contained in:
commit
35417fe3ed
@ -33,6 +33,7 @@ phpMyAdmin - ChangeLog
|
||||
- bug #3960 NavigationBarIconic config not honored
|
||||
- bug #3985 Call to undefined function mb_detect_encoding
|
||||
- bug #4007 Analyze option not shown for InnoDB tables
|
||||
- bug #4015 Forcing a storage engine for configuration storage
|
||||
|
||||
4.0.4.1 (2013-06-30)
|
||||
- [security] Global variables scope injection vulnerability (see PMASA-2013-7)
|
||||
|
||||
@ -83,7 +83,7 @@ $titles = PMA_Util::buildActionTitles();
|
||||
|
||||
if ($num_tables == 0) {
|
||||
$response->addHTML(
|
||||
'<p>' . __('No tables found in database') . '</p>' . "\n"
|
||||
'<p>' . __('No tables found in database.') . '</p>' . "\n"
|
||||
);
|
||||
if (empty($db_is_information_schema)) {
|
||||
ob_start();
|
||||
|
||||
@ -44,7 +44,7 @@ CREATE TABLE IF NOT EXISTS `pma__bookmark` (
|
||||
`query` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Bookmarks'
|
||||
COMMENT='Bookmarks'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS `pma__column_info` (
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `db_name` (`db_name`,`table_name`,`column_name`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Column information for phpMyAdmin'
|
||||
COMMENT='Column information for phpMyAdmin'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -84,7 +84,7 @@ CREATE TABLE IF NOT EXISTS `pma__history` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `username` (`username`,`db`,`table`,`timevalue`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='SQL history for phpMyAdmin'
|
||||
COMMENT='SQL history for phpMyAdmin'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -100,7 +100,7 @@ CREATE TABLE IF NOT EXISTS `pma__pdf_pages` (
|
||||
PRIMARY KEY (`page_nr`),
|
||||
KEY `db_name` (`db_name`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='PDF relation pages for phpMyAdmin'
|
||||
COMMENT='PDF relation pages for phpMyAdmin'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -114,7 +114,7 @@ CREATE TABLE IF NOT EXISTS `pma__recent` (
|
||||
`tables` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Recently accessed tables'
|
||||
COMMENT='Recently accessed tables'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -131,7 +131,7 @@ CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` (
|
||||
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`username`,`db_name`,`table_name`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Tables'' UI preferences'
|
||||
COMMENT='Tables'' UI preferences'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -150,7 +150,7 @@ CREATE TABLE IF NOT EXISTS `pma__relation` (
|
||||
PRIMARY KEY (`master_db`,`master_table`,`master_field`),
|
||||
KEY `foreign_field` (`foreign_db`,`foreign_table`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Relation table'
|
||||
COMMENT='Relation table'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -167,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `pma__table_coords` (
|
||||
`y` float unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (`db_name`,`table_name`,`pdf_page_number`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Table coordinates for phpMyAdmin PDF output'
|
||||
COMMENT='Table coordinates for phpMyAdmin PDF output'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -182,7 +182,7 @@ CREATE TABLE IF NOT EXISTS `pma__table_info` (
|
||||
`display_field` varchar(64) NOT NULL default '',
|
||||
PRIMARY KEY (`db_name`,`table_name`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Table information for phpMyAdmin'
|
||||
COMMENT='Table information for phpMyAdmin'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -200,7 +200,7 @@ CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
|
||||
`h` TINYINT,
|
||||
PRIMARY KEY (`db_name`,`table_name`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='Table coordinates for Designer'
|
||||
COMMENT='Table coordinates for Designer'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -222,7 +222,7 @@ CREATE TABLE IF NOT EXISTS `pma__tracking` (
|
||||
`tracking_active` int(1) unsigned NOT NULL default '1',
|
||||
PRIMARY KEY (`db_name`,`table_name`,`version`)
|
||||
)
|
||||
ENGINE=MyISAM ROW_FORMAT=COMPACT COMMENT='Database changes tracking for phpMyAdmin'
|
||||
COMMENT='Database changes tracking for phpMyAdmin'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -237,5 +237,5 @@ CREATE TABLE IF NOT EXISTS `pma__userconfig` (
|
||||
`config_data` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
)
|
||||
ENGINE=MyISAM COMMENT='User preferences storage for phpMyAdmin'
|
||||
COMMENT='User preferences storage for phpMyAdmin'
|
||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
@ -31,7 +31,7 @@ CREATE TABLE IF NOT EXISTS `pma__bookmark` (
|
||||
`query` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Bookmarks'
|
||||
COMMENT='Bookmarks'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -52,7 +52,7 @@ CREATE TABLE IF NOT EXISTS `pma__column_info` (
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `db_name` (`db_name`,`table_name`,`column_name`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Column information for phpMyAdmin'
|
||||
COMMENT='Column information for phpMyAdmin'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -71,7 +71,7 @@ CREATE TABLE IF NOT EXISTS `pma__history` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `username` (`username`,`db`,`table`,`timevalue`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='SQL history for phpMyAdmin'
|
||||
COMMENT='SQL history for phpMyAdmin'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS `pma__pdf_pages` (
|
||||
PRIMARY KEY (`page_nr`),
|
||||
KEY `db_name` (`db_name`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='PDF relation pages for phpMyAdmin'
|
||||
COMMENT='PDF relation pages for phpMyAdmin'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -101,7 +101,7 @@ CREATE TABLE IF NOT EXISTS `pma__recent` (
|
||||
`tables` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Recently accessed tables'
|
||||
COMMENT='Recently accessed tables'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -118,7 +118,7 @@ CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` (
|
||||
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`username`,`db_name`,`table_name`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Tables'' UI preferences'
|
||||
COMMENT='Tables'' UI preferences'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -137,7 +137,7 @@ CREATE TABLE IF NOT EXISTS `pma__relation` (
|
||||
PRIMARY KEY (`master_db`,`master_table`,`master_field`),
|
||||
KEY `foreign_field` (`foreign_db`,`foreign_table`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Relation table'
|
||||
COMMENT='Relation table'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -154,7 +154,7 @@ CREATE TABLE IF NOT EXISTS `pma__table_coords` (
|
||||
`y` float NOT NULL default '0',
|
||||
PRIMARY KEY (`db_name`,`table_name`,`pdf_page_number`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Table coordinates for phpMyAdmin PDF output'
|
||||
COMMENT='Table coordinates for phpMyAdmin PDF output'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -169,7 +169,7 @@ CREATE TABLE IF NOT EXISTS `pma__table_info` (
|
||||
`display_field` varchar(64) NOT NULL default '',
|
||||
PRIMARY KEY (`db_name`,`table_name`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Table information for phpMyAdmin'
|
||||
COMMENT='Table information for phpMyAdmin'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -187,7 +187,7 @@ CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
|
||||
`h` INT,
|
||||
PRIMARY KEY (`db_name`,`table_name`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='Table coordinates for Designer'
|
||||
COMMENT='Table coordinates for Designer'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -209,7 +209,6 @@ CREATE TABLE IF NOT EXISTS `pma__tracking` (
|
||||
`tracking_active` int(1) NOT NULL default '1',
|
||||
PRIMARY KEY (`db_name`,`table_name`,`version`)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
@ -224,5 +223,5 @@ CREATE TABLE IF NOT EXISTS `pma__userconfig` (
|
||||
`config_data` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
)
|
||||
ENGINE=InnoDB COMMENT='User preferences storage for phpMyAdmin'
|
||||
COMMENT='User preferences storage for phpMyAdmin'
|
||||
COLLATE utf8_bin;
|
||||
|
||||
@ -136,12 +136,12 @@ function PMA_current_version(data)
|
||||
escapeHtml(data['version']),
|
||||
escapeHtml(data['date'])
|
||||
);
|
||||
var klass = 'notice';
|
||||
var htmlClass = 'notice';
|
||||
if (Math.floor(latest / 10000) === Math.floor(current / 10000)) {
|
||||
/* Security update */
|
||||
klass = 'error';
|
||||
htmlClass = 'error';
|
||||
}
|
||||
$('#maincontainer').after('<div class="' + klass + '">' + message + '</div>');
|
||||
$('#maincontainer').after('<div class="' + htmlClass + '">' + message + '</div>');
|
||||
}
|
||||
if (latest === current) {
|
||||
version_information_message = ' (' + PMA_messages.strUpToDate + ')';
|
||||
|
||||
@ -256,7 +256,7 @@ $js_messages['enum_hint'] =__('Enter each value in a separate field');
|
||||
$js_messages['enum_addValue'] =__('Add %d value(s)');
|
||||
|
||||
/* For import.js */
|
||||
$js_messages['strImportCSV'] = __('Note: If the file contains multiple tables, they will be combined into one');
|
||||
$js_messages['strImportCSV'] = __('Note: If the file contains multiple tables, they will be combined into one.');
|
||||
|
||||
/* For sql.js */
|
||||
$js_messages['strHideQueryBox'] = __('Hide query box');
|
||||
|
||||
@ -605,7 +605,7 @@ class PMA_Index
|
||||
. PMA_Util::backquote($table) . ' DROP INDEX '
|
||||
. PMA_Util::backquote($index->getName()) . ';';
|
||||
$this_params['message_to_show'] = sprintf(
|
||||
__('Index %s has been dropped'), $index->getName()
|
||||
__('Index %s has been dropped.'), $index->getName()
|
||||
);
|
||||
|
||||
$js_msg = PMA_jsFormat(
|
||||
|
||||
@ -89,7 +89,7 @@ class PMA_Util
|
||||
/**
|
||||
* Returns an HTML IMG tag for a particular icon from a theme,
|
||||
* which may be an actual file or an icon from a sprite.
|
||||
* This function takes into account the ActionLinksMode
|
||||
* This function takes into account the ActionLinksMode
|
||||
* configuration setting and wraps the image tag in a span tag.
|
||||
*
|
||||
* @param string $icon name of icon file
|
||||
@ -106,19 +106,19 @@ class PMA_Util
|
||||
) {
|
||||
$include_icon = $include_text = false;
|
||||
if (in_array(
|
||||
$GLOBALS['cfg'][$control_param],
|
||||
$GLOBALS['cfg'][$control_param],
|
||||
array('icons', 'both')
|
||||
)
|
||||
) {
|
||||
) {
|
||||
$include_icon = true;
|
||||
}
|
||||
}
|
||||
if ($force_text
|
||||
|| in_array(
|
||||
$GLOBALS['cfg'][$control_param],
|
||||
$GLOBALS['cfg'][$control_param],
|
||||
array('text', 'both')
|
||||
)
|
||||
) {
|
||||
$include_text = true;
|
||||
$include_text = true;
|
||||
}
|
||||
// Sometimes use a span (we rely on this in js/sql.js). But for menu bar
|
||||
// we don't need a span
|
||||
@ -1811,10 +1811,10 @@ class PMA_Util
|
||||
// the text that follows and if browser does not display
|
||||
// images, the text is duplicated
|
||||
$tab['text'] = self::getIcon(
|
||||
$tab['icon'],
|
||||
$tab['text'],
|
||||
false,
|
||||
true,
|
||||
$tab['icon'],
|
||||
$tab['text'],
|
||||
false,
|
||||
true,
|
||||
'TabsMode'
|
||||
);
|
||||
|
||||
@ -3438,7 +3438,7 @@ class PMA_Util
|
||||
|
||||
if ($files === false) {
|
||||
PMA_Message::error(
|
||||
__('The directory you set for upload work cannot be reached')
|
||||
__('The directory you set for upload work cannot be reached.')
|
||||
)->display();
|
||||
} elseif (! empty($files)) {
|
||||
$block_html .= "\n"
|
||||
@ -4152,5 +4152,182 @@ class PMA_Util
|
||||
}
|
||||
return $regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information with latest version from phpmyadmin.net
|
||||
*
|
||||
* @return JSON decoded object with the data
|
||||
*/
|
||||
public static function getLatestVersion()
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
// wait 3s at most for server response, it's enough to get information
|
||||
// from a working server
|
||||
$connection_timeout = 3;
|
||||
|
||||
$response = '{}';
|
||||
// Get response text from phpmyadmin.net or from the session
|
||||
// Update cache every 6 hours
|
||||
if (isset($_SESSION['cache']['version_check'])
|
||||
&& time() < $_SESSION['cache']['version_check']['timestamp'] + 3600 * 6
|
||||
) {
|
||||
$save = false;
|
||||
$response = $_SESSION['cache']['version_check']['response'];
|
||||
} else {
|
||||
$save = true;
|
||||
$file = 'http://www.phpmyadmin.net/home_page/version.json';
|
||||
if (ini_get('allow_url_fopen')) {
|
||||
$context = array(
|
||||
'http' => array(
|
||||
'request_fulluri' => true,
|
||||
'timeout' => $connection_timeout,
|
||||
)
|
||||
);
|
||||
if (strlen($cfg['VersionCheckProxyUrl'])) {
|
||||
$context['http']['proxy'] = $cfg['VersionCheckProxyUrl'];
|
||||
if (strlen($cfg['VersionCheckProxyUser'])) {
|
||||
$auth = base64_encode(
|
||||
$cfg['VersionCheckProxyUser'] . ':'
|
||||
. $cfg['VersionCheckProxyPass']
|
||||
);
|
||||
$context['http']['header'] =
|
||||
'Proxy-Authorization: Basic '
|
||||
. $auth;
|
||||
}
|
||||
}
|
||||
$response = file_get_contents(
|
||||
$file,
|
||||
false,
|
||||
stream_context_create($context)
|
||||
);
|
||||
} else if (function_exists('curl_init')) {
|
||||
$curl_handle = curl_init($file);
|
||||
if (strlen($cfg['VersionCheckProxyUrl'])) {
|
||||
curl_setopt(
|
||||
$curl_handle,
|
||||
CURLOPT_PROXY,
|
||||
$cfg['VersionCheckProxyUrl']
|
||||
);
|
||||
if (strlen($cfg['VersionCheckProxyUser'])) {
|
||||
curl_setopt(
|
||||
$curl_handle,
|
||||
CURLOPT_PROXYUSERPWD,
|
||||
$cfg['VersionCheckProxyUser']
|
||||
. ':' . $cfg['VersionCheckProxyPass']
|
||||
);
|
||||
}
|
||||
}
|
||||
curl_setopt(
|
||||
$curl_handle,
|
||||
CURLOPT_RETURNTRANSFER,
|
||||
1
|
||||
);
|
||||
curl_setopt(
|
||||
$curl_handle,
|
||||
CURLOPT_HEADER,
|
||||
false
|
||||
);
|
||||
curl_setopt(
|
||||
$curl_handle,
|
||||
CURLOPT_RETURNTRANSFER,
|
||||
true
|
||||
);
|
||||
curl_setopt(
|
||||
$curl_handle,
|
||||
CURLOPT_TIMEOUT,
|
||||
$connection_timeout
|
||||
);
|
||||
$response = curl_exec($curl_handle);
|
||||
}
|
||||
}
|
||||
|
||||
if ($save) {
|
||||
$_SESSION['cache']['version_check'] = array(
|
||||
'response' => $response,
|
||||
'timestamp' => time()
|
||||
);
|
||||
}
|
||||
|
||||
$data = json_decode($response);
|
||||
if (is_object($data)
|
||||
&& strlen($data->version)
|
||||
&& strlen($data->date)
|
||||
) {
|
||||
if ($save) {
|
||||
$_SESSION['cache']['version_check'] = array(
|
||||
'response' => $response,
|
||||
'timestamp' => time()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates numerical equivalent of phpMyAdmin version string
|
||||
*
|
||||
* @param string $version version
|
||||
*
|
||||
* @return mixed false on failure, integer on success
|
||||
*/
|
||||
public static function versionToInt($version)
|
||||
{
|
||||
$parts = explode('-', $version);
|
||||
if (count($parts) > 1) {
|
||||
$suffix = $parts[1];
|
||||
} else {
|
||||
$suffix = '';
|
||||
}
|
||||
$parts = explode('.', $parts[0]);
|
||||
|
||||
$result = 0;
|
||||
|
||||
if (count($parts) >= 1 && is_numeric($parts[0])) {
|
||||
$result += 1000000 * $parts[0];
|
||||
}
|
||||
|
||||
if (count($parts) >= 2 && is_numeric($parts[1])) {
|
||||
$result += 10000 * $parts[1];
|
||||
}
|
||||
|
||||
if (count($parts) >= 3 && is_numeric($parts[2])) {
|
||||
$result += 100 * $parts[2];
|
||||
}
|
||||
|
||||
if (count($parts) >= 4 && is_numeric($parts[3])) {
|
||||
$result += 1 * $parts[3];
|
||||
}
|
||||
|
||||
if (!empty($suffix)) {
|
||||
$matches = array();
|
||||
if (preg_match('/^(\D+)(\d+)$/', $suffix, $matches)) {
|
||||
$suffix = $matches[1];
|
||||
$result += intval($matches[2]);
|
||||
}
|
||||
switch ($suffix) {
|
||||
case 'pl':
|
||||
$result += 60;
|
||||
break;
|
||||
case 'rc':
|
||||
$result += 30;
|
||||
break;
|
||||
case 'beta':
|
||||
$result += 20;
|
||||
break;
|
||||
case 'alpha':
|
||||
$result += 10;
|
||||
break;
|
||||
case 'dev':
|
||||
$result += 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$result += 50; // for final
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@ -193,46 +193,46 @@ $cfg_db['_overrides']['Servers/1/extension'] = extension_loaded('mysqli')
|
||||
? 'mysqli' : 'mysql';
|
||||
|
||||
/**
|
||||
* Basic validator assignments (functions from libraries/config/validate.lib.php
|
||||
* Basic validator assignments (functions from libraries/config/Validator.class.php
|
||||
* and 'validators' object in js/config.js)
|
||||
* Use only full paths and form ids
|
||||
*/
|
||||
$cfg_db['_validators'] = array(
|
||||
'CharTextareaCols' => 'PMA_validatePositiveNumber',
|
||||
'CharTextareaRows' => 'PMA_validatePositiveNumber',
|
||||
'ExecTimeLimit' => 'PMA_validateNonNegativeNumber',
|
||||
'Export/sql_max_query_size' => 'PMA_validatePositiveNumber',
|
||||
'ForeignKeyMaxLimit' => 'PMA_validatePositiveNumber',
|
||||
'Import/csv_enclosed' => array(array('PMA_validateByRegex', '/^.?$/')),
|
||||
'Import/csv_escaped' => array(array('PMA_validateByRegex', '/^.$/')),
|
||||
'Import/csv_terminated' => array(array('PMA_validateByRegex', '/^.$/')),
|
||||
'Import/ldi_enclosed' => array(array('PMA_validateByRegex', '/^.?$/')),
|
||||
'Import/ldi_escaped' => array(array('PMA_validateByRegex', '/^.$/')),
|
||||
'Import/ldi_terminated' => array(array('PMA_validateByRegex', '/^.$/')),
|
||||
'Import/skip_queries' => 'PMA_validateNonNegativeNumber',
|
||||
'InsertRows' => 'PMA_validatePositiveNumber',
|
||||
'NumRecentTables' => 'PMA_validateNonNegativeNumber',
|
||||
'LimitChars' => 'PMA_validatePositiveNumber',
|
||||
'LoginCookieValidity' => 'PMA_validatePositiveNumber',
|
||||
'LoginCookieStore' => 'PMA_validateNonNegativeNumber',
|
||||
'MaxDbList' => 'PMA_validatePositiveNumber',
|
||||
'MaxNavigationItems' => 'PMA_validatePositiveNumber',
|
||||
'MaxCharactersInDisplayedSQL' => 'PMA_validatePositiveNumber',
|
||||
'MaxRows' => 'PMA_validatePositiveNumber',
|
||||
'MaxTableList' => 'PMA_validatePositiveNumber',
|
||||
'MemoryLimit' => array(array('PMA_validateByRegex', '/^\d+(?:[kmg])?$/i')),
|
||||
'NavigationTreeTableLevel' => 'PMA_validatePositiveNumber',
|
||||
'QueryHistoryMax' => 'PMA_validatePositiveNumber',
|
||||
'QueryWindowWidth' => 'PMA_validatePositiveNumber',
|
||||
'QueryWindowHeight' => 'PMA_validatePositiveNumber',
|
||||
'RepeatCells' => 'PMA_validateNonNegativeNumber',
|
||||
'Server' => 'PMA_validateServer',
|
||||
'Server_pmadb' => 'PMA_validatePMAStorage',
|
||||
'Servers/1/port' => 'PMA_validatePortNumber',
|
||||
'Servers/1/hide_db' => 'PMA_validateRegex',
|
||||
'TextareaCols' => 'PMA_validatePositiveNumber',
|
||||
'TextareaRows' => 'PMA_validatePositiveNumber',
|
||||
'TrustedProxies' => 'PMA_validateTrustedProxies');
|
||||
'CharTextareaCols' => 'validatePositiveNumber',
|
||||
'CharTextareaRows' => 'validatePositiveNumber',
|
||||
'ExecTimeLimit' => 'validateNonNegativeNumber',
|
||||
'Export/sql_max_query_size' => 'validatePositiveNumber',
|
||||
'ForeignKeyMaxLimit' => 'validatePositiveNumber',
|
||||
'Import/csv_enclosed' => array(array('validateByRegex', '/^.?$/')),
|
||||
'Import/csv_escaped' => array(array('validateByRegex', '/^.$/')),
|
||||
'Import/csv_terminated' => array(array('validateByRegex', '/^.$/')),
|
||||
'Import/ldi_enclosed' => array(array('validateByRegex', '/^.?$/')),
|
||||
'Import/ldi_escaped' => array(array('validateByRegex', '/^.$/')),
|
||||
'Import/ldi_terminated' => array(array('validateByRegex', '/^.$/')),
|
||||
'Import/skip_queries' => 'validateNonNegativeNumber',
|
||||
'InsertRows' => 'validatePositiveNumber',
|
||||
'NumRecentTables' => 'validateNonNegativeNumber',
|
||||
'LimitChars' => 'validatePositiveNumber',
|
||||
'LoginCookieValidity' => 'validatePositiveNumber',
|
||||
'LoginCookieStore' => 'validateNonNegativeNumber',
|
||||
'MaxDbList' => 'validatePositiveNumber',
|
||||
'MaxNavigationItems' => 'validatePositiveNumber',
|
||||
'MaxCharactersInDisplayedSQL' => 'validatePositiveNumber',
|
||||
'MaxRows' => 'validatePositiveNumber',
|
||||
'MaxTableList' => 'validatePositiveNumber',
|
||||
'MemoryLimit' => array(array('validateByRegex', '/^\d+(?:[kmg])?$/i')),
|
||||
'NavigationTreeTableLevel' => 'validatePositiveNumber',
|
||||
'QueryHistoryMax' => 'validatePositiveNumber',
|
||||
'QueryWindowWidth' => 'validatePositiveNumber',
|
||||
'QueryWindowHeight' => 'validatePositiveNumber',
|
||||
'RepeatCells' => 'validateNonNegativeNumber',
|
||||
'Server' => 'validateServer',
|
||||
'Server_pmadb' => 'validatePMAStorage',
|
||||
'Servers/1/port' => 'validatePortNumber',
|
||||
'Servers/1/hide_db' => 'validateRegex',
|
||||
'TextareaCols' => 'validatePositiveNumber',
|
||||
'TextareaRows' => 'validatePositiveNumber',
|
||||
'TrustedProxies' => 'validateTrustedProxies');
|
||||
|
||||
/**
|
||||
* Additional validators used for user preferences
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
* Core libraries.
|
||||
*/
|
||||
require_once './libraries/config/FormDisplay.tpl.php';
|
||||
require_once './libraries/config/validate.lib.php';
|
||||
require_once './libraries/config/Validator.class.php';
|
||||
require_once './libraries/js_escape.lib.php';
|
||||
|
||||
/**
|
||||
@ -91,7 +91,7 @@ class FormDisplay
|
||||
'error_invalid_value' => __('Incorrect value'),
|
||||
'error_value_lte' => __('Value must be equal or lower than %s'));
|
||||
// initialize validators
|
||||
PMA_config_get_validators();
|
||||
PMA_Validator::config_get_validators();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +164,7 @@ class FormDisplay
|
||||
}
|
||||
|
||||
// run validation
|
||||
$errors = PMA_config_validate($paths, $values, false);
|
||||
$errors = PMA_Validator::config_validate($paths, $values, false);
|
||||
|
||||
// change error keys from canonical paths to work paths
|
||||
if (is_array($errors) && count($errors) > 0) {
|
||||
@ -198,7 +198,7 @@ class FormDisplay
|
||||
$js = array();
|
||||
$js_default = array();
|
||||
$tabbed_form = $tabbed_form && (count($this->_forms) > 1);
|
||||
$validators = PMA_config_get_validators();
|
||||
$validators = PMA_Validator::config_get_validators();
|
||||
|
||||
PMA_displayFormTop();
|
||||
|
||||
|
||||
@ -133,6 +133,10 @@ function PMA_displayInput($path, $name, $type, $value, $description = '',
|
||||
global $_FormDisplayGroup;
|
||||
static $icons; // An array of IMG tags used further below in the function
|
||||
|
||||
if (defined('TESTSUITE')) {
|
||||
$icons = null;
|
||||
}
|
||||
|
||||
$is_setup_script = defined('PMA_SETUP');
|
||||
if ($icons === null) { // if the static variables have not been initialised
|
||||
$icons = array();
|
||||
@ -443,6 +447,7 @@ function PMA_addJsValidate($field_id, $validators, &$js_array)
|
||||
foreach ((array)$validators as $validator) {
|
||||
$validator = (array)$validator;
|
||||
$v_name = array_shift($validator);
|
||||
$v_name = "PMA_" . $v_name;
|
||||
$v_args = array();
|
||||
foreach ($validator as $arg) {
|
||||
$v_args[] = PMA_escapeJsString($arg);
|
||||
|
||||
588
libraries/config/Validator.class.php
Normal file
588
libraries/config/Validator.class.php
Normal file
@ -0,0 +1,588 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Validaition class for various validation functions
|
||||
*
|
||||
* Validation function takes two argument: id for which it is called
|
||||
* and array of fields' values (usually values for entire formset, as defined
|
||||
* in forms.inc.php).
|
||||
* The function must always return an array with an error (or error array)
|
||||
* assigned to a form element (formset name or field path). Even if there are
|
||||
* no errors, key must be set with an empty value.
|
||||
*
|
||||
* Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
class PMA_Validator
|
||||
{
|
||||
/**
|
||||
* Returns validator list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function config_get_validators()
|
||||
{
|
||||
static $validators = null;
|
||||
|
||||
if ($validators === null) {
|
||||
$cf = ConfigFile::getInstance();
|
||||
$validators = $cf->getDbEntry('_validators', array());
|
||||
if (!defined('PMA_SETUP')) {
|
||||
// not in setup script: load additional validators for user
|
||||
// preferences we need original config values not overwritten
|
||||
// by user preferences, creating a new PMA_Config instance is a
|
||||
// better idea than hacking into its code
|
||||
$org_cfg = $cf->getOrgConfigObj();
|
||||
$uvs = $cf->getDbEntry('_userValidators', array());
|
||||
foreach ($uvs as $field => $uv_list) {
|
||||
$uv_list = (array)$uv_list;
|
||||
foreach ($uv_list as &$uv) {
|
||||
if (!is_array($uv)) {
|
||||
continue;
|
||||
}
|
||||
for ($i = 1; $i < count($uv); $i++) {
|
||||
if (substr($uv[$i], 0, 6) == 'value:') {
|
||||
$uv[$i] = PMA_arrayRead(
|
||||
substr($uv[$i], 6), $org_cfg->settings
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$validators[$field] = isset($validators[$field])
|
||||
? array_merge((array)$validators[$field], $uv_list)
|
||||
: $uv_list;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs validation $validator_id on values $values and returns error list.
|
||||
*
|
||||
* Return values:
|
||||
* o array, keys - field path or formset id, values - array of errors
|
||||
* when $isPostSource is true values is an empty array to allow for error list
|
||||
* cleanup in HTML documen
|
||||
* o false - when no validators match name(s) given by $validator_id
|
||||
*
|
||||
* @param string|array $validator_id ID of validator(s) to run
|
||||
* @param array &$values Values to validate
|
||||
* @param bool $isPostSource tells whether $values are directly from
|
||||
* POST request
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public static function config_validate($validator_id, &$values, $isPostSource)
|
||||
{
|
||||
// find validators
|
||||
$validator_id = (array) $validator_id;
|
||||
$validators = static::config_get_validators();
|
||||
$vids = array();
|
||||
$cf = ConfigFile::getInstance();
|
||||
foreach ($validator_id as &$vid) {
|
||||
$vid = $cf->getCanonicalPath($vid);
|
||||
if (isset($validators[$vid])) {
|
||||
$vids[] = $vid;
|
||||
}
|
||||
}
|
||||
if (empty($vids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create argument list with canonical paths and remember path mapping
|
||||
$arguments = array();
|
||||
$key_map = array();
|
||||
foreach ($values as $k => $v) {
|
||||
$k2 = $isPostSource ? str_replace('-', '/', $k) : $k;
|
||||
$k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2;
|
||||
$key_map[$k2] = $k;
|
||||
$arguments[$k2] = $v;
|
||||
}
|
||||
|
||||
// validate
|
||||
$result = array();
|
||||
foreach ($vids as $vid) {
|
||||
// call appropriate validation functions
|
||||
foreach ((array)$validators[$vid] as $validator) {
|
||||
$vdef = (array) $validator;
|
||||
$vname = array_shift($vdef);
|
||||
$vname = "PMA_Validator::" . $vname;
|
||||
$args = array_merge(array($vid, &$arguments), $vdef);
|
||||
$r = call_user_func_array($vname, $args);
|
||||
|
||||
// merge results
|
||||
if (is_array($r)) {
|
||||
foreach ($r as $key => $error_list) {
|
||||
// skip empty values if $isPostSource is false
|
||||
if (! $isPostSource && empty($error_list)) {
|
||||
continue;
|
||||
}
|
||||
if (! isset($result[$key])) {
|
||||
$result[$key] = array();
|
||||
}
|
||||
$result[$key] = array_merge($result[$key], (array)$error_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restore original paths
|
||||
$new_result = array();
|
||||
foreach ($result as $k => $v) {
|
||||
$k2 = isset($key_map[$k]) ? $key_map[$k] : $k;
|
||||
$new_result[$k2] = $v;
|
||||
}
|
||||
return empty($new_result) ? true : $new_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty error handler, used to temporarily restore PHP internal error handler
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function null_error_handler()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that $php_errormsg variable will be registered in case of an error
|
||||
* and enables output buffering (when $start = true).
|
||||
* Called with $start = false disables output buffering end restores
|
||||
* html_errors and track_errors.
|
||||
*
|
||||
* @param boolean $start Whether to start buffering
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function testPHPErrorMsg($start = true)
|
||||
{
|
||||
static $old_html_errors, $old_track_errors, $old_error_reporting;
|
||||
static $old_display_errors;
|
||||
if ($start) {
|
||||
$old_html_errors = ini_get('html_errors');
|
||||
$old_track_errors = ini_get('track_errors');
|
||||
$old_display_errors = ini_get('display_errors');
|
||||
$old_error_reporting = error_reporting(E_ALL);
|
||||
ini_set('html_errors', false);
|
||||
ini_set('track_errors', true);
|
||||
ini_set('display_errors', true);
|
||||
set_error_handler("PMA_Validator", "null_error_handler");
|
||||
ob_start();
|
||||
} else {
|
||||
ob_end_clean();
|
||||
restore_error_handler();
|
||||
error_reporting($old_error_reporting);
|
||||
ini_set('html_errors', $old_html_errors);
|
||||
ini_set('track_errors', $old_track_errors);
|
||||
ini_set('display_errors', $old_display_errors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test database connection
|
||||
*
|
||||
* @param string $extension 'drizzle', 'mysql' or 'mysqli'
|
||||
* @param string $connect_type 'tcp' or 'socket'
|
||||
* @param string $host host name
|
||||
* @param string $port tcp port to use
|
||||
* @param string $socket socket to use
|
||||
* @param string $user username to use
|
||||
* @param string $pass password to use
|
||||
* @param string $error_key key to use in return array
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public static function testDBConnection(
|
||||
$extension,
|
||||
$connect_type,
|
||||
$host,
|
||||
$port,
|
||||
$socket,
|
||||
$user,
|
||||
$pass = null,
|
||||
$error_key = 'Server'
|
||||
) {
|
||||
// static::testPHPErrorMsg();
|
||||
$socket = empty($socket) || $connect_type == 'tcp' ? null : $socket;
|
||||
$port = empty($port) || $connect_type == 'socket' ? null : ':' . $port;
|
||||
$error = null;
|
||||
if ($extension == 'drizzle') {
|
||||
while (1) {
|
||||
$drizzle = @drizzle_create();
|
||||
if (! $drizzle) {
|
||||
$error = __('Could not initialize Drizzle connection library');
|
||||
break;
|
||||
}
|
||||
$conn = $socket
|
||||
? @drizzle_con_add_uds($socket, $user, $pass, null, 0)
|
||||
: @drizzle_con_add_tcp(
|
||||
$drizzle, $host, $port, $user, $pass, null, 0
|
||||
);
|
||||
if (! $conn) {
|
||||
$error = __('Could not connect to Drizzle server');
|
||||
drizzle_free($drizzle);
|
||||
break;
|
||||
}
|
||||
// connection object is set up but we have to send some query
|
||||
// to actually connect
|
||||
$res = @drizzle_query($conn, 'SELECT 1');
|
||||
if (! $res) {
|
||||
$error = __('Could not connect to Drizzle server');
|
||||
} else {
|
||||
drizzle_result_free($res);
|
||||
}
|
||||
drizzle_con_free($conn);
|
||||
drizzle_free($drizzle);
|
||||
break;
|
||||
}
|
||||
} else if ($extension == 'mysql') {
|
||||
$conn = @mysql_connect($host . $socket . $port, $user, $pass);
|
||||
if (! $conn) {
|
||||
$error = __('Could not connect to MySQL server');
|
||||
} else {
|
||||
mysql_close($conn);
|
||||
}
|
||||
} else {
|
||||
$conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
|
||||
if (! $conn) {
|
||||
$error = __('Could not connect to MySQL server');
|
||||
} else {
|
||||
mysqli_close($conn);
|
||||
}
|
||||
}
|
||||
// static::testPHPErrorMsg(false);
|
||||
if (isset($php_errormsg)) {
|
||||
$error .= " - $php_errormsg";
|
||||
}
|
||||
return is_null($error) ? true : array($error_key => $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate server config
|
||||
*
|
||||
* @param string $path path to config, not used
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validateServer($path, $values)
|
||||
{
|
||||
$result = array(
|
||||
'Server' => '',
|
||||
'Servers/1/user' => '',
|
||||
'Servers/1/SignonSession' => '',
|
||||
'Servers/1/SignonURL' => ''
|
||||
);
|
||||
$error = false;
|
||||
if ($values['Servers/1/auth_type'] == 'config'
|
||||
&& empty($values['Servers/1/user'])
|
||||
) {
|
||||
$result['Servers/1/user']
|
||||
= __('Empty username while using config authentication method');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/auth_type'] == 'signon'
|
||||
&& empty($values['Servers/1/SignonSession'])
|
||||
) {
|
||||
$result['Servers/1/SignonSession'] = __(
|
||||
'Empty signon session name '
|
||||
. 'while using signon authentication method'
|
||||
);
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/auth_type'] == 'signon'
|
||||
&& empty($values['Servers/1/SignonURL'])
|
||||
) {
|
||||
$result['Servers/1/SignonURL']
|
||||
= __('Empty signon URL while using signon authentication method');
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if (! $error && $values['Servers/1/auth_type'] == 'config') {
|
||||
$password = $values['Servers/1/nopassword'] ? null
|
||||
: $values['Servers/1/password'];
|
||||
$test = static::testDBConnection(
|
||||
$values['Servers/1/extension'],
|
||||
$values['Servers/1/connect_type'],
|
||||
$values['Servers/1/host'],
|
||||
$values['Servers/1/port'],
|
||||
$values['Servers/1/socket'],
|
||||
$values['Servers/1/user'],
|
||||
$password,
|
||||
'Server'
|
||||
);
|
||||
if ($test !== true) {
|
||||
$result = array_merge($result, $test);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate pmadb config
|
||||
*
|
||||
* @param string $path path to config, not used
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validatePMAStorage($path, $values)
|
||||
{
|
||||
$result = array(
|
||||
'Server_pmadb' => '',
|
||||
'Servers/1/controluser' => '',
|
||||
'Servers/1/controlpass' => ''
|
||||
);
|
||||
$error = false;
|
||||
|
||||
if ($values['Servers/1/pmadb'] == '') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
if ($values['Servers/1/controluser'] == '') {
|
||||
$result['Servers/1/controluser']
|
||||
= __('Empty phpMyAdmin control user while using pmadb');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/controlpass'] == '') {
|
||||
$result['Servers/1/controlpass']
|
||||
= __('Empty phpMyAdmin control user password while using pmadb');
|
||||
$error = true;
|
||||
}
|
||||
if (! $error) {
|
||||
$test = static::testDBConnection(
|
||||
$values['Servers/1/extension'], $values['Servers/1/connect_type'],
|
||||
$values['Servers/1/host'], $values['Servers/1/port'],
|
||||
$values['Servers/1/socket'], $values['Servers/1/controluser'],
|
||||
$values['Servers/1/controlpass'], 'Server_pmadb'
|
||||
);
|
||||
if ($test !== true) {
|
||||
$result = array_merge($result, $test);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates regular expression
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validateRegex($path, $values)
|
||||
{
|
||||
$result = array($path => '');
|
||||
|
||||
if ($values[$path] == '') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
static::testPHPErrorMsg();
|
||||
|
||||
$matches = array();
|
||||
// in libraries/List_Database.class.php _checkHideDatabase(),
|
||||
// a '/' is used as the delimiter for hide_db
|
||||
preg_match('/' . $values[$path] . '/', '', $matches);
|
||||
|
||||
static::testPHPErrorMsg(false);
|
||||
|
||||
if (isset($php_errormsg)) {
|
||||
$error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
|
||||
return array($path => $error);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates TrustedProxies field
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validateTrustedProxies($path, $values)
|
||||
{
|
||||
$result = array($path => array());
|
||||
|
||||
if (empty($values[$path])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (is_array($values[$path])) {
|
||||
// value already processed by FormDisplay::save
|
||||
$lines = array();
|
||||
foreach ($values[$path] as $ip => $v) {
|
||||
$lines[] = preg_match('/^-\d+$/', $ip)
|
||||
? $v
|
||||
: $ip . ': ' . $v;
|
||||
}
|
||||
} else {
|
||||
// AJAX validation
|
||||
$lines = explode("\n", $values[$path]);
|
||||
}
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
$matches = array();
|
||||
// we catch anything that may (or may not) be an IP
|
||||
if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
|
||||
$result[$path][] = __('Incorrect value:') . ' ' . $line;
|
||||
continue;
|
||||
}
|
||||
// now let's check whether we really have an IP address
|
||||
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
|
||||
&& filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false
|
||||
) {
|
||||
$ip = htmlspecialchars(trim($matches[1]));
|
||||
$result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests integer value
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
* @param bool $allow_neg allow negative values
|
||||
* @param bool $allow_zero allow zero
|
||||
* @param int $max_value max allowed value
|
||||
* @param string $error_string error message key:
|
||||
* $GLOBALS["strConfig$error_lang_key"]
|
||||
*
|
||||
* @return string empty string if test is successful
|
||||
*/
|
||||
public static function validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
$allow_neg,
|
||||
$allow_zero,
|
||||
$max_value,
|
||||
$error_string
|
||||
) {
|
||||
if ($values[$path] === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (intval($values[$path]) != $values[$path]
|
||||
|| (! $allow_neg && $values[$path] < 0)
|
||||
|| (! $allow_zero && $values[$path] == 0)
|
||||
|| $values[$path] > $max_value
|
||||
) {
|
||||
return $error_string;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates port number
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validatePortNumber($path, $values)
|
||||
{
|
||||
return array(
|
||||
$path => static::validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
false,
|
||||
false,
|
||||
65535,
|
||||
__('Not a valid port number')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates positive number
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validatePositiveNumber($path, $values)
|
||||
{
|
||||
return array(
|
||||
$path => static::validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
false,
|
||||
false,
|
||||
PHP_INT_MAX,
|
||||
__('Not a positive number')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates non-negative number
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validateNonNegativeNumber($path, $values)
|
||||
{
|
||||
return array(
|
||||
$path => static::validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
false,
|
||||
true,
|
||||
PHP_INT_MAX,
|
||||
__('Not a non-negative number')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates value according to given regular expression
|
||||
* Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
* @param string $regex regullar expression to match
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validateByRegex($path, $values, $regex)
|
||||
{
|
||||
$result = preg_match($regex, $values[$path]);
|
||||
return array($path => ($result ? '' : __('Incorrect value')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates upper bound for numeric inputs
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
* @param int $max_value maximal allowed value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validateUpperBound($path, $values, $max_value)
|
||||
{
|
||||
$result = $values[$path] <= $max_value;
|
||||
return array($path => ($result ? ''
|
||||
: sprintf(__('Value must be equal or lower than %s'), $max_value)));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -1,584 +0,0 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Various validation functions
|
||||
*
|
||||
* Validation function takes two argument: id for which it is called
|
||||
* and array of fields' values (usually values for entire formset, as defined
|
||||
* in forms.inc.php).
|
||||
* The function must always return an array with an error (or error array)
|
||||
* assigned to a form element (formset name or field path). Even if there are
|
||||
* no errors, key must be set with an empty value.
|
||||
*
|
||||
* Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns validator list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_config_get_validators()
|
||||
{
|
||||
static $validators = null;
|
||||
|
||||
if ($validators === null) {
|
||||
$cf = ConfigFile::getInstance();
|
||||
$validators = $cf->getDbEntry('_validators', array());
|
||||
if (!defined('PMA_SETUP')) {
|
||||
// not in setup script: load additional validators for user
|
||||
// preferences we need original config values not overwritten
|
||||
// by user preferences, creating a new PMA_Config instance is a
|
||||
// better idea than hacking into its code
|
||||
$org_cfg = $cf->getOrgConfigObj();
|
||||
$uvs = $cf->getDbEntry('_userValidators', array());
|
||||
foreach ($uvs as $field => $uv_list) {
|
||||
$uv_list = (array)$uv_list;
|
||||
foreach ($uv_list as &$uv) {
|
||||
if (!is_array($uv)) {
|
||||
continue;
|
||||
}
|
||||
for ($i = 1; $i < count($uv); $i++) {
|
||||
if (substr($uv[$i], 0, 6) == 'value:') {
|
||||
$uv[$i] = PMA_arrayRead(
|
||||
substr($uv[$i], 6), $org_cfg->settings
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$validators[$field] = isset($validators[$field])
|
||||
? array_merge((array)$validators[$field], $uv_list)
|
||||
: $uv_list;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs validation $validator_id on values $values and returns error list.
|
||||
*
|
||||
* Return values:
|
||||
* o array, keys - field path or formset id, values - array of errors
|
||||
* when $isPostSource is true values is an empty array to allow for error list
|
||||
* cleanup in HTML documen
|
||||
* o false - when no validators match name(s) given by $validator_id
|
||||
*
|
||||
* @param string|array $validator_id ID of validator(s) to run
|
||||
* @param array &$values Values to validate
|
||||
* @param bool $isPostSource tells whether $values are directly from
|
||||
* POST request
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
function PMA_config_validate($validator_id, &$values, $isPostSource)
|
||||
{
|
||||
// find validators
|
||||
$validator_id = (array) $validator_id;
|
||||
$validators = PMA_config_get_validators();
|
||||
$vids = array();
|
||||
$cf = ConfigFile::getInstance();
|
||||
foreach ($validator_id as &$vid) {
|
||||
$vid = $cf->getCanonicalPath($vid);
|
||||
if (isset($validators[$vid])) {
|
||||
$vids[] = $vid;
|
||||
}
|
||||
}
|
||||
if (empty($vids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create argument list with canonical paths and remember path mapping
|
||||
$arguments = array();
|
||||
$key_map = array();
|
||||
foreach ($values as $k => $v) {
|
||||
$k2 = $isPostSource ? str_replace('-', '/', $k) : $k;
|
||||
$k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2;
|
||||
$key_map[$k2] = $k;
|
||||
$arguments[$k2] = $v;
|
||||
}
|
||||
|
||||
// validate
|
||||
$result = array();
|
||||
foreach ($vids as $vid) {
|
||||
// call appropriate validation functions
|
||||
foreach ((array)$validators[$vid] as $validator) {
|
||||
$vdef = (array) $validator;
|
||||
$vname = array_shift($vdef);
|
||||
$args = array_merge(array($vid, &$arguments), $vdef);
|
||||
$r = call_user_func_array($vname, $args);
|
||||
|
||||
// merge results
|
||||
if (is_array($r)) {
|
||||
foreach ($r as $key => $error_list) {
|
||||
// skip empty values if $isPostSource is false
|
||||
if (! $isPostSource && empty($error_list)) {
|
||||
continue;
|
||||
}
|
||||
if (! isset($result[$key])) {
|
||||
$result[$key] = array();
|
||||
}
|
||||
$result[$key] = array_merge($result[$key], (array)$error_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restore original paths
|
||||
$new_result = array();
|
||||
foreach ($result as $k => $v) {
|
||||
$k2 = isset($key_map[$k]) ? $key_map[$k] : $k;
|
||||
$new_result[$k2] = $v;
|
||||
}
|
||||
return empty($new_result) ? true : $new_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty error handler, used to temporarily restore PHP internal error handler
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function PMA_null_error_handler()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that $php_errormsg variable will be registered in case of an error
|
||||
* and enables output buffering (when $start = true).
|
||||
* Called with $start = false disables output buffering end restores
|
||||
* html_errors and track_errors.
|
||||
*
|
||||
* @param boolean $start Whether to start buffering
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function PMA_testPHPErrorMsg($start = true)
|
||||
{
|
||||
static $old_html_errors, $old_track_errors, $old_error_reporting;
|
||||
static $old_display_errors;
|
||||
if ($start) {
|
||||
$old_html_errors = ini_get('html_errors');
|
||||
$old_track_errors = ini_get('track_errors');
|
||||
$old_display_errors = ini_get('display_errors');
|
||||
$old_error_reporting = error_reporting(E_ALL);
|
||||
ini_set('html_errors', false);
|
||||
ini_set('track_errors', true);
|
||||
ini_set('display_errors', true);
|
||||
set_error_handler("PMA_null_error_handler");
|
||||
ob_start();
|
||||
} else {
|
||||
ob_end_clean();
|
||||
restore_error_handler();
|
||||
error_reporting($old_error_reporting);
|
||||
ini_set('html_errors', $old_html_errors);
|
||||
ini_set('track_errors', $old_track_errors);
|
||||
ini_set('display_errors', $old_display_errors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test database connection
|
||||
*
|
||||
* @param string $extension 'drizzle', 'mysql' or 'mysqli'
|
||||
* @param string $connect_type 'tcp' or 'socket'
|
||||
* @param string $host host name
|
||||
* @param string $port tcp port to use
|
||||
* @param string $socket socket to use
|
||||
* @param string $user username to use
|
||||
* @param string $pass password to use
|
||||
* @param string $error_key key to use in return array
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
function PMA_testDBConnection(
|
||||
$extension,
|
||||
$connect_type,
|
||||
$host,
|
||||
$port,
|
||||
$socket,
|
||||
$user,
|
||||
$pass = null,
|
||||
$error_key = 'Server'
|
||||
) {
|
||||
// PMA_testPHPErrorMsg();
|
||||
$socket = empty($socket) || $connect_type == 'tcp' ? null : $socket;
|
||||
$port = empty($port) || $connect_type == 'socket' ? null : ':' . $port;
|
||||
$error = null;
|
||||
if ($extension == 'drizzle') {
|
||||
while (1) {
|
||||
$drizzle = @drizzle_create();
|
||||
if (! $drizzle) {
|
||||
$error = __('Could not initialize Drizzle connection library');
|
||||
break;
|
||||
}
|
||||
$conn = $socket
|
||||
? @drizzle_con_add_uds($socket, $user, $pass, null, 0)
|
||||
: @drizzle_con_add_tcp(
|
||||
$drizzle, $host, $port, $user, $pass, null, 0
|
||||
);
|
||||
if (! $conn) {
|
||||
$error = __('Could not connect to Drizzle server');
|
||||
drizzle_free($drizzle);
|
||||
break;
|
||||
}
|
||||
// connection object is set up but we have to send some query
|
||||
// to actually connect
|
||||
$res = @drizzle_query($conn, 'SELECT 1');
|
||||
if (! $res) {
|
||||
$error = __('Could not connect to Drizzle server');
|
||||
} else {
|
||||
drizzle_result_free($res);
|
||||
}
|
||||
drizzle_con_free($conn);
|
||||
drizzle_free($drizzle);
|
||||
break;
|
||||
}
|
||||
} else if ($extension == 'mysql') {
|
||||
$conn = @mysql_connect($host . $socket . $port, $user, $pass);
|
||||
if (! $conn) {
|
||||
$error = __('Could not connect to MySQL server');
|
||||
} else {
|
||||
mysql_close($conn);
|
||||
}
|
||||
} else {
|
||||
$conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
|
||||
if (! $conn) {
|
||||
$error = __('Could not connect to MySQL server');
|
||||
} else {
|
||||
mysqli_close($conn);
|
||||
}
|
||||
}
|
||||
// PMA_testPHPErrorMsg(false);
|
||||
if (isset($php_errormsg)) {
|
||||
$error .= " - $php_errormsg";
|
||||
}
|
||||
return is_null($error) ? true : array($error_key => $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate server config
|
||||
*
|
||||
* @param string $path path to config, not used
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validateServer($path, $values)
|
||||
{
|
||||
$result = array(
|
||||
'Server' => '',
|
||||
'Servers/1/user' => '',
|
||||
'Servers/1/SignonSession' => '',
|
||||
'Servers/1/SignonURL' => ''
|
||||
);
|
||||
$error = false;
|
||||
if ($values['Servers/1/auth_type'] == 'config'
|
||||
&& empty($values['Servers/1/user'])
|
||||
) {
|
||||
$result['Servers/1/user']
|
||||
= __('Empty username while using config authentication method');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/auth_type'] == 'signon'
|
||||
&& empty($values['Servers/1/SignonSession'])
|
||||
) {
|
||||
$result['Servers/1/SignonSession'] = __(
|
||||
'Empty signon session name '
|
||||
. 'while using signon authentication method'
|
||||
);
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/auth_type'] == 'signon'
|
||||
&& empty($values['Servers/1/SignonURL'])
|
||||
) {
|
||||
$result['Servers/1/SignonURL']
|
||||
= __('Empty signon URL while using signon authentication method');
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if (! $error && $values['Servers/1/auth_type'] == 'config') {
|
||||
$password = $values['Servers/1/nopassword'] ? null
|
||||
: $values['Servers/1/password'];
|
||||
$test = PMA_testDBConnection(
|
||||
$values['Servers/1/extension'],
|
||||
$values['Servers/1/connect_type'],
|
||||
$values['Servers/1/host'],
|
||||
$values['Servers/1/port'],
|
||||
$values['Servers/1/socket'],
|
||||
$values['Servers/1/user'],
|
||||
$password,
|
||||
'Server'
|
||||
);
|
||||
if ($test !== true) {
|
||||
$result = array_merge($result, $test);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate pmadb config
|
||||
*
|
||||
* @param string $path path to config, not used
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validatePMAStorage($path, $values)
|
||||
{
|
||||
$result = array(
|
||||
'Server_pmadb' => '',
|
||||
'Servers/1/controluser' => '',
|
||||
'Servers/1/controlpass' => ''
|
||||
);
|
||||
$error = false;
|
||||
|
||||
if ($values['Servers/1/pmadb'] == '') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
if ($values['Servers/1/controluser'] == '') {
|
||||
$result['Servers/1/controluser']
|
||||
= __('Empty phpMyAdmin control user while using pmadb');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/controlpass'] == '') {
|
||||
$result['Servers/1/controlpass']
|
||||
= __('Empty phpMyAdmin control user password while using pmadb');
|
||||
$error = true;
|
||||
}
|
||||
if (! $error) {
|
||||
$test = PMA_testDBConnection(
|
||||
$values['Servers/1/extension'], $values['Servers/1/connect_type'],
|
||||
$values['Servers/1/host'], $values['Servers/1/port'],
|
||||
$values['Servers/1/socket'], $values['Servers/1/controluser'],
|
||||
$values['Servers/1/controlpass'], 'Server_pmadb'
|
||||
);
|
||||
if ($test !== true) {
|
||||
$result = array_merge($result, $test);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates regular expression
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validateRegex($path, $values)
|
||||
{
|
||||
$result = array($path => '');
|
||||
|
||||
if ($values[$path] == '') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
PMA_testPHPErrorMsg();
|
||||
|
||||
$matches = array();
|
||||
// in libraries/List_Database.class.php _checkHideDatabase(),
|
||||
// a '/' is used as the delimiter for hide_db
|
||||
preg_match('/' . $values[$path] . '/', '', $matches);
|
||||
|
||||
PMA_testPHPErrorMsg(false);
|
||||
|
||||
if (isset($php_errormsg)) {
|
||||
$error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
|
||||
return array($path => $error);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates TrustedProxies field
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validateTrustedProxies($path, $values)
|
||||
{
|
||||
$result = array($path => array());
|
||||
|
||||
if (empty($values[$path])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (is_array($values[$path])) {
|
||||
// value already processed by FormDisplay::save
|
||||
$lines = array();
|
||||
foreach ($values[$path] as $ip => $v) {
|
||||
$lines[] = preg_match('/^-\d+$/', $ip)
|
||||
? $v
|
||||
: $ip . ': ' . $v;
|
||||
}
|
||||
} else {
|
||||
// AJAX validation
|
||||
$lines = explode("\n", $values[$path]);
|
||||
}
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
$matches = array();
|
||||
// we catch anything that may (or may not) be an IP
|
||||
if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
|
||||
$result[$path][] = __('Incorrect value:') . ' ' . $line;
|
||||
continue;
|
||||
}
|
||||
// now let's check whether we really have an IP address
|
||||
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
|
||||
&& filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false
|
||||
) {
|
||||
$ip = htmlspecialchars(trim($matches[1]));
|
||||
$result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests integer value
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
* @param bool $allow_neg allow negative values
|
||||
* @param bool $allow_zero allow zero
|
||||
* @param int $max_value max allowed value
|
||||
* @param string $error_string error message key:
|
||||
* $GLOBALS["strConfig$error_lang_key"]
|
||||
*
|
||||
* @return string empty string if test is successful
|
||||
*/
|
||||
function PMA_validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
$allow_neg,
|
||||
$allow_zero,
|
||||
$max_value,
|
||||
$error_string
|
||||
) {
|
||||
if ($values[$path] === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (intval($values[$path]) != $values[$path]
|
||||
|| (! $allow_neg && $values[$path] < 0)
|
||||
|| (! $allow_zero && $values[$path] == 0)
|
||||
|| $values[$path] > $max_value
|
||||
) {
|
||||
return $error_string;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates port number
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validatePortNumber($path, $values)
|
||||
{
|
||||
return array(
|
||||
$path => PMA_validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
false,
|
||||
false,
|
||||
65535,
|
||||
__('Not a valid port number')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates positive number
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validatePositiveNumber($path, $values)
|
||||
{
|
||||
return array(
|
||||
$path => PMA_validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
false,
|
||||
false,
|
||||
PHP_INT_MAX,
|
||||
__('Not a positive number')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates non-negative number
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validateNonNegativeNumber($path, $values)
|
||||
{
|
||||
return array(
|
||||
$path => PMA_validateNumber(
|
||||
$path,
|
||||
$values,
|
||||
false,
|
||||
true,
|
||||
PHP_INT_MAX,
|
||||
__('Not a non-negative number')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates value according to given regular expression
|
||||
* Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
* @param string $regex regullar expression to match
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validateByRegex($path, $values, $regex)
|
||||
{
|
||||
$result = preg_match($regex, $values[$path]);
|
||||
return array($path => ($result ? '' : __('Incorrect value')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates upper bound for numeric inputs
|
||||
*
|
||||
* @param string $path path to config
|
||||
* @param array $values config values
|
||||
* @param int $max_value maximal allowed value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function PMA_validateUpperBound($path, $values, $max_value)
|
||||
{
|
||||
$result = $values[$path] <= $max_value;
|
||||
return array($path => ($result ? ''
|
||||
: sprintf(__('Value must be equal or lower than %s'), $max_value)));
|
||||
}
|
||||
?>
|
||||
@ -1180,7 +1180,7 @@ function PMA_getSelectOptionForUpload($vkey, $column)
|
||||
|
||||
if ($files === false) {
|
||||
return '<font color="red">' . __('Error') . '</font><br />' . "\n"
|
||||
. __('The directory you set for upload work cannot be reached') . "\n";
|
||||
. __('The directory you set for upload work cannot be reached.') . "\n";
|
||||
} elseif (!empty($files)) {
|
||||
return "<br />\n"
|
||||
. '<i>' . __('Or') . '</i>' . ' '
|
||||
|
||||
@ -43,13 +43,21 @@ abstract class PluginObserver implements SplObserver
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
*
|
||||
* TODO Declare this function abstract, removing its body,
|
||||
* as soon as we drop support for PHP 5.3.x.
|
||||
* See bug #3625
|
||||
*
|
||||
* @param SplSubject $subject The PluginManager notifying the observer
|
||||
* of an update.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public abstract function update (SplSubject $subject);
|
||||
|
||||
public function update (SplSubject $subject)
|
||||
{
|
||||
throw new Exception(
|
||||
'PluginObserver::update must be overridden in child classes.'
|
||||
);
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
|
||||
@ -659,7 +659,7 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
$conn_error = __('Access denied');
|
||||
} elseif (! empty($GLOBALS['no_activity'])) {
|
||||
$conn_error = sprintf(
|
||||
__('No activity within %s seconds; please log in again'),
|
||||
__('No activity within %s seconds; please log in again.'),
|
||||
$GLOBALS['cfg']['LoginCookieValidity']
|
||||
);
|
||||
} elseif ($GLOBALS['dbi']->getError()) {
|
||||
|
||||
@ -251,7 +251,7 @@ class AuthenticationSignon extends AuthenticationPlugin
|
||||
$_SESSION['PMA_single_signon_error_message'] = __('Access denied');
|
||||
} elseif (! empty($GLOBALS['no_activity'])) {
|
||||
$_SESSION['PMA_single_signon_error_message'] = sprintf(
|
||||
__('No activity within %s seconds; please log in again'),
|
||||
__('No activity within %s seconds; please log in again.'),
|
||||
$GLOBALS['cfg']['LoginCookieValidity']
|
||||
);
|
||||
} elseif ($GLOBALS['dbi']->getError()) {
|
||||
|
||||
@ -173,7 +173,7 @@ function Swekey_auth_error()
|
||||
$res = Swekey_CheckOtp($swekey_id, $_SESSION['SWEKEY']['RND_TOKEN'], $swekey_otp);
|
||||
unset($_SESSION['SWEKEY']['RND_TOKEN']);
|
||||
if (! $res) {
|
||||
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
|
||||
$result = __('Hardware authentication failed!') . ' (' . Swekey_GetLastError() . ')';
|
||||
} else {
|
||||
$_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'] = $swekey_id;
|
||||
$_SESSION['SWEKEY']['FORCE_USER'] = $_SESSION['SWEKEY']['VALID_SWEKEYS'][$swekey_id];
|
||||
@ -193,7 +193,7 @@ function Swekey_auth_error()
|
||||
|
||||
$_SESSION['SWEKEY']['RND_TOKEN'] = Swekey_GetFastRndToken();
|
||||
if (strlen($_SESSION['SWEKEY']['RND_TOKEN']) != 64) {
|
||||
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
|
||||
$result = __('Hardware authentication failed!') . ' (' . Swekey_GetLastError() . ')';
|
||||
unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
|
||||
}
|
||||
|
||||
|
||||
@ -480,7 +480,7 @@ function PMA_sqlQueryFormUpload()
|
||||
echo '</div>';
|
||||
|
||||
if ($files === false) {
|
||||
$errors[] = PMA_Message::error(__('The directory you set for upload work cannot be reached'));
|
||||
$errors[] = PMA_Message::error(__('The directory you set for upload work cannot be reached.'));
|
||||
} elseif (!empty($files)) {
|
||||
echo '<div class="formelement">';
|
||||
echo '<strong>' . __('web server upload directory:') .'</strong>' . "\n";
|
||||
|
||||
@ -130,7 +130,7 @@ function PMA_SQP_throwError($message, $sql)
|
||||
. __(
|
||||
'There seems to be an error in your SQL query. The MySQL server '
|
||||
. 'error output below, if there is any, may also help you in '
|
||||
. 'diagnosing the problem'
|
||||
. 'diagnosing the problem.'
|
||||
)
|
||||
. '</p>' . "\n"
|
||||
. '<pre>' . "\n"
|
||||
|
||||
@ -175,6 +175,10 @@ function PMA_readUserprefsFieldNames(array $forms = null)
|
||||
{
|
||||
static $names;
|
||||
|
||||
if (defined('TESTSUITE')) {
|
||||
$names = null;
|
||||
}
|
||||
|
||||
// return cached results
|
||||
if ($names !== null) {
|
||||
return $names;
|
||||
|
||||
1440
po/be@latin.po
1440
po/be@latin.po
File diff suppressed because it is too large
Load Diff
1460
po/en_GB.po
1460
po/en_GB.po
File diff suppressed because it is too large
Load Diff
1444
po/phpmyadmin.pot
1444
po/phpmyadmin.pot
File diff suppressed because it is too large
Load Diff
1450
po/pt_BR.po
1450
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1452
po/sr@latin.po
1452
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
1472
po/uz@latin.po
1472
po/uz@latin.po
File diff suppressed because it is too large
Load Diff
1446
po/zh_CN.po
1446
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1442
po/zh_TW.po
1442
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,10 @@ function process_formset(FormDisplay $form_display)
|
||||
// drop post data
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
|
||||
if (!defined('TESTSUITE')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
if (!$form_display->process(false)) {
|
||||
// handle form view and failed POST
|
||||
@ -55,7 +58,9 @@ function process_formset(FormDisplay $form_display)
|
||||
// drop post data
|
||||
header('HTTP/1.1 303 See Other');
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
if (!defined('TESTSUITE')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,37 +106,11 @@ function PMA_version_check()
|
||||
// version check messages should always be visible so let's make
|
||||
// a unique message id each time we run it
|
||||
$message_id = uniqid('version_check');
|
||||
// wait 3s at most for server response, it's enough to get information
|
||||
// from a working server
|
||||
$connection_timeout = 3;
|
||||
|
||||
$url = 'http://phpmyadmin.net/home_page/version.php';
|
||||
$context = stream_context_create(
|
||||
array(
|
||||
'http' => array('timeout' => $connection_timeout)
|
||||
)
|
||||
);
|
||||
$data = @file_get_contents($url, null, $context);
|
||||
if ($data === false) {
|
||||
if (function_exists('curl_init')) {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $connection_timeout);
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
} else {
|
||||
messages_set(
|
||||
'error',
|
||||
$message_id,
|
||||
__('Version check'),
|
||||
__('Neither URL wrapper nor CURL is available. Version check is not possible.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Fetch data
|
||||
$version_data = PMA_Util::getLatestVersion();
|
||||
|
||||
if (empty($data)) {
|
||||
if (empty($version_data)) {
|
||||
messages_set(
|
||||
'error',
|
||||
$message_id,
|
||||
@ -146,17 +120,10 @@ function PMA_version_check()
|
||||
return;
|
||||
}
|
||||
|
||||
/* Format: version\ndate\n(download\n)* */
|
||||
$data_list = explode("\n", $data);
|
||||
$version = $version_data->version;
|
||||
$date = $version_data->date;
|
||||
|
||||
if (count($data_list) > 1) {
|
||||
$version = $data_list[0];
|
||||
$date = $data_list[1];
|
||||
} else {
|
||||
$version = $date = '';
|
||||
}
|
||||
|
||||
$version_upstream = version_to_int($version);
|
||||
$version_upstream = PMA_Util::versionToInt($version);
|
||||
if ($version_upstream === false) {
|
||||
messages_set(
|
||||
'error',
|
||||
@ -167,7 +134,7 @@ function PMA_version_check()
|
||||
return;
|
||||
}
|
||||
|
||||
$version_local = version_to_int($GLOBALS['PMA_Config']->get('PMA_VERSION'));
|
||||
$version_local = PMA_Util::versionToInt($GLOBALS['PMA_Config']->get('PMA_VERSION'));
|
||||
if ($version_local === false) {
|
||||
messages_set(
|
||||
'error',
|
||||
@ -206,55 +173,6 @@ function PMA_version_check()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates numerical equivalent of phpMyAdmin version string
|
||||
*
|
||||
* @param string $version version
|
||||
*
|
||||
* @return mixed false on failure, integer on success
|
||||
*/
|
||||
function version_to_int($version)
|
||||
{
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)((\.|-(pl|rc|dev|beta|alpha))(\d+)?(-dev)?)?$/', $version, $matches)) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($matches[6])) {
|
||||
switch ($matches[6]) {
|
||||
case 'pl':
|
||||
$added = 60;
|
||||
break;
|
||||
case 'rc':
|
||||
$added = 30;
|
||||
break;
|
||||
case 'beta':
|
||||
$added = 20;
|
||||
break;
|
||||
case 'alpha':
|
||||
$added = 10;
|
||||
break;
|
||||
case 'dev':
|
||||
$added = 0;
|
||||
break;
|
||||
default:
|
||||
messages_set(
|
||||
'notice',
|
||||
'version_match',
|
||||
__('Version check'),
|
||||
'Unknown version part: ' . htmlspecialchars($matches[6])
|
||||
);
|
||||
$added = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$added = 50; // for final
|
||||
}
|
||||
if (!empty($matches[7])) {
|
||||
$added = $added + $matches[7];
|
||||
}
|
||||
return $matches[1] * 1000000 + $matches[2] * 10000 + $matches[3] * 100 + $added;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether config file is readable/writable
|
||||
*
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
require './lib/common.inc.php';
|
||||
|
||||
$validators = array();
|
||||
require './libraries/config/validate.lib.php';
|
||||
require './libraries/config/Validator.class.php';
|
||||
|
||||
header('Content-type: application/json');
|
||||
|
||||
@ -22,7 +22,7 @@ if (!($values instanceof stdClass)) {
|
||||
PMA_fatalError(__('Wrong data'));
|
||||
}
|
||||
$values = (array)$values;
|
||||
$result = PMA_config_validate($vids, $values, true);
|
||||
$result = PMA_Validator::config_validate($vids, $values, true);
|
||||
if ($result === false) {
|
||||
$result = 'Wrong data or no validation for ' . $vids;
|
||||
}
|
||||
|
||||
@ -97,4 +97,68 @@ class PMA_Util_Test extends PHPUnit_Framework_TestCase
|
||||
PMA_Util::pageselector("pma", 3)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test version checking
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @group large
|
||||
*/
|
||||
public function testGetLatestVersion()
|
||||
{
|
||||
$GLOBALS['cfg']['VersionCheckProxyUrl'] = '';
|
||||
$version = PMA_Util::getLatestVersion();
|
||||
$this->assertNotEmpty($version->version);
|
||||
$this->assertNotEmpty($version->date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test version to int conversion.
|
||||
*
|
||||
* @param string $version Version string
|
||||
* @param int $numberic Integer matching version
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @dataProvider dataVersions
|
||||
*/
|
||||
public function testVersionToInt($version, $numeric)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$numeric,
|
||||
PMA_Util::versionToInt($version)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for version parsing
|
||||
*
|
||||
* @return array with test data
|
||||
*/
|
||||
public function dataVersions()
|
||||
{
|
||||
return array(
|
||||
array('1.0.0', 1000050),
|
||||
array('2.0.0.2-dev', 2000002),
|
||||
array('3.4.2.1', 3040251),
|
||||
array('3.4.2-dev3', 3040203),
|
||||
array('3.4.2-dev', 3040200),
|
||||
array('3.4.2-pl', 3040260),
|
||||
array('3.4.2-pl3', 3040263),
|
||||
array('4.4.2-rc22', 4040252),
|
||||
array('4.4.2-rc', 4040230),
|
||||
array('4.4.22-beta22', 4042242),
|
||||
array('4.4.22-beta', 4042220),
|
||||
array('4.4.21-alpha22', 4042132),
|
||||
array('4.4.20-alpha', 4042010),
|
||||
array('4.40.20-alpha-dev', 4402010),
|
||||
array('4.4a', 4000050),
|
||||
array('4.4.4-test', 4040400),
|
||||
array('4.1.0', 4010050),
|
||||
array('4.0.1.3', 4000153),
|
||||
array('4.1-dev', 4010000),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
593
test/classes/config/PMA_FormDisplay_test.php
Normal file
593
test/classes/config/PMA_FormDisplay_test.php
Normal file
@ -0,0 +1,593 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* tests for FormDisplay class in config folder
|
||||
*
|
||||
* @package PhpMyAdmin-test
|
||||
*/
|
||||
|
||||
require_once 'libraries/config/ConfigFile.class.php';
|
||||
require_once 'libraries/config/FormDisplay.class.php';
|
||||
require_once 'libraries/Util.class.php';
|
||||
require_once 'libraries/Theme.class.php';
|
||||
require_once 'libraries/Config.class.php';
|
||||
require_once 'libraries/php-gettext/gettext.inc';
|
||||
require_once 'libraries/user_preferences.lib.php';
|
||||
|
||||
/**
|
||||
* Tests for PMA_FormDisplay class
|
||||
*
|
||||
* @package PhpMyAdmin-test
|
||||
*/
|
||||
class PMA_FormDisplay_Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Configures global environment.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function setup()
|
||||
{
|
||||
$_SESSION['PMA_Theme'] = new PMA_Theme();
|
||||
$GLOBALS['pmaThemePath'] = $_SESSION['PMA_Theme']->getPath();
|
||||
$GLOBALS['pmaThemeImage'] = 'theme/';
|
||||
$GLOBALS['PMA_Config'] = new PMA_Config();
|
||||
$GLOBALS['PMA_Config']->enableBc();
|
||||
$GLOBALS['server'] = 0;
|
||||
$this->object = new FormDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown for test cases
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
unset($this->object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::__constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormDisplayContructor()
|
||||
{
|
||||
$this->assertCount(
|
||||
5,
|
||||
$this->readAttribute($this->object, '_jsLangStrings')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::registerForm
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRegisterForm()
|
||||
{
|
||||
$reflection = new \ReflectionClass('FormDisplay');
|
||||
|
||||
$attrForms = $reflection->getProperty('_forms');
|
||||
$attrForms->setAccessible(true);
|
||||
|
||||
$array = array(
|
||||
"Servers" => array(
|
||||
"1" => array(
|
||||
'test' => 1,
|
||||
1 => ':group:end'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->object->registerForm('pma_testform', $array, 2);
|
||||
$_forms = $attrForms->getValue($this->object);
|
||||
$this->assertInstanceOf(
|
||||
'Form',
|
||||
$_forms['pma_testform']
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
"Servers/2/test" => "Servers/1/test",
|
||||
"Servers/2/:group:end:0" => "Servers/1/:group:end:0"
|
||||
),
|
||||
$this->readAttribute($this->object, '_systemPaths')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
"Servers/2/test" => "Servers-2-test",
|
||||
"Servers/2/:group:end:0" => "Servers-2-:group:end:0"
|
||||
),
|
||||
$this->readAttribute($this->object, '_translatedPaths')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::process
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testProcess()
|
||||
{
|
||||
$this->assertFalse(
|
||||
$this->object->process(true, true)
|
||||
);
|
||||
|
||||
$this->object = $this->getMockBuilder('FormDisplay')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('save'))
|
||||
->getMock();
|
||||
|
||||
$attrForms = new \ReflectionProperty('FormDisplay', '_forms');
|
||||
$attrForms->setAccessible(true);
|
||||
$attrForms->setValue($this->object, array(1, 2, 3));
|
||||
|
||||
$this->object->expects($this->once())
|
||||
->method('save')
|
||||
->with(array(0, 1, 2), false)
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$this->assertTrue(
|
||||
$this->object->process(false, false)
|
||||
);
|
||||
|
||||
$attrForms->setValue($this->object, array());
|
||||
|
||||
$this->assertFalse(
|
||||
$this->object->process(false, false)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::displayErrors
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDisplayErrors()
|
||||
{
|
||||
$reflection = new \ReflectionClass('FormDisplay');
|
||||
|
||||
$attrIsValidated = $reflection->getProperty('_isValidated');
|
||||
$attrIsValidated->setAccessible(true);
|
||||
$attrIsValidated->setValue($this->object, true);
|
||||
|
||||
$attrIsValidated = $reflection->getProperty('_errors');
|
||||
$attrIsValidated->setAccessible(true);
|
||||
$attrIsValidated->setValue($this->object, array());
|
||||
|
||||
$this->assertNull(
|
||||
$this->object->displayErrors()
|
||||
);
|
||||
|
||||
$arr = array(
|
||||
"Servers/1/test" => array('e1'),
|
||||
"foobar" => array('e2', 'e3')
|
||||
);
|
||||
|
||||
$sysArr = array(
|
||||
"Servers/1/test" => "Servers/1/test2"
|
||||
);
|
||||
|
||||
$attrSystemPaths = $reflection->getProperty('_systemPaths');
|
||||
$attrSystemPaths->setAccessible(true);
|
||||
$attrSystemPaths->setValue($this->object, $sysArr);
|
||||
|
||||
$attrIsValidated->setValue($this->object, $arr);
|
||||
|
||||
$GLOBALS['strConfigForm_foobar'] = 'foobar123';
|
||||
|
||||
$this->expectOutputString(
|
||||
'<dl><dt>Servers_test2_name</dt>' .
|
||||
'<dd>e1</dd></dl><dl><dt>foobar123</dt><dd>' .
|
||||
'e2</dd><dd>e3</dd></dl>'
|
||||
);
|
||||
|
||||
$this->object->displayErrors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::fixErrors
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFixErrors()
|
||||
{
|
||||
$reflection = new \ReflectionClass('FormDisplay');
|
||||
|
||||
$attrIsValidated = $reflection->getProperty('_isValidated');
|
||||
$attrIsValidated->setAccessible(true);
|
||||
$attrIsValidated->setValue($this->object, true);
|
||||
|
||||
$attrIsValidated = $reflection->getProperty('_errors');
|
||||
$attrIsValidated->setAccessible(true);
|
||||
$attrIsValidated->setValue($this->object, array());
|
||||
|
||||
$this->assertNull(
|
||||
$this->object->fixErrors()
|
||||
);
|
||||
|
||||
$arr = array(
|
||||
"Servers/1/test" => array('e1'),
|
||||
"Servers/2/test" => array('e2', 'e3'),
|
||||
"Servers/3/test" => array()
|
||||
);
|
||||
|
||||
$sysArr = array(
|
||||
"Servers/1/test" => "Servers/1/connect_type"
|
||||
);
|
||||
|
||||
$attrSystemPaths = $reflection->getProperty('_systemPaths');
|
||||
$attrSystemPaths->setAccessible(true);
|
||||
$attrSystemPaths->setValue($this->object, $sysArr);
|
||||
|
||||
$attrIsValidated->setValue($this->object, $arr);
|
||||
|
||||
$this->object->fixErrors();
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'Servers' => array(
|
||||
'1' => array(
|
||||
'test' => 'tcp'
|
||||
)
|
||||
)
|
||||
),
|
||||
$_SESSION['ConfigFile0']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::_validateSelect
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testValidateSelect()
|
||||
{
|
||||
$attrValidateSelect = new \ReflectionMethod(
|
||||
'FormDisplay',
|
||||
'_validateSelect'
|
||||
);
|
||||
$attrValidateSelect->setAccessible(true);
|
||||
|
||||
$arr = array('foo' => 'var');
|
||||
$value = 'foo';
|
||||
$this->assertTrue(
|
||||
$attrValidateSelect->invokeArgs(
|
||||
$this->object,
|
||||
array(&$value, $arr)
|
||||
)
|
||||
);
|
||||
|
||||
$arr = array('' => 'foobar');
|
||||
$value = null;
|
||||
$this->assertTrue(
|
||||
$attrValidateSelect->invokeArgs(
|
||||
$this->object,
|
||||
array(&$value, $arr)
|
||||
)
|
||||
);
|
||||
$this->assertEquals(
|
||||
"string",
|
||||
gettype($value)
|
||||
);
|
||||
|
||||
$arr = array(0 => 'foobar');
|
||||
$value = 0;
|
||||
$this->assertTrue(
|
||||
$attrValidateSelect->invokeArgs(
|
||||
$this->object,
|
||||
array(&$value, $arr)
|
||||
)
|
||||
);
|
||||
|
||||
$arr = array('1' => 'foobar');
|
||||
$value = 0;
|
||||
$this->assertFalse(
|
||||
$attrValidateSelect->invokeArgs(
|
||||
$this->object,
|
||||
array(&$value, $arr)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::hasErrors
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHasErrors()
|
||||
{
|
||||
$attrErrors = new \ReflectionProperty('FormDisplay', '_errors');
|
||||
$attrErrors->setAccessible(true);
|
||||
|
||||
$this->assertFalse(
|
||||
$this->object->hasErrors()
|
||||
);
|
||||
|
||||
$attrErrors->setValue(
|
||||
$this->object,
|
||||
array(1, 2)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$this->object->hasErrors()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::getDocLink
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetDocLink()
|
||||
{
|
||||
$this->assertEquals(
|
||||
"./url.php?url=http%3A%2F%2Fdocs.phpmyadmin.net%2Fen%2Flatest%2F" .
|
||||
"config.html%23cfg_Servers_3_test_2_&server=0&lang=en&" .
|
||||
";token=token",
|
||||
$this->object->getDocLink("Servers/3/test/2/")
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'',
|
||||
$this->object->getDocLink("Import")
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'',
|
||||
$this->object->getDocLink("Export")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::getWikiLink
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetWikiLink()
|
||||
{
|
||||
$this->assertEquals(
|
||||
"./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" .
|
||||
"AllowDeny.29&server=0&lang=en&token=token",
|
||||
$this->object->getWikiLink('Servers/1/AllowDeny')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" .
|
||||
"format_2&server=0&lang=en&token=token",
|
||||
$this->object->getWikiLink('Import/format')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" .
|
||||
"test&server=0&lang=en&token=token",
|
||||
$this->object->getWikiLink('Export/test')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::_getOptName
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetOptName()
|
||||
{
|
||||
$method = new \ReflectionMethod('FormDisplay', '_getOptName');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$this->assertEquals(
|
||||
"Servers_",
|
||||
$method->invoke($this->object, "Servers/1/")
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"Servers_23_",
|
||||
$method->invoke($this->object, "Servers/1/23/")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::_loadUserprefsInfo
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLoadUserprefsInfo()
|
||||
{
|
||||
$method = new \ReflectionMethod('FormDisplay', '_loadUserprefsInfo');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$attrUserprefs = new \ReflectionProperty(
|
||||
'FormDisplay',
|
||||
'_userprefsDisallow'
|
||||
);
|
||||
|
||||
$attrUserprefs->setAccessible(true);
|
||||
$method->invoke($this->object, null);
|
||||
$this->assertEquals(
|
||||
array(),
|
||||
$attrUserprefs->getValue($this->object)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for FormDisplay::_setComments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSetComments()
|
||||
{
|
||||
if (!function_exists('runkit_constant_redefine')) {
|
||||
$this->markTestSkipped('Cannot redefine constant');
|
||||
}
|
||||
|
||||
$method = new \ReflectionMethod('FormDisplay', '_setComments');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// recoding
|
||||
$opts['values']['iconv'] = 'testIconv';
|
||||
$opts['values']['recode'] = 'testRecode';
|
||||
|
||||
$expect = $opts;
|
||||
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('RecodingEngine', &$opts)
|
||||
);
|
||||
|
||||
$expect['comment'] = '';
|
||||
if (!function_exists('iconv')) {
|
||||
$expect['values']['iconv'] .= " (unavailable)";
|
||||
$expect['comment'] = '"iconv" requires iconv extension';
|
||||
}
|
||||
if (!function_exists('recode_string')) {
|
||||
$expect['values']['recode'] .= " (unavailable)";
|
||||
$expect['comment'] .= ($expect['comment'] ? ", " : '') .
|
||||
'"recode" requires recode extension';
|
||||
}
|
||||
$expect['comment_warning'] = 1;
|
||||
|
||||
$this->assertEquals(
|
||||
$expect,
|
||||
$opts
|
||||
);
|
||||
|
||||
// ZipDump, GZipDump, BZipDump
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('ZipDump', &$opts)
|
||||
);
|
||||
|
||||
$comment = '';
|
||||
if (!function_exists("zip_open")) {
|
||||
$comment = 'Compressed import will not work due to missing function ' .
|
||||
'zip_open.';
|
||||
}
|
||||
if (!function_exists("gzcompress")) {
|
||||
$comment .= ($comment ? '; ' : '') . 'Compressed export will not work ' .
|
||||
'due to missing function gzcompress.';
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
$comment,
|
||||
$opts['comment']
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$opts['comment_warning']
|
||||
);
|
||||
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('GZipDump', &$opts)
|
||||
);
|
||||
|
||||
$comment = '';
|
||||
if (!function_exists("gzopen")) {
|
||||
$comment = 'Compressed import will not work due to missing function ' .
|
||||
'gzopen.';
|
||||
}
|
||||
if (!function_exists("gzencode")) {
|
||||
$comment .= ($comment ? '; ' : '') . 'Compressed export will not work ' .
|
||||
'due to missing function gzencode.';
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
$comment,
|
||||
$opts['comment']
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$opts['comment_warning']
|
||||
);
|
||||
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('BZipDump', &$opts)
|
||||
);
|
||||
|
||||
$comment = '';
|
||||
if (!function_exists("gzopen")) {
|
||||
$comment = 'Compressed import will not work due to missing function ' .
|
||||
'bzopen.';
|
||||
}
|
||||
if (!function_exists("bzcompress")) {
|
||||
$comment .= ($comment ? '; ' : '') . 'Compressed export will not work ' .
|
||||
'due to missing function bzcompress.';
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
$comment,
|
||||
$opts['comment']
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$opts['comment_warning']
|
||||
);
|
||||
|
||||
// SQLValidate
|
||||
|
||||
$GLOBALS['cfg']['SQLValidator']['use'] = false;
|
||||
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('SQLQuery/Validate', &$opts)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"SQL Validator is disabled",
|
||||
$opts['comment']
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$opts['comment_warning']
|
||||
);
|
||||
|
||||
if (defined('PMA_SETUP')) {
|
||||
runkit_constant_remove('PMA_SETUP');
|
||||
}
|
||||
|
||||
$GLOBALS['cfg']['MaxDbList'] = 10;
|
||||
$GLOBALS['cfg']['MaxTableList'] = 10;
|
||||
$GLOBALS['cfg']['QueryHistoryMax'] = 10;
|
||||
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('MaxDbList', &$opts)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"maximum 10",
|
||||
$opts['comment']
|
||||
);
|
||||
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('MaxTableList', &$opts)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"maximum 10",
|
||||
$opts['comment']
|
||||
);
|
||||
|
||||
$method->invokeArgs(
|
||||
$this->object,
|
||||
array('QueryHistoryMax', &$opts)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"maximum 10",
|
||||
$opts['comment']
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
@ -13,9 +13,15 @@ require_once 'libraries/Theme.class.php';
|
||||
require_once 'libraries/Config.class.php';
|
||||
require_once 'libraries/php-gettext/gettext.inc';
|
||||
|
||||
|
||||
/**
|
||||
* Tests for PMA_Form class
|
||||
*
|
||||
* @package PhpMyAdmin-test
|
||||
*/
|
||||
class PMA_Form_Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Configures global environment.
|
||||
*
|
||||
@ -29,22 +35,261 @@ class PMA_Form_Test extends PHPUnit_Framework_TestCase
|
||||
$GLOBALS['PMA_Config'] = new PMA_Config();
|
||||
$GLOBALS['PMA_Config']->enableBc();
|
||||
$GLOBALS['server'] = 0;
|
||||
$this->object = new Form('pma_form_name', array('pma_form1','pma_form2'), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown for test cases
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
unset($this->object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Form::__constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testContructor()
|
||||
{
|
||||
$form = new Form('pma_form_name', array('pma_form1','pma_form2'), 1);
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$form->index
|
||||
$this->object->index
|
||||
);
|
||||
$this->assertEquals(
|
||||
'pma_form_name',
|
||||
$form->name
|
||||
$this->object->name
|
||||
);
|
||||
$this->assertArrayHasKey(
|
||||
'pma_form1',
|
||||
$form->fields
|
||||
$this->object->fields
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Form::getOptionType
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetOptionType()
|
||||
{
|
||||
$attrFieldsTypes = new \ReflectionProperty('Form', '_fieldsTypes');
|
||||
$attrFieldsTypes->setAccessible(true);
|
||||
$attrFieldsTypes->setValue(
|
||||
$this->object,
|
||||
array("7" => "Seven")
|
||||
);
|
||||
|
||||
$this->assertNull(
|
||||
$this->object->getOptionType("123/4/5/6")
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"Seven",
|
||||
$this->object->getOptionType("123/4/5/7")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Form::getOptionValueList
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetOptionValueList()
|
||||
{
|
||||
$this->assertEquals(
|
||||
array('NHibernate C# DO', 'NHibernate XML'),
|
||||
$this->object->getOptionValueList("Export/codegen_format")
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'auto' => 'auto',
|
||||
'1' => 1,
|
||||
'0' => 0
|
||||
),
|
||||
$this->object->getOptionValueList("OBGzip")
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'none' => 'Nowhere',
|
||||
'left' => 'Left',
|
||||
'right' => 'Right',
|
||||
'both' => "Both"
|
||||
),
|
||||
$this->object->getOptionValueList("RowActionLinks")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Form::_readFormPathsCallback
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadFormPathsCallBack()
|
||||
{
|
||||
$reflection = new \ReflectionClass('Form');
|
||||
$method = $reflection->getMethod('_readFormPathsCallback');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$array = array(
|
||||
"foo" => array(
|
||||
"bar" => array(
|
||||
'test' => 1,
|
||||
1 => ':group:end'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$method->invoke($this->object, $array, 'foo', 'pref');
|
||||
|
||||
$result = $this->object->fields;
|
||||
|
||||
$this->assertCount(
|
||||
4,
|
||||
$result
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"pma_form1",
|
||||
$result['pma_form1']
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"pma_form2",
|
||||
$result['pma_form2']
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"preffoo/foo/bar/test",
|
||||
$result[0]
|
||||
);
|
||||
|
||||
// needs regexp because the counter is static
|
||||
|
||||
$this->assertRegExp(
|
||||
'/^preffoo\/foo\/bar\/\:group\:end\:\d+$/',
|
||||
$result[1]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Form::readFormPaths
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadFormPaths()
|
||||
{
|
||||
$reflection = new \ReflectionClass('Form');
|
||||
$method = $reflection->getMethod('readFormPaths');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$array = array(
|
||||
"foo" => array(
|
||||
"bar" => array(
|
||||
'test' => 1,
|
||||
1 => ':group:end'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$method->invoke($this->object, $array);
|
||||
|
||||
$result = $this->object->fields;
|
||||
|
||||
$this->assertCount(
|
||||
2,
|
||||
$result
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
"foo/bar/test",
|
||||
$result['test']
|
||||
);
|
||||
|
||||
unset($result['test']);
|
||||
|
||||
// needs regexp because the counter is static
|
||||
|
||||
$keys = array_keys($result);
|
||||
$key = $keys[0];
|
||||
|
||||
$this->assertRegexp(
|
||||
"/^\:group\:end\:(\d+)$/",
|
||||
$key
|
||||
);
|
||||
|
||||
preg_match("/^\:group\:end\:(\d+)$/", $key, $matches);
|
||||
$digit = $matches[1];
|
||||
|
||||
$this->assertEquals(
|
||||
"foo/bar/:group:end:" . $digit,
|
||||
$result[':group:end:' . $digit]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Form::readTypes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadTypes()
|
||||
{
|
||||
$reflection = new \ReflectionClass('Form');
|
||||
$method = $reflection->getMethod('readTypes');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$this->object->fields = array(
|
||||
"pma_form1" => "Servers/1/port",
|
||||
"pma_form2" => "Servers/1/connect_type",
|
||||
":group:end:0" => "preffoo/foo/bar/test",
|
||||
"1" => "preffoo/foo/bar/:group:end:0"
|
||||
);
|
||||
|
||||
$attrFieldsTypes = $reflection->getProperty('_fieldsTypes');
|
||||
$attrFieldsTypes->setAccessible(true);
|
||||
|
||||
$method->invoke($this->object, null);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
"pma_form1" => "integer",
|
||||
"pma_form2" => "select",
|
||||
":group:end:0" => "group",
|
||||
"1" => "NULL"
|
||||
),
|
||||
$attrFieldsTypes->getValue($this->object)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Form::loadForm
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLoadForm()
|
||||
{
|
||||
$this->object = $this->getMockBuilder('Form')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('readFormPaths', 'readTypes'))
|
||||
->getMock();
|
||||
|
||||
$this->object->expects($this->exactly(1))
|
||||
->method('readFormPaths')
|
||||
->with('testForm');
|
||||
|
||||
$this->object->expects($this->exactly(1))
|
||||
->method('readTypes');
|
||||
|
||||
$this->object->loadForm('pmaform', 'testForm');
|
||||
|
||||
$this->assertEquals(
|
||||
'pmaform',
|
||||
$this->object->name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,11 @@ class PMA_ConfigFile_Test extends PHPUnit_Framework_TestCase
|
||||
|
||||
unset($_SESSION[$this->readAttribute($this->object, "_id")]);
|
||||
unset($this->object);
|
||||
|
||||
// reset the instance
|
||||
$attr_instance = new ReflectionProperty("ConfigFile", "_instance");
|
||||
$attr_instance->setAccessible(true);
|
||||
$attr_instance->setValue(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -748,7 +753,7 @@ class PMA_ConfigFile_Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->assertEquals(
|
||||
null,
|
||||
$this->object->getServerName('foobar123')
|
||||
$this->object->removeServer(1)
|
||||
);
|
||||
|
||||
$objectID = $this->readAttribute($this->object, "_id");
|
||||
@ -902,7 +907,8 @@ class PMA_ConfigFile_Test extends PHPUnit_Framework_TestCase
|
||||
$attrReadMapping->setValue(
|
||||
$this->object,
|
||||
array(
|
||||
"2" => "two"
|
||||
"2" => "two",
|
||||
"3" => "foobar"
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user