Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Postponed on #2544156: Deprecate drupal_render_children() according to #11
Problem/Motivation
drupal_render_children() calls SafeMarkup::set() which is meant to be for internal use only.
Proposed resolution
Remove the call by refactoring the code.- If refactoring is not possible, thoroughly document where the string is coming from and why it is safe, and why SafeMarkup::set() is required.
Remaining tasks
Evaluate whether the string can be refactored to one of the formats outlined in this change record: https://www.drupal.org/node/2311123- Identify whether there is existing automated test coverage for the sanitization of the string. If there is, list the test in the issue summary. If there isn't, add an automated test for it.
- If the string cannot be refactored, the SafeMarkup::set() usage needs to be thoroughly audited and documented.
Manual testing steps (for XSS and double escaping)
Not necessary, we are only adding documentation.
User interface changes
N/A
API changes
N/A
Comment | File | Size | Author |
---|---|---|---|
#20 | 2501455.18.patch | 1.05 KB | alexpott |
#4 | document-2501455-4.patch | 569 bytes | akalata |
#1 | document-2501455-1.patch | 538 bytes | star-szr |
Comments
Comment #1
star-szrI'm not really sure how true this is but it's pretty internal. This is a start, anyway.
Comment #2
joelpittetThis documentation seems correct.
Comment #3
xjmThanks @Cottser. So looking at this comment, I think we should be a little more explicit about the purpose of the call that render() is not magically making everything sanitized -- saying it is "safe" is a little unspecific. Similarly to #2273925-269: Ensure #markup is XSS escaped in Renderer::doRender() and... whatever other issue it was I bumped back yesterday for the same thing. #2501403: Document SafeMarkup::set in Xss::filter. Kind of blurring together. :) We might want a longish comment on what the render system has done up until that point and how it interacts with the... thingy. Twig autoescaping.
Here's the comment from the
doRender()
issue to save that page load:Comment #4
akalata CreditAttribution: akalata commentedHere's a try for updated documentation, though I'm not sure it's exactly what you're looking for. I'm thinking we don't need to provide details on the render system since we've documented the specific class that should be handling the checking of markup (maybe?).
Comment #5
joelpittetAlso good with that/can't think of anything better to describe it. Thanks @akalata
Comment #6
xjmSo, I started to post a slightly tweaked text for this. Then, I was going to suggest it be merged with the patch for docs in
Renderer::doRender()
so that we could explain it consistently.Then I realized that this function (unlike
doRender()
) is not just marking XSS-filtered #markup as safe -- it's marking the entire render array output as safe and returning it, which means (as far as I know) that any unsafe strings in the render array will never get sanitized by Twig either.What's more, it actually doesn't appear to be a part of the main render API any more. It's only called in four places and it sort of circumvents the rest of the render system actually. I think this function should be replaced entirely in the code that calls it, and deprecated.
I pinged @Wim Leers for feedback on the status of drupal_render_children().
Comment #7
Wim LeersKilling
drupal_render_children()
would be splendid. It is a very, very confusing function anyway.I'd like input from somebody with very deep Theme system knowledge to make sure that that is actually okay though. Assigning to Joël.
Comment #8
xjmThanks Wim!
Comment #9
joelpittetI wish assignments notified me somehow:) I just happened to be following this one.
I think we can kill it's use in core almost entirely if not totally. But not sure we can do that in contrib, that I'd definitely need a check on grepping all contrib.
It's not as confusing as
drupal_render()
which needs some factoring love ;-)It loops through the element children, renders each child element and concatenates them. Which is actually also done in drupal_render/Renderer::doRender:
/lib/Drupal/Core/Render/Renderer.php:391
The only difference is that the one in
doRender
is sorted, and the one indrupal_render_children()
is not sorted and can take arbitrary keys.Currently it's used in the following places:
Maybe we need a compliment to
|without()
to be|with()
to get this feature in twig?Currently haven't had any reason to use this feature in core.
system.admin.inc
andcore/modules/views_ui/views_ui.theme.inc
are on the theme function chopping block.#1938930: Convert theme_system_modules_details() to #type table
#1963978: Convert theme_views_ui_build_group_filter_form() to Twig
The
views.module
one may not even need that extra call at all, but worth testing that theory out. Same with preRenderToolbar. Those two are the wildcards.So +1 to create a follow-up to deprecate that function and find all it's use in contrib.
Comment #10
star-szr@Fabianx would be good to ping here too. I think generally it is used to print remaindered/extra "stuff" contained in a render array, but maybe we can remove it now that we have |without. Not sure at the moment.
Comment #11
xjmGreat, so here's what I'd recommend:
Comment #12
star-szrComment #13
lauriiiComment #14
lauriiiCreated the follow-up and will work on that: #2544156: Deprecate drupal_render_children(). drupal_render_children() has the only SafeMarkup::set() call in common.inc so postponing this on the child issue.
Comment #15
jrearickClarifying what this is postponed on in the issue summary.
Comment #16
alexpottLet's swap the SafeMarkup::set() for a SafeString::create() - it'll work fine.
Comment #17
alexpottComment #18
alexpottIn discussion with @xjm, @joelpittet, @effulgentsia, @cilefen, @lauriii, @davidhernandez, @yesct and @pwolanin it was concluded that regardless of the outcome of #2544156: Deprecate drupal_render_children() we should do the replacement of SafeMarkup::set() with SafeString::create() as this is consistent with Renderer::render().
Comment #19
xjmComment #20
alexpottComment #21
lauriiiRTBC if this passes.
Tested the few places where render_children is used manually and it seemed to work.
Comment #22
joelpittetRTBC++
Comment #23
catchCommitted/pushed to 8.0.x, thanks!