Closed dicrtarasov closed 3 years ago
How is this broken? Default implementation produces something like:
<p class="help-block">An hint with > "3" unquoted elements</p>
Need to be quoted by htmlspecialchars.
Why?
I guess that's because it's not a good practice to have HTML in your models. @dicrtarasov right?
It's true but the example doesn't contain any HTML and it's provided by developer so by default it should not need encoding like data provided by end user. It also by default doesn't generate anything inside HTML tag attributes which would require encoding. I'm just trying to understand.
I guess this is similar to other possible injections. The basic idea is to make it impossible for a developer to make such errors, therefore such input should be escaped also. In Yii2 examples, this comes always hardcoded from the model, but technically the hint could come from anywhere, therefore it would be could practice to encode it. At best encode by default, but let the developer disable it.
This kind of reasoning would let us end with everything being encoded by default. If developer uses something that comes from user and wants to display it, it should be encoded but it is developer's responsibility in that case because framework is not forcing to use risky input here. We are doing the same for labels - in both cases only options are encoded because these go as HTML attributes. I would like to hear @dicrtarasov response about all this.
1) Text in hits does not contains HTML, but can include chars like "
, or ">". It's normal. (Ex. "value must be < 30")
2) Text can be used to output in console, file or other places, so it must not be quoted by default.
3) Only output in HTML must be always quoted.
4) Adding support of encode
or encodeHint
options, similar to existing encodeLabel
, does not broke existing code compatibility.
This kind of reasoning would let us end with everything being encoded by default. If developer uses something that comes from user and wants to display it, it should be encoded but it is developer's responsibility in that case because framework is not forcing to use risky input here. We are doing the same for labels - in both cases only options are encoded because these go as HTML attributes. I would like to hear @dicrtarasov response about all this.
Hint and other text are similar to labels when output in HTML.
Developers mut have an posibility to use options to encode (like encodeHints
=> true)
Output in HTML must always have options to encode content.
When text are html-quoted by default, then output to console, file must be used with entitydecode
?
I guess you are referring to encodeLabel
from DataColumn
or encodeLabels
from Menu
widget - the option there was added to prevent encoding on demand because the default behavior is to encode it. You want now opposite of that for hints.
I'm against such feature.
$form->field used to generate HTML similar to DataColumn or Menu widget. So we can add options to control encoding. In anyway, currently generated HTML is broken.
HTML is broken. So this is a bug. But can be a feature also :)
Please explain to me why HTML is broken here.
<p class="help-block">An hint with > "3" unquoted elements</p>
Is this right?
Yes, I believe this is a valid HTML. If I'm mistaken please state some doc links saying otherwise.
No, because of ">" HTML is broken
Unquoted content must not be used in HTML
This is about XML...
HTML5 ("DOCTYPE html") is XHTML.
Try to validate it at validator.w3c.org
This is for HTML: https://tools.ietf.org/html/rfc1866#section-3.2
https://validator.w3.org/nu/#textarea Code tested (extra markup added so it does not complain):
<!DOCTYPE html>
<html lang="en">
<head><title>Test</title></head>
<body>
<p class="help-block">An hint with > "3" unquoted elements</p>
</body>
</html>
Ohh.... this is special case. What about:
<!DOCTYPE html>
<html lang="en">
<head><title>Test</title></head>
<body>
<p class="help-block">An hint <with > "3" unquoted elements</p>
</body>
</html>
we are discussing about nothing HTML special chars in content must be quoted and nothing else.
@dicrtarasov is correct. Special chars should be escaped.
Yes, I agree. But I state it should be up to the developer, not framework. And I rest my case.
Ok, how developer can encode this, when using model in ActiveField ?
echo $form->field($model, 'attr');
I propose to add new option encode
to hintOptions
:
echo $form->field($model, `attr`, [
'hintOptions' => [
'encode' => true
]
]);
Or... what other way is?
I found the way, but it is not so beautifull:
echo $form->field($model, `attr`, [
'hintOptions' => [
'hint' => Html::encode($model->attr)
]
]);
It's better to add encode
support to BaseHtml::activeHint
:
public static function activeHint($model, $attribute, $options = [])
{
$attribute = static::getAttributeName($attribute);
$hint = isset($options['hint']) ? $options['hint'] : $model->getAttributeHint($attribute);
if (empty($hint)) {
return '';
}
+ $encode = ArrayHelper::remove($options, 'encode', false);
+ if ($encode) {
+ $hint = static::encode($hint);
+ }
$tag = ArrayHelper::remove($options, 'tag', 'div');
unset($options['hint']);
return static::tag($tag, $hint, $options);
}
I agree that adding encoding option makes sense. @dicrtarasov do you have some time for a pull request?
Please remember to also add this in other places that could take possible "broken" HTML:
(I hope you see now how ridiculous this is...)
Hmm. Yes, that's a bit inconsistent...
I will be glad to help in any way I can. I can add functionality to BaseHtml::activeHint, but I don't know all the aspects of the other classes listed above.
The thing is that in many places @bizley pointed to we're not encoding anything and letting it up to end user. In order to have it all consistent we have to either adjust it everywhere or do not adjust it. In case of adjusting it everywhere we can't change behavior because of backwards compatibility (for example, one may use HTML in hints).
Overall it can not be efficiently done with Yii 2 without too much breakage. Closing because of that. Will contiue thinking about it for Yii 3.
What steps will reproduce the problem?
Generates broken HTML because of chars in model hint.
What is the expected result?
We can add support of 'encode' option to BaseHtml.
or
Additional info