The system module documents $head_title as intended for use in the title tag and it's used that way in system and built-in themes (most contrib themes too).
But the $head_title var is not filtered for html markup! This produces invalid html output if a slogan is used and contains markup.
E.g. go to /admin/config/system/site-information and set Slogan with some markup. Look at the browser title bar and the resulting html.
Refer to http://www.w3.org/TR/html4/struct/global.html#h-7.4.2 -- title can contain PCDATA only.
modules/system/html.tpl.php: <title><?php print $head_title; ?></title>
modules/system/maintenance-page.tpl.php: <title><?php print $head_title; ?></title>
themes/bartik/templates/maintenance-page.tpl.php: <title><?php print $head_title; ?></title>
themes/garland/maintenance-page.tpl.php: <title><?php print $head_title ?></title>
themes/seven/maintenance-page.tpl.php: <title><?php print $head_title; ?></title>
For reference, the note:
modules/system/html.tpl.php: * - $head_title: A modified version of the page title, for use in the TITLE
the possible addition of invalid markup to $head_title:
includes/theme.inc: $head_title['slogan'] = filter_xss_admin(variable_get('site_slogan', ''));
TL;DR: $head_title must not contain markup as already noted in the docs for the var.
Needs D6 backport, s.a. http://drupal.org/node/340358
Comments
Comment #1
zany commentedComment #2
marcingy commentedMarking as needs review and bumping to d8.
Comment #4
zany commentedRerolled patch for D8.
Comment #5
zany commentedRenamed for auto testing.
Comment #6
zany commentedComment #7
marcingy commentedIt would be nice have tests for this. Otherwise looks good.
Comment #8
zany commentedThanks. Do you mean SimpleTest or other users testing this? It has been documented to be useful and harmless in the referenced D6 issue. I apply this patch to all my installs since D6 appeared (3 years ago). The situation without strip_tags() is invalid html markup.
Comment #9
marcingy commentedMy bad the tag indicates the need for simpletests. I'm happy to rbtc otherwise as the patch looks good :) but I think it is a good case for test.
Comment #10
zany commentedThis patch is with tests added.
The test went into system.test PageTitleFiltering test case as testHTMLTitleTag(). The test code fits neatly with the testTitleTags() and testTitleXSS() in there:
HTML in page titles
Tests correct handling or conversion by drupal_set_title() and drupal_get_title() and checks the correct escaping of site name and slogan.
To be clear, this patch removes HTML markup from the slogan when displayed as HTML Title tag. (The slogan is displayed in the html title tag if there is no drupal_set_title() set, i.e. some nodes exist and you view the front page, see node.module's node_page_default() )
We don't use check_plain() so we don't spell out tags in the html title.
There is no simple way to do the same for site-name (i.e strip tags) as in most cases site-name is already check_plain()ed (i.e entity-encoded).
Comment #11
kscheirer#10: system-head_title-1219040-10.patch queued for re-testing.
Comment #13
zany commentedReroll with tests for D8.
Comment #15
zany commentedTests fail because the front page now redirects to the user or login -- it used to be the promoted node listing. Is there some (default) path that won't set the title?
Comment #16
zany commentedFixed patch from #10 and #13 using a path of
node(it's a random page that won't set a title). This requires theviewsmodule to be included for the tests. Are there guidelines or opinions on including modules in tests?Comment #30
mstrelan commentedI reviewed this with @quietone and @darvanen as part of the Bug Smash Initiative. We tested in Drupal 9.4, 10.0 and 10.1 across various themes including Stark, Bartik, Olivero, Seven and Claro. We weren't able to determine how to actually make the slogan appear in the
<title>tag. I reviewed the relevant code intemplate_preprocess_htmland can see there are 5 separate issues (listed below) that have changed the way head_title works since this issue was reported. Also note if I remove the conditions so we always call$head_title['slogan'] = strip_tags($site_config->get('slogan'));then I can get the slogan in the<title>tag, and the markup is stripped appropriately. Since it seems this has been addressed already I'm closing as outdated.#2352155: Remove HtmlFragment/HtmlPage
#2369987: Remove SafeMarkup::set() from 'head' title on template_preprocess_html
#2560641: Remove all usages SafeMarkup::checkPlain() from render arrays
#2576533: Rename SafeStringInterface to MarkupInterface and move related classes
#2776975: March 3, 2017: Convert core to array syntax coding standards for Drupal 8.3.x RC phase