Fixes #1955: Some validators used to cause warnings or errors in case non-scalar array typed values being checked. #2186

Merged
merged 4 commits into from Mar 10, 2013
Jump to file
+248 −17
Split
View
@@ -12,6 +12,7 @@ Version 1.1.14 work in progress
- Bug #1941: yiiactiveform.js form reset now uses CHtml::errorCss instead of a hardcoded value (mdomba)
- Bug #1942: CActiveForm client/ajax validation will now remove error class from server side validation (mdomba)
- Bug #1945: Reference to undefined variable $column in CDbMigration::dropPrimaryKey (paystey)
+- Bug #1955: Some validators used to cause warnings or errors in case non-scalar array typed values being checked (resurtm)
- Bug #1984: CDbMigration: fix of undeclared variable usage in debug information in dropPrimaryKey (papulovskiy)
- Bug #1996: Using yiic help for commands with parameters with array as default value resulted in PHP error with latest PHP versions (dInGd0nG, samdark)
- Bug #1997: Cache key in CGettextMessageSource::loadMessages wasn't specific enough (odevyatkov)
@@ -47,7 +47,8 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
$captcha=$this->getCaptchaAction();
- if(!$captcha->validate($value,$this->caseSensitive))
+ // reason of array checking is explained here: https://github.com/yiisoft/yii/issues/1955
+ if(is_array($value) || !$captcha->validate($value,$this->caseSensitive))
{
$message=$this->message!==null?$this->message:Yii::t('yii','The verification code is incorrect.');
$this->addError($object,$attribute,$message);
@@ -52,17 +52,22 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
- $formats=is_string($this->format) ? array($this->format) : $this->format;
$valid=false;
- foreach($formats as $format)
+
+ // reason of array checking is explained here: https://github.com/yiisoft/yii/issues/1955
+ if(!is_array($value))
{
- $timestamp=CDateTimeParser::parse($value,$format,array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0));
- if($timestamp!==false)
+ $formats=is_string($this->format) ? array($this->format) : $this->format;
+ foreach($formats as $format)
{
- $valid=true;
- if($this->timestampAttribute!==null)
- $object->{$this->timestampAttribute}=$timestamp;
- break;
+ $timestamp=CDateTimeParser::parse($value,$format,array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0));
+ if($timestamp!==false)
+ {
+ $valid=true;
+ if($this->timestampAttribute!==null)
+ $object->{$this->timestampAttribute}=$timestamp;
+ break;
+ }
}
}
@@ -87,7 +87,7 @@ protected function validateAttribute($object,$attribute)
*/
public function validateValue($value)
{
- if($this->validateIDN)
+ if(is_string($value) && $this->validateIDN)
$value=$this->encodeIDN($value);
// make sure string length is limited to avoid DOS attacks
$valid=is_string($value) && strlen($value)<=254 && (preg_match($this->pattern,$value) || $this->allowName && preg_match($this->fullPattern,$value));
@@ -182,7 +182,7 @@ protected function mxSort($a, $b)
/**
* Converts given IDN to the punycode.
- * @param $value IDN to be converted.
+ * @param string $value IDN to be converted.
* @return string resulting punycode.
* @since 1.1.13
*/
@@ -73,6 +73,13 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
+ return;
+ }
+
$className=$this->className===null?get_class($object):Yii::import($this->className);
$attributeName=$this->attributeName===null?$attribute:$this->attributeName;
$finder=CActiveRecord::model($className);
@@ -78,6 +78,13 @@ protected function validateAttribute($object,$attribute)
$value=$object->$attribute;
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be a number.');
+ $this->addError($object,$attribute,$message);
+ return;
+ }
if($this->integerOnly)
{
if(!preg_match($this->integerPattern,"$value"))
@@ -48,7 +48,10 @@ protected function validateAttribute($object,$attribute)
return;
if($this->pattern===null)
throw new CException(Yii::t('yii','The "pattern" property must be specified with a valid regular expression.'));
- if((!$this->not && !preg_match($this->pattern,$value)) || ($this->not && preg_match($this->pattern,$value)))
+ // reason of array checking explained here: https://github.com/yiisoft/yii/issues/1955
+ if(is_array($value) ||
+ (!$this->not && !preg_match($this->pattern,$value)) ||
+ ($this->not && preg_match($this->pattern,$value)))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is invalid.');
$this->addError($object,$attribute,$message);
@@ -80,6 +80,13 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
+ return;
+ }
+
if(function_exists('mb_strlen') && $this->encoding!==false)
$length=mb_strlen($value, $this->encoding ? $this->encoding : Yii::app()->charset);
else
@@ -83,6 +83,13 @@ protected function validateAttribute($object,$attribute)
if($this->allowEmpty && $this->isEmpty($value))
return;
+ if(is_array($value))
+ {
+ // https://github.com/yiisoft/yii/issues/1955
+ $this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
+ return;
+ }
+
$className=$this->className===null?get_class($object):Yii::import($this->className);
$attributeName=$this->attributeName===null?$attribute:$this->attributeName;
$finder=CActiveRecord::model($className);
@@ -72,7 +72,7 @@ protected function validateAttribute($object,$attribute)
* Validates a static value to see if it is a valid URL.
* Note that this method does not respect {@link allowEmpty} property.
* This method is provided so that you can call it directly without going through the model validation rule mechanism.
- * @param mixed $value the value to be validated
+ * @param string $value the value to be validated
* @return mixed false if the the value is not a valid URL, otherwise the possibly modified value ({@see defaultScheme})
* @since 1.1.1
*/
@@ -1574,6 +1574,11 @@ public static function activeTextArea($model,$attribute,$htmlOptions=array())
}
else
$text=self::resolveValue($model,$attribute);
+
+ // https://github.com/yiisoft/yii/issues/1955
+ if(is_array($text))
+ $text='';
+
@qiangxue
qiangxue Mar 11, 2013 Member

There is no need to check array here. The developer is responsible to make sure the type is proper. By doing so, it would mean we should do similar for nearly everywhere, which is simply too much for the framework.

return self::tag('textarea',$htmlOptions,isset($htmlOptions['encode']) && !$htmlOptions['encode'] ? $text : self::encode($text));
}
@@ -2137,6 +2142,11 @@ protected static function activeInputField($type,$model,$attribute,$htmlOptions)
unset($htmlOptions['value']);
elseif(!isset($htmlOptions['value']))
$htmlOptions['value']=self::resolveValue($model,$attribute);
+
+ // https://github.com/yiisoft/yii/issues/1955
+ if(is_array($htmlOptions['value']))
+ $htmlOptions['value']='';
+
if($model->hasErrors($attribute))
self::addErrorCss($htmlOptions);
return self::tag('input',$htmlOptions);
@@ -61,6 +61,21 @@ public function testValidationUsingStrict()
$model->foo = '1';
$this->assertTrue($model->hasErrors('foo'));
}
+
+ /**
+ * Test array typed value
+ * https://github.com/yiisoft/yii/issues/1955
+ *
+ * @return null
+ */
+ public function testValidateArrayValue()
+ {
+ $model = $this->getModelMock();
+ $model->foo = array(1);
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('foo'));
+ $this->assertSame(array('Foo must be either 1 or 0.'), $model->getErrors('foo'));
+ }
/**
* Mocks up an object to test with
@@ -25,6 +25,11 @@ public function testValidationErrorsWithEquals()
$model->bar = 'foo';
$this->assertTrue($model->validate());
+ // https://github.com/yiisoft/yii/issues/1955
+ $model->foo = array('foo');
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('foo'));
+
// client validation
$validator = new CCompareValidator;
$validator->operator = '=';
@@ -44,6 +44,10 @@ public function testFormatOption()
$this->assertTrue($model->validate());
$model->foo = '01-24-2011';
$this->assertFalse($model->validate());
+
+ // array value, https://github.com/yiisoft/yii/issues/1955
+ $model->foo = array('01-01-2011');
+ $this->assertFalse($model->validate());
}
/**
@@ -60,4 +60,16 @@ public function testIDNUrl($email, $validateIDN, $assertion)
$result = $emailValidator->validateValue($email);
$this->assertEquals($assertion, $result);
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $model=new ValidatorTestModel('CEmailValidatorTest');
+ $model->email=array('user@domain.tld');
+ $model->validate(array('email'));
+ $this->assertTrue($model->hasErrors('email'));
+ $this->assertEquals(array('Email is not a valid email address.'),$model->getErrors('email'));
+ }
}
@@ -127,4 +127,16 @@ public function testValidateWithCriteria()
$model->name = $name;
$this->assertFalse($model->validate(),'Unable to validate model with custom criteria!');
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $modelClassName = $this->_arModelName;
+ $model = new $modelClassName('simple');
+ $model->name = array('test_name');
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('name'));
+ }
}
@@ -0,0 +1,98 @@
+<?php
+
+class CStringValidatorTest extends CTestCase
+{
+ public function testMin()
+ {
+ // null value
+ $model1=new ValidatorTestModel('CStringValidatorTest');
+ $model1->validate(array('string1'));
+ $this->assertTrue($model1->hasErrors('string1'));
+ $this->assertSame(array('Too short message.'),$model1->getErrors('string1'));
+
+ // 9 characters length value
+ $model2=new ValidatorTestModel('CStringValidatorTest');
+ $model2->string1='123456789';
+ $model2->validate(array('string1'));
+ $this->assertTrue($model2->hasErrors('string1'));
+ $this->assertSame(array('Too short message.'),$model2->getErrors('string1'));
+
+ // 10 characters length value
+ $model3=new ValidatorTestModel('CStringValidatorTest');
+ $model3->string1='1234567890';
+ $model3->validate(array('string1'));
+ $this->assertFalse($model3->hasErrors('string1'));
+ $this->assertNotSame(array('Too short message.'),$model3->getErrors('string1'));
+
+ // array value: https://github.com/yiisoft/yii/issues/1955
+ $model4=new ValidatorTestModel('CStringValidatorTest');
+ $model4->string1=array('1234567890');
+ $model4->validate(array('string1'));
+ $this->assertTrue($model4->hasErrors('string1'));
+ }
+
+ public function testMax()
+ {
+ // null value
+ $model1=new ValidatorTestModel('CStringValidatorTest');
+ $model1->validate(array('string2'));
+ $this->assertFalse($model1->hasErrors('string2'));
+ $this->assertNotSame(array('Too long message.'),$model1->getErrors('string2'));
+
+ // 11 characters length value
+ $model2=new ValidatorTestModel('CStringValidatorTest');
+ $model2->string2='12345678901';
+ $model2->validate(array('string2'));
+ $this->assertTrue($model2->hasErrors('string2'));
+ $this->assertSame(array('Too long message.'),$model2->getErrors('string2'));
+
+ // 10 characters length value
+ $model3=new ValidatorTestModel('CStringValidatorTest');
+ $model3->string2='1234567890';
+ $model3->validate(array('string2'));
+ $this->assertFalse($model3->hasErrors('string2'));
+ $this->assertNotSame(array('Too long message.'),$model3->getErrors('string2'));
+
+ // array value: https://github.com/yiisoft/yii/issues/1955
+ $model4=new ValidatorTestModel('CStringValidatorTest');
+ $model4->string2=array('1234567890');
+ $model4->validate(array('string2'));
+ $this->assertTrue($model4->hasErrors('string2'));
+ }
+
+ public function testIs()
+ {
+ // null value
+ $model1=new ValidatorTestModel('CStringValidatorTest');
+ $model1->validate(array('string3'));
+ $this->assertTrue($model1->hasErrors('string3'));
+ $this->assertSame(array('Error message.'),$model1->getErrors('string3'));
+
+ // 9 characters length value
+ $model2=new ValidatorTestModel('CStringValidatorTest');
+ $model2->string3='123456789';
+ $model2->validate(array('string3'));
+ $this->assertTrue($model2->hasErrors('string3'));
+ $this->assertSame(array('Error message.'),$model2->getErrors('string3'));
+
+ // 11 characters length value
+ $model3=new ValidatorTestModel('CStringValidatorTest');
+ $model3->string3='12345678901';
+ $model3->validate(array('string3'));
+ $this->assertTrue($model3->hasErrors('string3'));
+ $this->assertSame(array('Error message.'),$model3->getErrors('string3'));
+
+ // 10 characters length value
+ $model4=new ValidatorTestModel('CStringValidatorTest');
+ $model4->string3='1234567890';
+ $model4->validate(array('string3'));
+ $this->assertFalse($model4->hasErrors('string3'));
+ $this->assertNotSame(array('Error message.'),$model4->getErrors('string3'));
+
+ // array value: https://github.com/yiisoft/yii/issues/1955
+ $model5=new ValidatorTestModel('CStringValidatorTest');
+ $model5->string3=array('1234567890');
+ $model5->validate(array('string3'));
+ $this->assertTrue($model5->hasErrors('string3'));
+ }
+}
@@ -127,4 +127,16 @@ public function testValidateWithCriteria()
$model->name = $name;
$this->assertTrue($model->validate(),'Unable to validate model with custom criteria!');
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $modelClassName = $this->_arModelName;
+ $model = new $modelClassName('simple');
+ $model->name = array('test_name');
+ $this->assertFalse($model->validate());
+ $this->assertTrue($model->hasErrors('name'));
+ }
}
@@ -10,10 +10,10 @@ public function testEmpty()
$this->assertArrayHasKey('url', $model->getErrors());
}
- public function testArbitaryUrl()
+ public function testArbitraryUrl()
{
$urlValidator = new CUrlValidator();
- $url = 'http://testing-arbitary-domain.com/';
+ $url = 'http://testing-arbitrary-domain.com/';
$result = $urlValidator->validateValue($url);
$this->assertEquals($url, $result);
}
@@ -173,4 +173,16 @@ public function testAllowEmpty($url, $allowEmpty, $assertion)
$result = $urlValidator->validateValue($url);
$this->assertEquals($assertion, $result);
}
+
+ /**
+ * https://github.com/yiisoft/yii/issues/1955
+ */
+ public function testArrayValue()
+ {
+ $model=new ValidatorTestModel('CUrlValidatorTest');
+ $model->url=array('http://yiiframework.com/');
+ $model->validate(array('url'));
+ $this->assertTrue($model->hasErrors('url'));
+ $this->assertEquals(array('Url is not a valid URL.'),$model->getErrors('url'));
+ }
}
Oops, something went wrong.