Merge branch 'master' of https://github.com/phpmyadmin/phpmyadmin into UT_plu_parse

This commit is contained in:
adamgsoc2013 2013-07-12 23:23:36 +08:00
commit 35417fe3ed
106 changed files with 56465 additions and 53924 deletions

View File

@ -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)

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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 + ')';

View File

@ -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');

View File

@ -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(

View File

@ -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;
}
}
?>

View File

@ -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

View File

@ -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();

View File

@ -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);

View 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)));
}
}
?>

View File

@ -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)));
}
?>

View File

@ -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>' . ' '

View File

@ -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 ~~~~~~~~~~~~~~~~~~~~ */

View File

@ -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()) {

View File

@ -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()) {

View File

@ -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
}

View 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";

View File

@ -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"

View File

@ -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/af.po

File diff suppressed because it is too large Load Diff

1442
po/ar.po

File diff suppressed because it is too large Load Diff

1440
po/az.po

File diff suppressed because it is too large Load Diff

1440
po/be.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1468
po/bg.po

File diff suppressed because it is too large Load Diff

2579
po/bn.po

File diff suppressed because it is too large Load Diff

1466
po/br.po

File diff suppressed because it is too large Load Diff

1438
po/bs.po

File diff suppressed because it is too large Load Diff

1446
po/ca.po

File diff suppressed because it is too large Load Diff

1444
po/ckb.po

File diff suppressed because it is too large Load Diff

1449
po/cs.po

File diff suppressed because it is too large Load Diff

1452
po/cy.po

File diff suppressed because it is too large Load Diff

1445
po/da.po

File diff suppressed because it is too large Load Diff

1452
po/de.po

File diff suppressed because it is too large Load Diff

1456
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1464
po/es.po

File diff suppressed because it is too large Load Diff

1448
po/et.po

File diff suppressed because it is too large Load Diff

1442
po/eu.po

File diff suppressed because it is too large Load Diff

1448
po/fa.po

File diff suppressed because it is too large Load Diff

1479
po/fi.po

File diff suppressed because it is too large Load Diff

1458
po/fr.po

File diff suppressed because it is too large Load Diff

1491
po/gl.po

File diff suppressed because it is too large Load Diff

1438
po/he.po

File diff suppressed because it is too large Load Diff

1452
po/hi.po

File diff suppressed because it is too large Load Diff

1442
po/hr.po

File diff suppressed because it is too large Load Diff

1460
po/hu.po

File diff suppressed because it is too large Load Diff

1444
po/hy.po

File diff suppressed because it is too large Load Diff

1455
po/ia.po

File diff suppressed because it is too large Load Diff

1446
po/id.po

File diff suppressed because it is too large Load Diff

1466
po/it.po

File diff suppressed because it is too large Load Diff

1448
po/ja.po

File diff suppressed because it is too large Load Diff

1448
po/ka.po

File diff suppressed because it is too large Load Diff

1444
po/kk.po

File diff suppressed because it is too large Load Diff

1444
po/kn.po

File diff suppressed because it is too large Load Diff

1442
po/ko.po

File diff suppressed because it is too large Load Diff

1454
po/lt.po

File diff suppressed because it is too large Load Diff

1440
po/lv.po

File diff suppressed because it is too large Load Diff

1440
po/mk.po

File diff suppressed because it is too large Load Diff

1444
po/ml.po

File diff suppressed because it is too large Load Diff

1440
po/mn.po

File diff suppressed because it is too large Load Diff

1438
po/ms.po

File diff suppressed because it is too large Load Diff

1474
po/nb.po

File diff suppressed because it is too large Load Diff

1457
po/nl.po

File diff suppressed because it is too large Load Diff

1444
po/pa.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1462
po/pl.po

File diff suppressed because it is too large Load Diff

1466
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1450
po/ro.po

File diff suppressed because it is too large Load Diff

1460
po/ru.po

File diff suppressed because it is too large Load Diff

1460
po/si.po

File diff suppressed because it is too large Load Diff

1444
po/sk.po

File diff suppressed because it is too large Load Diff

1450
po/sl.po

File diff suppressed because it is too large Load Diff

1438
po/sq.po

File diff suppressed because it is too large Load Diff

1440
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1446
po/sv.po

File diff suppressed because it is too large Load Diff

1444
po/ta.po

File diff suppressed because it is too large Load Diff

1448
po/te.po

File diff suppressed because it is too large Load Diff

1442
po/th.po

File diff suppressed because it is too large Load Diff

1444
po/tk.po

File diff suppressed because it is too large Load Diff

1453
po/tr.po

File diff suppressed because it is too large Load Diff

1440
po/tt.po

File diff suppressed because it is too large Load Diff

1440
po/ug.po

File diff suppressed because it is too large Load Diff

1487
po/uk.po

File diff suppressed because it is too large Load Diff

1452
po/ur.po

File diff suppressed because it is too large Load Diff

1474
po/uz.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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;
}
}
}
}

View File

@ -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
*

View File

@ -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;
}

View File

@ -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),
);
}
}

View 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_&amp;server=0&amp;lang=en&amp" .
";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&amp;server=0&amp;lang=en&amp;token=token",
$this->object->getWikiLink('Servers/1/AllowDeny')
);
$this->assertEquals(
"./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" .
"format_2&amp;server=0&amp;lang=en&amp;token=token",
$this->object->getWikiLink('Import/format')
);
$this->assertEquals(
"./url.php?url=http%3A%2F%2Fwiki.phpmyadmin.net%2Fpma%2FConfig%23" .
"test&amp;server=0&amp;lang=en&amp;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']
);
}
}
?>

View File

@ -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
);
}
}

View File

@ -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