diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 656fc8de40..c5c3d545ff 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -43,6 +43,7 @@ Yii Framework 2 Change Log - Bug #19454: Fix PDO exception code not properly passed to `yii\db\Exception` (Roguyt) - Bug #19477: cast shell_exec() output to string (schmunk42) - Bug #19481: Exception is always empty in ErrorHandler when handling fatal error (Renkas) +- Bug #19462: Fix validator client options to encode HTML tags (bizley) 2.0.45 February 11, 2022 ------------------------ diff --git a/framework/captcha/CaptchaValidator.php b/framework/captcha/CaptchaValidator.php index 9bcedca449..1a725386e0 100644 --- a/framework/captcha/CaptchaValidator.php +++ b/framework/captcha/CaptchaValidator.php @@ -9,6 +9,7 @@ namespace yii\captcha; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\Json; use yii\validators\ValidationAsset; use yii\validators\Validator; @@ -89,7 +90,7 @@ class CaptchaValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.captcha(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ');'; + return 'yii.validation.captcha(value, messages, ' . Json::htmlEncode($options) . ');'; } /** diff --git a/framework/validators/BooleanValidator.php b/framework/validators/BooleanValidator.php index ac8e334ea6..aea5a11db4 100644 --- a/framework/validators/BooleanValidator.php +++ b/framework/validators/BooleanValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Json; /** * BooleanValidator checks if the attribute value is a boolean value. @@ -76,7 +77,7 @@ class BooleanValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.boolean(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ');'; + return 'yii.validation.boolean(value, messages, ' . Json::htmlEncode($options) . ');'; } /** diff --git a/framework/validators/CompareValidator.php b/framework/validators/CompareValidator.php index fbe4d2cbe2..b94d498c6a 100644 --- a/framework/validators/CompareValidator.php +++ b/framework/validators/CompareValidator.php @@ -10,6 +10,7 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; use yii\helpers\Html; +use yii\helpers\Json; /** * CompareValidator compares the specified attribute value with another value. @@ -234,7 +235,7 @@ class CompareValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.compare(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ', $form);'; + return 'yii.validation.compare(value, messages, ' . Json::htmlEncode($options) . ', $form);'; } /** diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php index 2d67ac60cb..65f8897cad 100644 --- a/framework/validators/FileValidator.php +++ b/framework/validators/FileValidator.php @@ -432,7 +432,7 @@ class FileValidator extends Validator { ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.file(attribute, messages, ' . Json::encode($options) . ');'; + return 'yii.validation.file(attribute, messages, ' . Json::htmlEncode($options) . ');'; } /** diff --git a/framework/validators/FilterValidator.php b/framework/validators/FilterValidator.php index d24131a971..0a0ec5ba9a 100644 --- a/framework/validators/FilterValidator.php +++ b/framework/validators/FilterValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use yii\base\InvalidConfigException; +use yii\helpers\Json; /** * FilterValidator converts the attribute value according to a filter. @@ -93,7 +94,7 @@ class FilterValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'value = yii.validation.trim($form, attribute, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ', value);'; + return 'value = yii.validation.trim($form, attribute, ' . Json::htmlEncode($options) . ', value);'; } /** diff --git a/framework/validators/ImageValidator.php b/framework/validators/ImageValidator.php index 0a06dd75f4..d7121f5b6c 100644 --- a/framework/validators/ImageValidator.php +++ b/framework/validators/ImageValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Json; use yii\web\UploadedFile; /** @@ -166,7 +167,7 @@ class ImageValidator extends FileValidator { ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.image(attribute, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ', deferred);'; + return 'yii.validation.image(attribute, messages, ' . Json::htmlEncode($options) . ', deferred);'; } /** diff --git a/framework/validators/RangeValidator.php b/framework/validators/RangeValidator.php index bcde4a1309..9d11fdc20e 100644 --- a/framework/validators/RangeValidator.php +++ b/framework/validators/RangeValidator.php @@ -10,6 +10,7 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; use yii\helpers\ArrayHelper; +use yii\helpers\Json; /** * RangeValidator validates that the attribute value is among a list of values. @@ -111,7 +112,7 @@ class RangeValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.range(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ');'; + return 'yii.validation.range(value, messages, ' . Json::htmlEncode($options) . ');'; } /** diff --git a/framework/validators/RequiredValidator.php b/framework/validators/RequiredValidator.php index 646357ace3..03a7b1b415 100644 --- a/framework/validators/RequiredValidator.php +++ b/framework/validators/RequiredValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Json; /** * RequiredValidator validates that the specified attribute does not have null or empty value. @@ -93,7 +94,7 @@ class RequiredValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.required(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ');'; + return 'yii.validation.required(value, messages, ' . Json::htmlEncode($options) . ');'; } /** diff --git a/framework/validators/StringValidator.php b/framework/validators/StringValidator.php index 3f44ce29de..4db6314e25 100644 --- a/framework/validators/StringValidator.php +++ b/framework/validators/StringValidator.php @@ -8,6 +8,7 @@ namespace yii\validators; use Yii; +use yii\helpers\Json; /** * StringValidator validates that the attribute value is of certain length. @@ -168,7 +169,7 @@ class StringValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'yii.validation.string(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ');'; + return 'yii.validation.string(value, messages, ' . Json::htmlEncode($options) . ');'; } /** diff --git a/framework/validators/TrimValidator.php b/framework/validators/TrimValidator.php index 2e32db69c4..7426d195bd 100644 --- a/framework/validators/TrimValidator.php +++ b/framework/validators/TrimValidator.php @@ -7,6 +7,8 @@ namespace yii\validators; +use yii\helpers\Json; + /** * This class converts the attribute value(s) to string(s) and strip characters. * @@ -65,7 +67,7 @@ class TrimValidator extends Validator ValidationAsset::register($view); $options = $this->getClientOptions($model, $attribute); - return 'value = yii.validation.trim($form, attribute, ' . json_encode($options) . ', value);'; + return 'value = yii.validation.trim($form, attribute, ' . Json::htmlEncode($options) . ', value);'; } /** diff --git a/tests/framework/validators/BooleanValidatorTest.php b/tests/framework/validators/BooleanValidatorTest.php index 9835422ebf..4c183a0de0 100644 --- a/tests/framework/validators/BooleanValidatorTest.php +++ b/tests/framework/validators/BooleanValidatorTest.php @@ -85,7 +85,7 @@ class BooleanValidatorTest extends TestCase $obj->attrD = []; $this->assertEquals( - 'yii.validation.boolean(value, messages, {"trueValue":true,"falseValue":false,"message":"attrB must be either \"true\" or \"false\".","skipOnEmpty":1,"strict":1});', + 'yii.validation.boolean(value, messages, {"trueValue":true,"falseValue":false,"message":"attrB must be either \u0022true\u0022 or \u0022false\u0022.","skipOnEmpty":1,"strict":1});', $validator->clientValidateAttribute($obj, 'attrB', new ViewStub()) ); } diff --git a/tests/framework/validators/RequiredValidatorTest.php b/tests/framework/validators/RequiredValidatorTest.php index 1d4fde051d..fd7cc1811e 100644 --- a/tests/framework/validators/RequiredValidatorTest.php +++ b/tests/framework/validators/RequiredValidatorTest.php @@ -7,6 +7,7 @@ namespace yiiunit\framework\validators; +use yii\base\Model; use yii\validators\RequiredValidator; use yiiunit\data\validators\models\FakedValidationModel; use yiiunit\TestCase; @@ -66,4 +67,33 @@ class RequiredValidatorTest extends TestCase $val->validateAttribute($m, 'attr_val'); $this->assertFalse($m->hasErrors('attr_val')); } + + public function testErrorClientMessage() + { + $validator = new RequiredValidator(['message' => 'error for {attribute}']); + + $obj = new ModelForReqValidator(); + + $this->assertEquals( + 'yii.validation.required(value, messages, {"message":"\u003Cstrong\u003Eerror\u003C\/strong\u003E for \u003Cb\u003EAttr\u003C\/b\u003E"});', + $validator->clientValidateAttribute($obj, 'attr', new ViewStub()) + ); + } +} + +class ModelForReqValidator extends Model +{ + public $attr; + + public function rules() + { + return [ + [['attr'], 'required'], + ]; + } + + public function attributeLabels() + { + return ['attr' => 'Attr']; + } }