HtmlTag render element corrupts plain text that resembles HTML

Created on 12 April 2022, over 2 years ago
Updated 16 March 2023, almost 2 years ago

Problem/Motivation

If the HtmlTag render element is passed a value that is plain text (does not implement MarkupInterface) but resembles HTML (contains a < character followed by a letter) then the markup is corrupted.

Steps to reproduce

Example code - the title for an article about HTML.

$build = [
  '#type' => 'html_tag',
  '#tag' => 'h2', '#value' => 'How to use the <script> tag'
];
\Drupal::service('renderer')->renderPlain($build);

Actual output: <h2>How to use the tag</h2>
Expected output: <h2>How to use the &lt;script&gt; tag</h2>

For a real-life example, I hit this using TitleFormatter from the module Manage Display .

Proposed resolution

The problem is this code in ::preRenderHtmlTag:

        $element['#markup'] = Markup::create(Xss::filterAdmin($element['#value']));

The code assumes that if the input is not safe-markup then it is unsafe markup. This is contrary to the assumption elsewhere in the Drupal render system that text would be automatically escaped. The class comment confirms this expectation, describing this parameter as a string, not as markup:

#value: (string, optional) A string containing the textual contents of the tag.

This suggests that the correct code is like this:

        $element['#markup'] = new HtmlEscapedText($element['#value']);

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Needs work

Version

10.1

Component
Render 

Last updated about 8 hours ago

Created by

🇬🇧United Kingdom adamps

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024