nette / latte

☕ Latte: the safest & truly intuitive templates for PHP. Engine for those who want the most secure PHP sites.
https://latte.nette.org
Other
1.09k stars 107 forks source link

Setting ContentType in a context filter does not work in a XML template #322

Closed janchaloupka closed 1 year ago

janchaloupka commented 1 year ago

Version: 3.0.4

Bug Description

I have encountered a problem when I was creating a custom filter for XML files that escapes content in a CDATA block.

The problem is that I need the Latte parser to treat the returned value of this filter as already escaped (safe) text. In a HTML template everything works as expected. however when I use this filter in a XML template (specified using a {contentType xml} block), the returned value is always escaped by Latte no matter the selected ContentType in the filter.

Steps To Reproduce

$latte = new \Latte\Engine();
$latte->addFilter('cdata', static function(\Latte\Runtime\FilterInfo $info, string $data) {
    $info->contentType = \Latte\ContentType::Xml; // Same result with any other ContentType
    return '<![CDATA[' . $data . ']]>';
});

$latte->setLoader(new \Latte\Loaders\StringLoader(['template' => '{contentType xml}<?xml version="1.0"?><root>{$foo|cdata}</root>']));
$latte->render('template', ['foo' => '<a>Hello world</a>']);

Output: <?xml version="1.0"?><root>&lt;![CDATA[&lt;a&gt;Hello world&lt;/a&gt;]]&gt;</root> (incorrect)

Expected: <?xml version="1.0"?><root><![CDATA[<a>Hello world</a>]]></root>

Expected Behavior

When used in a HTML template, everything works as expected. I would expect the same behaviour for XML templates.

$latte = new \Latte\Engine();
$latte->addFilter('cdata', static function(\Latte\Runtime\FilterInfo $info, string $data) {
    $info->contentType = \Latte\ContentType::Html;
    return '<![CDATA[' . $data . ']]>';
});

$latte->setLoader(new \Latte\Loaders\StringLoader(['template' => '<root>{$foo|cdata}</root>']));
$latte->render('template', ['foo' => '<a>Hello world</a>']); // This returns the expected result
dg commented 1 year ago

It should work, but you'll need to set $info->contentType = Latte\ContentType::Html; Sometime in the future I'll make it work better with Xml.