I experienced the same bug like in issue https://www.drupal.org/project/easy_breadcrumb/issues/3056018 but for an alternate field used as breadcrumb title.
I created a simple patch to fix the HTML decoding.
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | alternate_field_html_decoded-3568508.patch | 837 bytes | bekro |
Issue fork easy_breadcrumb-3568508
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
bekro commentedAdd patch
Comment #3
csakiistvanReviewed the patch in #2 (
alternate_field_html_decoded-3568508.patch) against2.x(da98433) on Drupal 11.4.4 / PHP 8.5.5. Confirmed with analternative_title_fieldholdingTom & Jerry: before the patch the crumb renderedTom & Jerry, after itTom & Jerry. ✅The cause is that
TitleResolver::getTitle()returns a plain string, so neither decoding branch inEasyBreadcrumbBuilder::getTitleString()(theMarkupInterfaceand#markuprender-array cases) ever applies to the alternative title field.No security concern: breadcrumb titles are passed as plain strings to
Link/Link::createFromRoute(), never wrapped inMarkup::create()or a#markupkey, so Twig autoescaping still handles the output. Decoding afterXss::filter()is not exploitable here, and it matches theHtml::decodeEntities(Xss::filter(...))pattern already used inEasyBreadcrumbBuilder.php(lines 386, 838, 846). Coding standards are fine.Suggestions
getTitleString()instead — anis_string($title)branch would cover every string-returning title source rather than only the alternative field, and avoids a fourth decode call site.&would lock this in — #3056018: HTML character decoded fixed the same class of bug without a test, which is how it resurfaced here.Testing produced with the assistance of an LLM.
Comment #5
loopduplicate commentedComment #7
loopduplicate commentedComment #8
csakiistvanComment #9
csakiistvanEnvironment
5bfef4e)Prerequisites
field_breadcrumb_titleto the Basic page content type./amp-parentwhosefield_breadcrumb_titlevalue contains an ampersand, e.g.Tom & Jerry.Steps
EasyBreadcrumbBuilder::getTitleString()now runs plain strings throughHtml::decodeEntities(Xss::filter())as well, instead of only handlingMarkupInterfaceobjects and#markuprender arrays.ddev drush cr/amp-parentand look at the second breadcrumb segment, before and after the fix.EasyBreadcrumbAlternateTitleFieldTest./admin/structure/menu/manage/main/addand/admin/structure/types/manage/page/fields.Expected results
Tom & Jerry.testWithHtmlCharacterReferencefails on unpatched2.xand passes with the fix.MarkupInterfaceand#markupbranches that the MR rewrote.Actual results
Before the fix the crumb was double-escaped: the markup contained
Tom & Jerry, so the page showed Tom & Jerry. After the fix the markup isTom & Jerryand the page shows Tom & Jerry, as expected.The whole module suite is green with the fix applied (22 tests, 201 assertions; the reported deprecations come from the surrounding site, not from the module). The added
testWithHtmlCharacterReferencedoes cover the bug: reverting onlysrc/EasyBreadcrumbBuilder.phpto2.xand rerunning makes it fail withBehat\Mink\Exception\ElementHtmlException: The string "Page & Test" was not found in the HTML of the element matching css "#block-breadcrumb li:nth-child(2)", while the rest of the suite stays green.No regression on the rewritten branches:
/admin/structure/menu/manage/main/addrenders … / Main Navigation / Add Menu Link and/admin/structure/types/manage/page/fieldsrenders … / Basic Page / Manage Fields, identical before and after the fix. Note thatstrip_tags()was dropped from theMarkupInterfacebranch in favour ofXss::filter(), so allowed tags now survive into the segment text instead of being removed; the segments are still passed toLinkas plain strings and escaped by Twig, so this is a display detail rather than a security change, and no core admin title hit it in this test.One small remark:
testWithHtmlCharacterReferencenever setsALTERNATIVE_TITLE_FIELDitself — it relies on the module's shipped defaultalternative_title_field: 'field_breadcrumb_title'inconfig/install/easy_breadcrumb.settings.yml. It works, but setting the config explicitly in the test would make it independent of that default.Testing produced with the assistance of an LLM.
Comment #10
greg boggsYes, this looks good.
csakiistvan,
Your testing is appreciated and super welcome, and has been correct in finding todos. But, your AI is also being too detailed which gives us a lot to read. Please make sure your results paragraphs are super clear on whether the issues are good to go or they need more work. If they are good to go, and they need more work, please open a new issue with the more work part in that new issue.
Comment #11
csakiistvanThanks the suggestion @greg boggs, I refine the workflow so that the end result is more quickly understood.
Comment #13
loopduplicate commentedThanks @bekro @csakiistvan @greg-boggs :3