Problem/Motivation
We are getting more use cases for escaping if given string is not safe. We see code patterns like:
\Drupal\Component\Utility\PlaceholderTrait::placeholderFormat():
foreach ($args as $key => $value) {
switch ($key[0]) {
case '@':
// Escaped only.
if (!SafeMarkup::isSafe($value)) {
$args[$key] = Html::escape($value);
}
break;
case '%':
default:
// Escaped and placeholder.
if (!SafeMarkup::isSafe($value)) {
$value = Html::escape($value);
}
$args[$key] = '<em class="placeholder">' . $value . '</em>';
break;
And in views_pre_render_views_form_views_form():
foreach ($substitutions as $placeholder => $substitution) {
$search[] = Html::escape($placeholder);
// Ensure that any replacements made are safe to make.
if (!SafeMarkup::isSafe($substitution)) {
$substitution = Html::escape($substitution);
}
// ..
Proposed resolution
Follow up to #2569699: Remove SafeMarkup::checkPlain() for Drupal 9.0.x to comment #30 by @alexpott:
+++ b/core/includes/batch.inc @@ -102,6 +103,14 @@ function _batch_do() { + if (!SafeMarkup::isSafe($message)) { + $message = Html::escape($message); + }Is it time to add SafeMarkup::escapeIfUnsafe() it seems we have quite a few issues that need this.
Remaining tasks
Create methodSafeMarkup:: escapeIfUnsafe()Find use cases and replace themWrite tests- Review
User interface changes
None.
API changes
API addition to SafeMarkup?
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #24 | 2573913-24.patch | 4.26 KB | upchuk |
| #24 | interdiff-24.txt | 2.22 KB | upchuk |
| #22 | 2573913-22.patch | 4.08 KB | upchuk |
| #22 | interdiff-22.txt | 741 bytes | upchuk |
| #15 | 2573913-15.patch | 4 KB | upchuk |
Comments
Comment #2
upchuk commentedComment #3
upchuk commentedSomething like this?
Comment #4
imiksuYyup something like that, I'll try to put it in use in couple of places and see if any tests fails.
Comment #5
imiksuPutting to "Needs review" to review tests. Tests for this specific method are still needed. Do we need to change/update documentation somewhere?
Comment #6
imiksuComment #7
imiksuActually should we use here
SafeMarkup::checkPlain()instead?Comment #8
upchuk commentedSafeMarkup::checkPlain() will be deprecated no?
Comment #9
MattA commentedThere doesn't appear to be any need for these intermediate variables anymore.
Comment #10
imiksuThat's correct, ignore my comment.
How come there's no need?
Comment #11
imiksuHere's initial version of tests. It needs to test case where we already have safe string and it wouldn't escape it.
Comment #15
upchuk commentedAdded test to cover also the safe string that needs to stay unchanged. Hope that's good :)
Comment #16
upchuk commentedComment #17
imiksuComment #18
upchuk commentedComment #19
berdir$string can also be a SafeString object, no? That's exactly what were are checking here. So we should document the type as string|SafeStringInterface.
empty line between @param and @return (but not between multiple @param's).
The description is also not clear what happens if the string was safe, it sounds like it doesn't return anything. Maybe just "An escaped or safe string." ?
Comment #20
lauriiiThis can be also SafeString.
This is not a string that its returning but instead a SafeStringInterface.
Comment #21
upchuk commentedComment #22
upchuk commentedHere we go.
Comment #23
MattA commented#20.2
If a
SafeStringInterfaceis passed, then by definition it is safe and simply returned immediately. If a regular string is passed, then it is checked against the static list and either returned (if it was already marked as safe) or run throughHtml::escape(), which also results in a plain old string being returned.In my opinion, I don't think the current documentation does a good job of explaining this.
Also, #9 was never addressed.
Comment #24
upchuk commented@MattA,
Sorry, I overlooked #9. Please see the interdiff for the changes you mentioned.
As for the documentation, I think I see what you mean, I tried to adjust it.
Comment #25
lauriiiI discussed about this issue with @alexpott and @stefan.r and we agreed that we don't want to do this now. The reason why its not a good idea to add a helper for this is that in most of the cases where strings has to be manually escaped, there is better alternative than using this helper method. By adding this helper we would encourage people use this method on top of other solutions.
I also looked the use cases in core and I didn't find good use cases so far in the core where there would get much benefit out of this. I also think that this will get better by the time we get rid of SafeMarkup::isSafe().