Problem/Motivation
There is no render #thingie the behaves like twig.
- #markup admin filters if not safe
- #plain_text always escapes regardless of safety
- Twig will escape if not safe
This means that issues like #2567159: Fix improper usage of t() in ViewsBlock are resorting to inline templates to get this behaviour. Funnily enough we use to be able to flip #markup between filtering and escaping but that got changed in #2555931: Add #plain_text to escape text in render arrays. I think the rationale behind that change was good since
$render_array = ['#plain_text' => SafeString::create('<em>I win</em>')];
looks awful.
But
$render_array = ['#plain_text' => t('@thing: @subthing', $placeholders)];
the fact that this will double escape is also awful.
Proposed resolution
Not sure. We could make #plain_text use the inbuilt double escaping prevention in htmlspecialchars() or maybe once t() and SafeMarkup::format return objects we could glean information as to how they are made safe.
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #28 | 2568045-9.x-27.patch | 9.1 KB | alexpott |
| #28 | 2568045-9.x-27-test-only.patch | 1.16 KB | alexpott |
| #27 | 2568045-9.x-27.patch | 9.1 KB | alexpott |
| #15 | 2568045-review.txt | 2.01 KB | dawehner |
| #15 | interdiff.txt | 1.14 KB | dawehner |
Issue fork drupal-2568045
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
alexpottComment #3
alexpottHere is the simplest fix.
Comment #4
alexpottSo one problem with this approach is that it should be allowed for translators to add html elements like bdi and dir see http://www.w3.org/International/questions/qa-html-dir for more.
Comment #5
plachComment #7
dawehnerShould we make that an option on Html::escape?
Comment #9
plachI think an explicit method (on top of that) would be better DX, something like
HTML::escapeUnsafe().Comment #10
dawehnerAgreed!
Comment #11
alexpottSo the filter admin page relies on double escaping :)
Comment #12
effulgentsia commentedExactly. I think we should postpone this on #2509218: Ensure that SafeString objects can be used in non-HTML contexts and then do:
in places where we want translated plain-text strings.
Comment #13
joelpittetOfftopic: Yes yes double yes. not that method name but yes:) CLI or email can be smart about rendered context. Value objects FTW and PHP shortcomings be-damned!
Comment #14
tim.plunkettHitting this in #2513534: Remove the 'disabled' region from Block UI, this patch fixes my issue.
My workaround is to use #markup with t():
Comment #15
dawehnerThis is a patch on top of #2575615: Introduce HtmlEscapedText and remove SafeMarkup::setMultiple() and SafeMarkup::getAll() and remove the static safeStrings list
Comment #24
mjpa commentedFollowing, although probably pointlessly, as I've come across this too and the work around in #14 just looks ugly...
Comment #27
alexpottNew approach that passes FilterAdminTest, doesn't change behaviour in an unexpected way - ie. RendererTest passes with no changes and also fixes #3199730: Views block description is double-escaped if display name is set.
No interdiff because it has been a while and re-classifying as a major bug because it's very very hard to not double escape when you do something like:
Any & in $info['label'] will be double escaped if a block is disabled.
Comment #28
alexpottWith only the addition to RendererTest applied the test shows exactly what is happening on #3199730: Views block description is double-escaped if display name is set
Comment #30
alexpott@catch pointed me to #275308: Make check_plain() reentrant which is pretty similar - but I don't think it is quite the same because in D8/9 we have MarkupInterface so we know when we're dealing with one of these objects.
Comment #31
longwaveIs it safe to push the check inside
Html::escape(), so any caller that might pass in a MarkupInterface benefits from this fix?Comment #34
knurg commentedAny progress on this? Whenever I do rewriting manually on views via "a href" and tokens I end up having this issue... it is pretty severe for me and worked pretty well before Drupal 9 :/
Comment #37
smustgrave commented@alexpott should a change be made for #31?
Comment #38
alexpottWe could try #31 but I worry about things like the filter admin page which need things double escaped. I think that #plain_text indicates an intention beyond other places where Html::escape() is called so the patch in #28 is correct but moving this to Html::escape() could have unintended impacts.
Comment #39
smustgrave commentedWonder if the issue summary could be updated though.
The proposed solution, correct me if I'm wrong, doesn't seem to match up with the solution in the patch.
Solution wise though this looks good.
Comment #41
acbramley commentedThis was triaged as part of BSI. At the very least needs a reroll onto an MR.