From 26c3fce74ffd9151531baa3d1d6303358bc28fde Mon Sep 17 00:00:00 2001 From: taggon Date: Wed, 15 Jun 2011 07:40:53 +0000 Subject: [PATCH] Fix a bug related to checking content's length. git-svn-id: http://xe-core.googlecode.com/svn/branches/1.5.0@8480 201d5d3c-b55e-5fd7-737f-ddc643e51545 --- classes/validator/Validator.class.php | 2 +- common/js/xml_js_filter.js | 85 ++++++++++++++-------- tests/classes/validator/ValidatorTest.php | 26 +++++-- tests/classes/validator/insertDocument.xml | 14 ++++ 4 files changed, 89 insertions(+), 38 deletions(-) create mode 100644 tests/classes/validator/insertDocument.xml diff --git a/classes/validator/Validator.class.php b/classes/validator/Validator.class.php index 8d2a258fa..21da30572 100644 --- a/classes/validator/Validator.class.php +++ b/classes/validator/Validator.class.php @@ -158,7 +158,7 @@ class Validator $strlength = $this->_has_mb_func?mb_strlen($value,'utf-8'):$this->mbStrLen($value); } - if($min > ($is_min_b?$strbytes:$strlength) || $max < ($is_max_b?$strbytes:$strlength)) return $this->error($key, 'outofrange'); + if(($min && $min > ($is_min_b?$strbytes:$strlength)) || ($max && $max < ($is_max_b?$strbytes:$strlength))) return $this->error($key, 'outofrange'); } // equalto diff --git a/common/js/xml_js_filter.js b/common/js/xml_js_filter.js index f03278515..4e8398c28 100644 --- a/common/js/xml_js_filter.js +++ b/common/js/xml_js_filter.js @@ -85,48 +85,58 @@ var Validator = xe.createApp('Validator', { }); }, API_VALIDATE : function(sender, params) { - var self = this, result = true, form = params[0], filter=null, callback=null; + var result = true, form = params[0], filter=null, callback=null; + var name, el, val, mod, len, lenb, max, min, maxb, minb, rules, e_el, e_val, i, c, r, result; if (form.elements['_filter']) filter = form.elements['_filter'].value; if (!filter) return true; if ($.isFunction(callbacks[filter])) callback = callbacks[filter]; filter = $.extend({}, filters[filter.toLowerCase()] || {}, extras); - $.each(filter, function(name) { - var _el = form.elements[name]; + for(name in filter) { + if(!filter.hasOwnProperty(name)) continue; - if (!_el) return true; + f = filter[name]; + el = form.elements[name]; + val = el?$.trim(get_value($(el))):''; + mod = (f.modifier||'')+','; - var el = $(_el), val = $.trim(get_value(el)); - var minlen = parseInt(this.minlength) || 0; - var maxlen = parseInt(this.maxlength) || 0; - var rule = (this.rule || '').split(','); + if(!val) { + if(f['default']) val = f['default']; + if(f.required) return this.cast('ALERT', [form, name, 'isnull']) && false; + else continue; + } - if (this.required && !val) return (result = (!!self.cast('ALERT', [form, name, 'isnull']) && false)); - if (!this.required && !val) return (result = true); - if ((minlen && val.length < minlen) || (maxlen && val.length > maxlen)) return (result = (!!self.cast('ALERT', [form, name, 'outofrange', minlen, maxlen]) && false)); + min = parseInt(f.minlength) || 0; + max = parseInt(f.maxlength) || 0; + minb = /b$/.test(f.minlength||''); + maxb = /b$/.test(f.maxlength||''); + len = val.length; + if(minb || maxb) lenb = get_bytes(val); + if((min && min > (minb?lenb:len)) || (max && max < (maxb?lenb:len))) { + return this.cast('ALERT', [form, name, 'outofrange', min, max]) && false; + } - if (this.equalto) { - var eq_val = get_value($(form.elements[this.equalto])); - if (eq_val != val) return (result = (!!self.cast('ALERT', [form, name, 'equalto']) && false)); + if(f.equalto) { + e_el = form.elements[f.equalto]; + e_val = e_el?$.trim(get_value($(e_el))):''; + if(e_el && e_val !== val) { + return this.cast('ALERT', [form, name, 'equalto']) && false; + } } + + rules = (f.rule || '').split(','); + for(i=0,c=rules.length; i < c; i++) { + if(!(r = rules[i])) continue; - if (rule) { - $.each(rule, function(i,r) { - if (!r) return true; - - var ret = self.cast('APPLY_RULE', [r, val]); - if (!ret) { - self.cast('ALERT', [form, name, 'invalid_'+this]); - return (result = false); - } - }); + result = this.cast('APPLY_RULE', [r, val]); + if(mod.indexOf('not,') > -1) result = !result; + if(!result) { + return this.cast('ALERT', [form, name, 'invalid_'+r]) && false; + } } + } - if (!result) return false; - }); - - if (!result) return false; if ($.isFunction(callback)) return callback(form); return true; @@ -185,9 +195,10 @@ var Validator = xe.createApp('Validator', { var name = params[0]; var value = params[1]; - if (typeof(rules[name]) == 'undefined') return true; // no filter - if ($.isFunction(rules[name])) return rules[name](value); - if (rules[name] instanceof RegExp) return rules[name].test(value); + if(typeof(rules[name]) == 'undefined') return true; // no filter + if($.isFunction(rules[name])) return rules[name](value); + if(rules[name] instanceof RegExp) return rules[name].test(value); + if($.isArray(rules[name])) return ($.inArray(value, rules[name]) > -1); return true; }, @@ -274,6 +285,16 @@ function get_value(elem) { } } +function get_bytes(str) { + str += ''; + if(!str.length) return 0; + + str = encodeURI(str); + var c = str.split('%').length - 1; + + return str.length - c*2; +} + })(jQuery); /** @@ -335,4 +356,4 @@ function legacy_filter(filter_name, form, module, act, callback, responses, conf v.cast('VALIDATE', [form, filter_name]); return false; -} \ No newline at end of file +} diff --git a/tests/classes/validator/ValidatorTest.php b/tests/classes/validator/ValidatorTest.php index 246f5b346..7b713c3f6 100644 --- a/tests/classes/validator/ValidatorTest.php +++ b/tests/classes/validator/ValidatorTest.php @@ -1,10 +1,11 @@ assertEquals( 'idididid', Context::get('userid') ); } + public function testLength() { + $vd = new Validator(); + + $vd->addFilter('field1', array('length'=>'3:')); + $this->assertFalse( $vd->validate(array('field1'=>'ab')) ); + $this->assertTrue( $vd->validate(array('field1'=>'abc')) ); + $this->assertTrue( $vd->validate(array('field1'=>'abcd')) ); + } + public function testCustomRule() { } @@ -78,12 +88,18 @@ class Context $output = new stdClass; foreach($args as $name) { - if(array_key_exists($name, $mock_vars)) $output->{$name} = $mock_vars[$name]; + $output->{$name} = $mock_vars[$name]; } return $output; } + public function getRequestVars() { + global $mock_vars; + + return $mock_vars; + } + public function get($name) { global $mock_vars; return array_key_exists($name, $mock_vars)?$mock_vars[$name]:''; diff --git a/tests/classes/validator/insertDocument.xml b/tests/classes/validator/insertDocument.xml new file mode 100644 index 000000000..56d49d7d1 --- /dev/null +++ b/tests/classes/validator/insertDocument.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + +