parametrized validators

valdiation by regular expressions
shorter text fields for numeric inputs
This commit is contained in:
Crack
2010-07-17 11:39:30 +02:00
parent c5bef4d2da
commit afca401bc8
7 changed files with 107 additions and 83 deletions

View File

@@ -169,7 +169,9 @@ var validate = {};
// form validator list
var validators = {
// regexp: numeric value
_regexp_numeric: new RegExp('^[0-9]+$'),
_regexp_numeric: /^[0-9]+$/,
// regexp: extract parts from PCRE expression
_regexp_pcre_extract: /(.)(.*)\1(.*)?/,
/**
* Validates positive number
*
@@ -210,41 +212,20 @@ var validators = {
return result;
},
/**
* DefaultPropDisplay validator
* Validates value according to given regular expression
*
* @param {boolean} isKeyUp
* @param {string} regexp
*/
validate_DefaultPropDisplay: function(isKeyUp) {
validate_by_regex: function(isKeyUp, regexp) {
if (isKeyUp && this.value == '') {
return true;
}
var valid = this.value.match(/^(?:horizontal|vertical|[0-9]+)$/) != null;
// convert PCRE regexp
var parts = regexp.match(validators._regexp_pcre_extract);
var valid = this.value.match(new RegExp(parts[2], parts[3])) != null;
return valid ? true : PMA_messages['error_invalid_value']
},
/**
* Validates string length - must be 1 character long
*
* @param {boolean} isKeyUp
*/
validate_str1: function (isKeyUp) {
if (isKeyUp && this.value == '') {
return true;
}
var result = this.value.length == 1;
return result ? true : PMA_messages['error_invalid_value'];
},
/**
* Validates string length - must be 0 or 1 character long
*
* @param {boolean} isKeyUp
*/
validate_str01: function (isKeyUp) {
if (isKeyUp && this.value == '') {
return true;
}
var result = this.value.length <= 1;
return result ? true : PMA_messages['error_invalid_value'];
},
// field validators
_field: {
},
@@ -259,7 +240,7 @@ var validators = {
* @param {String} id field id
* @param {String} type validator (key in validators object)
* @param {boolean} onKeyUp whether fire on key up
* @param {object} params validation function parameters
* @param {Array} params validation function parameters
*/
function validateField(id, type, onKeyUp, params) {
if (typeof validators[type] == 'undefined') {
@@ -390,7 +371,11 @@ function validate_field(field, isKeyUp, errors) {
errors[field_id] = [];
var functions = getFieldValidators(field_id, isKeyUp);
for (var i = 0; i < functions.length; i++) {
var result = functions[i][0].apply(field[0], [isKeyUp, functions[i][1]]);
var args = functions[i][1] != null
? functions[i][1].slice(0)
: [];
args.unshift(isKeyUp);
var result = functions[i][0].apply(field[0], args);
if (result !== true) {
if (typeof result == 'string') {
result = [result];

View File

@@ -27,6 +27,7 @@ $cfg_db['Servers'] = array(1 => array(
$cfg_db['RecodingEngine'] = array('auto', 'iconv', 'recode');
$cfg_db['DefaultCharset'] = $GLOBALS['cfg']['AvailableCharsets'];
$cfg_db['OBGzip'] = array('auto', true, false);
$cfg_db['MemoryLimit'] = 'short_string';
$cfg_db['ShowTooltipAliasTB'] = array('nested', true, false);
$cfg_db['DisplayDatabasesList'] = array('auto', true, false);
$cfg_db['LeftLogoLinkWindow'] = array('main', 'new');
@@ -36,6 +37,8 @@ $cfg_db['LeftDefaultTabTable'] = array(
'tbl_select.php', // search page
'tbl_change.php', // insert row page
'sql.php'); // browse page
$cfg_db['LeftFrameDBSeparator'] = 'short_string';
$cfg_db['LeftFrameTableSeparator'] = 'short_string';
$cfg_db['NavigationBarIconic'] = array(true, false, 'both');
$cfg_db['Order'] = array('ASC', 'DESC', 'SMART');
$cfg_db['ProtectBinary'] = array(false, 'blob', 'all');
@@ -77,6 +80,12 @@ $cfg_db['Import']['sql_compatibility'] = $cfg_db['Export']['sql_compatibility']
// can't be read by POSTGRESQL (see our bug #1596328)
//'POSTGRESQL',
'TRADITIONAL');
$cfg_db['Import']['csv_terminated'] = 'short_string';
$cfg_db['Import']['csv_enclosed'] = 'short_string';
$cfg_db['Import']['csv_escaped'] = 'short_string';
$cfg_db['Import']['ldi_terminated'] = 'short_string';
$cfg_db['Import']['ldi_enclosed'] = 'short_string';
$cfg_db['Import']['ldi_escaped'] = 'short_string';
$cfg_db['Import']['ldi_local_option'] = array('auto', true, false);
$cfg_db['Export']['format'] = array('codegen', 'csv', 'excel', 'htmlexcel',
'htmlword', 'latex', 'ods', 'odt', 'pdf', 'sql', 'texytext', 'xls', 'xml',
@@ -84,9 +93,21 @@ $cfg_db['Export']['format'] = array('codegen', 'csv', 'excel', 'htmlexcel',
$cfg_db['Export']['compression'] = array('none', 'zip', 'gzip', 'bzip2');
$cfg_db['Export']['charset'] = array_merge(array(''), $GLOBALS['cfg']['AvailableCharsets']);
$cfg_db['Export']['codegen_format'] = array('#', 'NHibernate C# DO', 'NHibernate XML');
$cfg_db['Export']['csv_separator'] = 'short_string';
$cfg_db['Export']['csv_terminated'] = 'short_string';
$cfg_db['Export']['csv_enclosed'] = 'short_string';
$cfg_db['Export']['csv_escaped'] = 'short_string';
$cfg_db['Export']['csv_null'] = 'short_string';
$cfg_db['Export']['excel_null'] = 'short_string';
$cfg_db['Export']['excel_edition'] = array('win' => 'Windows',
'mac_excel2003' => 'Excel 2003 / Macintosh', 'mac_excel2008' => 'Excel 2008 / Macintosh');
$cfg_db['Export']['sql_type'] = array('INSERT', 'UPDATE', 'REPLACE');
$cfg_db['Export']['xls_null'] = 'short_string';
$cfg_db['Export']['xlsx_null'] = 'short_string';
$cfg_db['Export']['htmlword_null'] = 'short_string';
$cfg_db['Export']['ods_null'] = 'short_string';
$cfg_db['Export']['odt_null'] = 'short_string';
$cfg_db['Export']['texytext_null'] = 'short_string';
/**
* Default values overrides
@@ -104,16 +125,16 @@ $cfg_db['_overrides']['Servers/1/extension'] = extension_loaded('mysqli')
$cfg_db['_validators'] = array(
'CharTextareaCols' => 'validate_positive_number',
'CharTextareaRows' => 'validate_positive_number',
'DefaultPropDisplay' => 'validate_DefaultPropDisplay',
'DefaultPropDisplay' => array('validate_by_regex', '/^(?:horizontal|vertical|\d+)$/'),
'ExecTimeLimit' => 'validate_non_negative_number',
'Export/sql_max_query_size' => 'validate_positive_number',
'ForeignKeyMaxLimit' => 'validate_positive_number',
'Import/csv_enclosed' => 'validate_str01',
'Import/csv_escaped' => 'validate_str1',
'Import/csv_terminated' => 'validate_str1',
'Import/ldi_enclosed' => 'validate_str01',
'Import/ldi_escaped' => 'validate_str1',
'Import/ldi_terminated' => 'validate_str1',
'Import/csv_enclosed' => array('validate_by_regex', '/^.?$/'),
'Import/csv_escaped' => array('validate_by_regex', '/^.$/'),
'Import/csv_terminated' => array('validate_by_regex', '/^.$/'),
'Import/ldi_enclosed' => array('validate_by_regex', '/^.?$/'),
'Import/ldi_escaped' => array('validate_by_regex', '/^.$/'),
'Import/ldi_terminated' => array('validate_by_regex', '/^.$/'),
'Import/skip_queries' => 'validate_non_negative_number',
'InsertRows' => 'validate_positive_number',
'LeftFrameTableLevel' => 'validate_positive_number',
@@ -124,7 +145,7 @@ $cfg_db['_validators'] = array(
'MaxCharactersInDisplayedSQL' => 'validate_positive_number',
'MaxRows' => 'validate_positive_number',
'MaxTableList' => 'validate_positive_number',
'MemoryLimit' => 'validate_non_negative_number',
'MemoryLimit' => array('validate_by_regex', '/^\d+(?:[kmg])?$/i'),
'QueryHistoryMax' => 'validate_positive_number',
'QueryWindowWidth' => 'validate_positive_number',
'QueryWindowHeight' => 'validate_positive_number',

View File

@@ -151,7 +151,7 @@ class FormDisplay
}
// run validation
$errors = validate($paths, $values, false);
$errors = PMA_config_validate($paths, $values, false);
// change error keys from canonical paths to work paths
if (is_array($errors) && count($errors) > 0) {
@@ -259,10 +259,10 @@ class FormDisplay
foreach ($this->js_lang_strings as $strName => $strValue) {
$js_lang[] = "'$strName': '" . PMA_jsFormat($strValue, false) . '\'';
}
$js[] = '$.extend(PMA_messages, {' . implode(",\n\t", $js_lang) . '})';
$js[] = "$.extend(PMA_messages, {\n\t" . implode(",\n\t", $js_lang) . '})';
}
$js[] = '$.extend(defaultValues, {' . implode(",\n\t", $js_default) . '})';
$js[] = "$.extend(defaultValues, {\n\t" . implode(",\n\t", $js_default) . '})';
display_js($js);
}
@@ -309,11 +309,12 @@ class FormDisplay
case 'string':
$type = 'text';
break;
case 'double':
$type = 'text';
case 'short_string':
$type = 'short_text';
break;
case 'double':
case 'integer':
$type = 'text';
$type = 'number_text';
break;
case 'boolean':
$type = 'checkbox';
@@ -353,6 +354,8 @@ class FormDisplay
$js_line = '\'' . $translated_path . '\': ';
switch ($type) {
case 'text':
case 'short_text':
case 'number_text':
$js_line .= '\'' . PMA_escapeJsString($value_default) . '\'';
break;
case 'checkbox':
@@ -474,16 +477,17 @@ class FormDisplay
foreach ($form->fields as $field => $system_path) {
$work_path = array_search($system_path, $this->system_paths);
$key = $this->translated_paths[$work_path];
$type = $form->getOptionType($field);
// skip groups
if ($form->getOptionType($field) == 'group') {
if ($type == 'group') {
continue;
}
// ensure the value is set
if (!isset($_POST[$key])) {
// checkboxes aren't set by browsers if they're off
if ($form->getOptionType($field) == 'boolean') {
if ($type == 'boolean') {
$_POST[$key] = false;
} else {
$this->errors[$form->name][] = sprintf(
@@ -505,7 +509,6 @@ class FormDisplay
}
// cast variables to correct type
$type = $form->getOptionType($field);
switch ($type) {
case 'double':
settype($_POST[$key], 'float');
@@ -524,6 +527,7 @@ class FormDisplay
}
break;
case 'string':
case 'short_string':
$_POST[$key] = trim($_POST[$key]);
break;
case 'array':

View File

@@ -43,7 +43,8 @@ function display_form_top($action = null, $method = 'post', $hidden_fields = nul
*
* @param array $tabs
*/
function display_tabs_top($tabs) {
function display_tabs_top($tabs)
{
?>
<ul class="tabs">
<?php foreach ($tabs as $tab_id => $tab_name): ?>
@@ -163,7 +164,15 @@ function display_input($path, $name, $description = '', $type, $value, $value_is
<?php
switch ($type) {
case 'text':
echo '<input type="text" size="50" ' . $name_id . $field_class
echo '<input type="text" size="60" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'short_text':
echo '<input type="text" size="25" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'number_text':
echo '<input type="text" size="15" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'checkbox':
@@ -318,7 +327,8 @@ function display_fieldset_bottom_simple()
/**
* Closes form tabs
*/
function display_tabs_bottom() {
function display_tabs_bottom()
{
echo "</div>\n";
}
@@ -337,8 +347,16 @@ function display_form_bottom()
* @param string $validator
* @param array $js_array
*/
function js_validate($field_id, $validator, &$js_array) {
$js_array[] = "validateField('$field_id', '$validator', true)";
function js_validate($field_id, $validator, &$js_array)
{
$validator = (array)$validator;
$v_name = array_shift($validator);
$v_args = array();
foreach ($validator as $arg) {
$v_args[] = PMA_escapeJsString($arg);
}
$v_args = $v_args ? ", ['" . implode("', '", $v_args) . "']" : '';
$js_array[] = "validateField('$field_id', '$v_name', true$v_args)";
}
/**
@@ -346,7 +364,8 @@ function js_validate($field_id, $validator, &$js_array) {
*
* @param array $js_array
*/
function display_js($js_array) {
function display_js($js_array)
{
if (empty($js_array)) {
return;
}
@@ -363,7 +382,8 @@ function display_js($js_array) {
* @param string $name
* @param array $error_list
*/
function display_errors($name, $error_list) {
function display_errors($name, $error_list)
{
echo '<dl>';
echo '<dt>' . htmlspecialchars($name) . '</dt>';
foreach ($error_list as $error) {

View File

@@ -30,7 +30,7 @@ $forms['Servers']['Server'] = array('Servers' => array(1 => array(
'connect_type',
'extension',
'compress',
'auth_type',
'auth_type' => ':group',
'auth_http_realm',
'user',
'password',

View File

@@ -29,7 +29,7 @@
* @param bool $isPostSource tells whether $values are directly from POST request
* @return bool|array
*/
function validate($validator_id, &$values, $isPostSource)
function PMA_config_validate($validator_id, &$values, $isPostSource)
{
// find validators
$cf = ConfigFile::getInstance();
@@ -59,7 +59,12 @@ function validate($validator_id, &$values, $isPostSource)
// validate
$result = array();
foreach ($vids as $vid) {
$r = call_user_func($validators[$vid], $vid, $arguments);
// call appropriate validation function
$vdef = (array) $validators[$vid];
$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) {
@@ -299,7 +304,6 @@ function validate_trusted_proxies($path, $values)
return $result;
}
/**
* Tests integer value
*
@@ -361,41 +365,31 @@ function validate_non_negative_number($path, $values)
}
/**
* Validates DefaultPropDisplay field
* Validates value according to given regular expression
* Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
*
* @param string $path
* @param array $values
* @return array
* @param array $values
* @param string $regex
* @return void
*/
function validate_DefaultPropDisplay($path, $values)
function validate_by_regex($path, $values, $regex)
{
$result = preg_match('/^(?:horizontal|vertical|\d+)$/', $values[$path]);
$result = preg_match($regex, $values[$path]);
return array($path => ($result ? '' : __('Incorrect value')));
}
/**
* Validates string length - must be 1 character long
* Validates upper bound for numeric inputs
*
* @param string $path
* @param array $values
* @param array $values
* @param int $max_value
* @return array
*/
function validate_str1($path, $values)
function validate_upper_bound($path, $values, $max_value)
{
$result = strlen($values[$path]) == 1;
return array($path => ($result ? '' : __('Incorrect value')));
}
/**
* Validates string length - must be 0 or 1 character long
*
* @param string $path
* @param array $values
* @return array
*/
function validate_str01($path, $values)
{
$result = strlen($values[$path]) <= 1;
return array($path => ($result ? '' : __('Incorrect value')));
$result = $values[$path] <= $max_value;
return array($path => ($result ? '' : sprintf(__('Value must be equal or lower than %s'), $max_value)));
}
?>

View File

@@ -24,7 +24,7 @@ if (!($values instanceof stdClass)) {
die('Wrong data');
}
$values = (array)$values;
$result = validate($vids, $values, true);
$result = PMA_config_validate($vids, $values, true);
if ($result === false) {
$result = 'Wrong data or no validation for ' . $vids;
}